I’ve been using Digital Ocean as my cloud provider as Docker Cloud will give you $20 free credit to use with them for signing up. If you sign up to Digital Ocean using the above referral link, you will also receive an additional $10 credit.
nginx-proxy is a Docker container that will transparently proxy any of your Docker containers and
publish them under a virtualhost as defined in a
VIRTUAL_HOST variable which can be specified
on any container you wish to proxy.
As an added bonus, we can use nginx-letsencrypt-proxy which will automatically provision SSL certificates from Lets Encrypt for each of the containers virtual hosts. The SSL certificates are renewed every hour from Lets Encrypt to prevent them from expiring.
So lets get started…
Docker Cloud offer a web-based user interface and a command line tool. The majority of this tutorial
will be carried out using the command line tool. To install the tool, run
pip install docker-cloud, preferably within a
Once installed, we need to create a Docker Cloud configuration file. Currently, the default filename
for this is still
tutum.yml. So, create and open this file for editing.
The first thing we need is a volume container to temporarily contain generated Lets Encrypt
certificates. This doesn’t have to be persisted or backed up as the certificates are regenerated
automatically at regular intervals. As you can see, our volume container is called
and contains the path
volume-certs: image: ubuntu mem_limit: 64m volumes: - "/etc/nginx/certs" command: "/bin/true"
The next step is to create another volume container to hold some configuration and templates that
are required by the
nginx-proxy container. As this volume container always needs to contain
the same static content, I created a separate container
for this which I linked to Docker Cloud. This means that the container is automatically built
when the repository is updated.
This new volume container is then added to our
tutum.yml configuration file to ensure it is
created with the rest of our stack.
volume-nginx-proxy-config: image: jinglemansweep/nginx-proxy-configuration mem_limit: 64m command: "/bin/true"
We now need to setup the
nginx-proxy containers. There are two containers, one is just a standard
nginx container which performs the reverse proxying. This container
use volumes from our next container, docker-gen, as well as
our temporary certifcate volume container
volume-certs we configured earlier.
docker-gen container is special in that it has access to the host machines Docker socket
so can monitor when containers are started and stopped. When it detects a change, it regenerates
the Nginx configuration automatically using the templates specified in our
nginx-proxy: image: nginx volumes_from: - volume-certs - volume-nginx-proxy-config ports: - "80:80" - "443:443" nginx-gen: image: jwilder/docker-gen volumes: - "/var/run/docker.sock:/tmp/docker.sock:ro" volumes_from: - nginx-proxy - volume-nginx-proxy-config command: "-notify-sighup nginx -watch -only-exposed -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf"
If you want to automatically provide SSL certificates for your containers using Lets Encrypt, we will need to configure
one more container. The
nginx-letsencrypt-proxy container creates the required domain authorisation material required by
Lets Encrypt’s validation system and publishes it to the main
nginx-proxy container via a shared volume container.
You will have to specify the container ID of your
docker-gen container using the
variable, which is
nginx-gen in this example. This container automatically configures the Lets Encrypt validation material
whenever a container is started, hence the need for using the host machines Docker socket again.
nginx-letsencrypt-proxy: image: jrcs/letsencrypt-nginx-proxy-companion environment: - "NGINX_DOCKER_GEN_CONTAINER=nginx-gen" volumes: - "/var/run/docker.sock:/var/run/docker.sock:ro" volumes_from: - nginx-proxy
That is most of the configuration done. The only additional steps is to add containers that you want to be reverse-proxied by Nginx to a given domain/sub-domain and secured via SSL. In this example, we are just using another default Nginx container.
Any container you want reverse-proxied requires its ports to be exposed using
EXPOSE and not
PORTS. It also requires three environment
variables. The first (
VIRTUAL_HOST) is the domain/sub-domain that Nginx will use to proxy that container. The next two
LETSENCRYPT_EMAIL) are used for automatically generating our SSL certificates. Generally, the
LETSENCRYPT_HOST variables should contain the same value.
nginx-website: image: nginx environment: - "VIRTUAL_HOST=cloud.louisking.xyz" - "LETSENCRYPT_HOST=cloud.louisking.xyz" - "LETSENCRYPT_EMAILfirstname.lastname@example.org" expose: - "80" - "443"
Now we have configured all our containers, we can use the
docker-cloud command line too to provision
our stack. The first thing to do is to login to Docker Cloud using the standard
docker login command.
Once you have done this, Docker Cloud will work using your account.
We’ll navigate to where our
tutum.yml file is and create our stack:
docker-cloud stack up
Source code for my full Docker hosting setup can be found on GitHub.
That’s it for now. More to follow soon.