Kuba docker
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 00000000000..2ce8a820983
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,11 @@
+# this file uses slightly different syntax than .gitignore,
+# e.g. ".tox/" will not ignore .tox directory
+
+# well, official docker build should be done on clean git checkout
+# anyway, so .tox should be empty... But I'm sure people will try to
+# test docker on their git working directories.
+
+.git
+.tox
+venv
+docs
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000000..b6a07388ca7
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,61 @@
+# https://github.com/letsencrypt/lets-encrypt-preview/pull/431#issuecomment-103659297
+# it is more likely developers will already have ubuntu:trusty rather
+# than e.g. debian:jessie and image size differences are negligible
+FROM ubuntu:trusty
+MAINTAINER Jakub Warmuz <jakub@warmuz.org>
+MAINTAINER William Budington <bill@eff.org>
+
+# Note: this only exposes the port to other docker containers. You
+# still have to bind to 443@host at runtime, as per the ACME spec.
+EXPOSE 443
+
+# TODO: make sure --config-dir and --work-dir cannot be changed
+# through the CLI (letsencrypt-docker wrapper that uses standalone
+# authenticator and text mode only?)
+VOLUME /etc/letsencrypt /var/lib/letsencrypt
+
+WORKDIR /opt/letsencrypt
+
+# no need to mkdir anything:
+# https://docs.docker.com/reference/builder/#copy
+# If <dest> doesn't exist, it is created along with all missing
+# directories in its path.
+
+COPY bootstrap/ubuntu.sh /opt/letsencrypt/src/
+RUN /opt/letsencrypt/src/ubuntu.sh && \
+    apt-get clean && \
+    rm -rf /var/lib/apt/lists/* \
+           /tmp/* \
+           /var/tmp/*
+
+# the above is not likely to change, so by putting it further up the
+# Dockerfile we make sure we cache as much as possible
+
+
+COPY setup.py README.rst CHANGES.rst MANIFEST.in /opt/letsencrypt/src/
+
+# all above files are necessary for setup.py, however, package source
+# code directory has to be copied separately to a subdirectory...
+# https://docs.docker.com/reference/builder/#copy: "If <src> is a
+# directory, the entire contents of the directory are copied,
+# including filesystem metadata. Note: The directory itself is not
+# copied, just its contents." Order again matters, three files are far
+# more likely to be cached than the whole project directory
+
+COPY letsencrypt /opt/letsencrypt/src/letsencrypt/
+COPY acme /opt/letsencrypt/src/acme/
+COPY letsencrypt_apache /opt/letsencrypt/src/letsencrypt_apache/
+COPY letsencrypt_nginx /opt/letsencrypt/src/letsencrypt_nginx/
+
+
+RUN virtualenv --no-site-packages -p python2 /opt/letsencrypt/venv && \
+    /opt/letsencrypt/venv/bin/pip install -e /opt/letsencrypt/src
+
+# install in editable mode (-e) to save space: it's not possible to
+# "rm -rf /opt/letsencrypt/src" (it's stays in the underlaying image);
+# this might also help in debugging: you can "docker run --entrypoint
+# bash" and investigate, apply patches, etc.
+
+ENV PATH /opt/letsencrypt/venv/bin:$PATH
+# TODO: is --text really necessary?
+ENTRYPOINT [ "letsencrypt", "--text" ]
diff --git a/bootstrap/_deb_common.sh b/bootstrap/_deb_common.sh
index b09130d7768..4e4c75b33b2 100755
--- a/bootstrap/_deb_common.sh
+++ b/bootstrap/_deb_common.sh
@@ -10,21 +10,35 @@
 #     - 7.8 "wheezy" (x64)
 #     - 8.0 "jessie" (x64)
 
+
 # virtualenv binary can be found in different packages depending on
 # distro version (#346)
-distro=$(lsb_release -si)
-# 6.0.10 => 60, 14.04 => 1404
-version=$(lsb_release -sr | awk -F '.' '{print $1 $2}')
-if [ "$distro" = "Ubuntu" -a "$version" -ge 1410 ]
-then
-  virtualenv="virtualenv"
-elif [ "$distro" = "Debian" -a "$version" -ge 80 ]
+newer () {
+  distro=$(lsb_release -si)
+  # 6.0.10 => 60, 14.04 => 1404
+  # TODO: in sid version==unstable
+  version=$(lsb_release -sr | awk -F '.' '{print $1 $2}')
+  if [ "$distro" = "Ubuntu" -a "$version" -ge 1410 ]
+  then
+    return 0;
+  elif [ "$distro" = "Debian" -a "$version" -ge 80 ]
+  then
+    return 0;
+  else
+    return 1;
+  fi
+}
+
+# you can force newer if lsb_release is not available (e.g. Docker
+# debian:jessie base image)
+if [ "$1" = "newer" ] || newer
 then
   virtualenv="virtualenv"
 else
   virtualenv="python-virtualenv"
 fi
 
+
 # dpkg-dev: dpkg-architecture binary necessary to compile M2Crypto, c.f.
 #           #276, https://github.com/martinpaljak/M2Crypto/issues/62,
 #           M2Crypto setup.py:add_multiarch_paths
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 00000000000..dbe6e4f011d
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,14 @@
+production:
+  build: .
+  ports:
+    - "443:443"
+
+# For development, mount git root to /opt/letsencrypt/src in order to
+# make the dev workflow more vagrant-like.
+development:
+  build: .
+  ports:
+    - "443:443"
+  volumes:
+    - .:/opt/letsencrypt/src
+    - /opt/letsencrypt/venv
diff --git a/docs/using.rst b/docs/using.rst
index daa2425ea1d..a9b547cf9c1 100644
--- a/docs/using.rst
+++ b/docs/using.rst
@@ -2,6 +2,24 @@
 Using the Let's Encrypt client
 ==============================
 
+Quick start
+===========
+
+Using docker you can quickly get yourself a testing cert. From the
+server that the domain your requesting a cert for resolves to,
+download docker, and issue the following command
+
+.. code-block:: shell
+
+   sudo docker run -it --rm -p 443:443 --name letsencrypt \
+               -v "/etc/letsencrypt:/etc/letsencrypt" \
+               -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
+               quay.io/letsencrypt/lets-encrypt-preview:latest
+
+And follow the instructions. Your new cert will be available in
+``/etc/letsencrypt/certs``.
+
+
 Prerequisites
 =============
 

Inherits kuba's docker setup.  Importantly, adds a development container to docker-compose.yml

Adds venv to a discrete directory, rather than it being the parent directory of src/
