Let‘s go full SSL
We were thrilled when Let’s Encrypt started their public beta so we could get free, high quality SSL certificates for all the services we use and host ourselves.
We use jwilder/nginx-proxy as the reverse proxy. Why? Because it’s super easy to set up and takes care of all our virtual host (vhost) configuration automatically so we can just launch services and don’t have to care about a thing anymore. But dealing with SSL certificates was still a manual step we had to perform. So we thought we could just go ahead and automate that piece of the process a little more and enhanced the jwilder/nginx-proxy.
We created the eforce21/letsencrypt-nginx-proxy that features fully automated SSL certificate generation and renewal per vhost.
How does that work?
Let’s have a look into the Dockerfile:
RUN apt-get update && apt-get install -y git cron vim && apt-get clean && rm -rf
/var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN systemctl enable cron
RUN cd / && git clone https://github.com/letsencrypt/letsencrypt
COPY etc /etc
COPY ssl.tmpl /app/
COPY createSSL.sh /
RUN chmod +x /createSSL.sh
COPY Procfile /app/Procfile
COPY cronfile /app/cronfile
RUN crontab /app/cronfile
So first we take the 0.2.0 tag of the jwilder/nginx-proxy. On top of this we install cron and vim (I know, vim does not necessarily have to be in there, but it makes things just so much easier if you need to adjust something quickly or test/debug). After we enable the cron service we clone the Let’s Encrypt project from github.
We also adjusted the nginx-proxy with some more config files you can find in the etc folder of our repository. So we add all these resources, I’ll explain why we need them just now. In the per vhost default config we added
The Procfile starts all necessary services. We adapted it to run our docker-gen command for the certificate generation as well. If you need more information on Procfiles (and how to use them, here’s a good resource on foreman.
The cronfile holds the definition of the renewal of the certificates: 00 10 * * * docker-gen -only-exposed -notify „/createSSL.sh“ /app/ssl.tmpl /createSSL.sh
We make it check if a renewal is necessary every day at 10am. Therefore it takes the ssl.tmp file, generated the createSSL-shell-script and runs it. The ssl.tmpl contains a skeleton of a shell script that we need in order to obtain or renew certificates. It’s a GO template as docker-gen is a tool written in GO.
We add the createSSL.sh via Dockerfile because generating it wouldn’t lead to the chmod +x and therefore the generation would not work. The file is empty as the content will be generated via docker-gen.
So let’s TL;DR:
We use docker-gen to watch for container startups and generate the createSSL.sh to obtain certs. We have a cron job running that checks if certificates need to be renewed via the createSSL.sh that we generate via docker-gen as well.