Ceci est une ancienne révision du document !
As the web moves towards a “secure by default” approach, enabling HTTPS on your website is becoming more and more important. I’ve spent the last few weeks updating the websites I manage to run HTTPS, including some that run in docker. As some readers may have noticed, I have also switched the fullcirclemagazine.org website over to HTTPS. The reason for this is simple - Google (and others) are encouraging the use of HTTPS by clearly denoting (with a green padlock) encryption on websites. This month’s article will therefore be dedicated to what HTTPS is, how to get set up with Let’s Encrypt, and how to combine it with docker.
What is HTTPS and Let’s Encrypt? HTTPS helps to protect private data when logging in, when using HTML forms, or otherwise when sharing information with a website. The information is secured via encryption, and can also prevent man-in-the-middle attacks (where another device intercepts your packets). Depending on your host, it may be automatically configured, or an option you can pay for. Previously, SSL certificates were issued only by certain companies (at cost), and self-signed certificates were not considered secure. That changed recently with Let’s Encrypt, which will create secure, trusted certificates for free. The main difference between paid certificates and free ones through Let’s Encrypt are the duration. Certificates from Let’s Encrypt expire after 90 days - meaning you need to actively renew them more often than paid certificates. However, this can be done with a helper tool (I use ‘certbot’), and, combined with crontab, will keep the certificates updated without much effort.
What is Docker? Docker is a system for running services in virtual containers - and is built upon the existing Linux kernel. This means that it is faster, and requires less disk and RAM space than full virtualized environments (such as Vagrant). You can use it to run any number of systems, and multiple containers can communicate with each other via a private network.
Prerequisites In my case, the services I worked with covered 3 containers. One running jwilder’s nginx-proxy image, one running a basic nginx image, and one running a basic apache image. The basic nginx and apache images were linked together as a LEAMP server (an Apache server behind an Nginx server, where Nginx covers static files, and PHP files are handled by Apache). Nginx-proxy is an image that automatically directs and manages the traffic to various other containers (so the URLs lead to the correct container).
Where to start? My original research didn’t indicate too many posts on this particular topic. There were plenty on setting up nginx or apache to serve HTTPS sites. However, the complication comes from using nginx-proxy. As the traffic is technically forwarded between 3 containers, I originally assumed that I would need to configure SSH on both the Nginx-proxy and the Nginx containers. Fortunately, after some trial and error, it turns out that you only need to configure HTTPS on Nginx-proxy, and the settings are then carried through.
Create Certificate To do this, you’ll need to install certbot, which depends on your server’s OS and version. For most Ubuntu versions, you’ll need to add the certbot/certbot ppa (instructions here: https://certbot.eff.org/all-instructions/). Once you’ve installed certbot, you’ll want to create your certificate. I did this using the certonly command, as I did not want certbot to attempt to autoconfigure anything. To configure the certificate, run the following command: certbot certonly Then answer the questions (you will need to point it to the actual webroot of your website that is publically accessible, otherwise Let’s Encrypt cannot confirm you own the domain and the certificate is not created). Once the certificate is created, it will be stored in /etc/letsencrypt/live/<URL>/fullchain.pem and /etc/letsencrypt/live/<URL>/privkey.pem
Create folder for docker volume While you can link the folder from letsencrypt up with docker, I would recommend creating a new folder that you can more easily access (in your user’s home folder, for example). A command that works for this would be: mkdir -p ~/nginxproxy-certs cp /etc/letsencrypt/live/<URL>/{fullchain,privkey}.pem ~/nginxproxy-certs/ If you want nginx-proxy to automatically apply the certificates, you’ll need to have them saved in the style of <URL>.crt and <URL>.key. These can be symbolic links, if you want to create subfolders in nginxproxy-certs for each URL. However, the links must be at the top level of the directory (directly in nginxproxy-certs).
Link Certificate to Nginx-Proxy To supply the certificates to the image, you can use the following command (taken from the official nginx-proxy): docker run -d -p 80:80 -p 443:443 -v /path/to/certs:/etc/nginx/certs -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy Replace the /path/to/certs with the actual folder you placed the certificate in. If you set the names of the files properly, you will just need to make sure the VIRTUAL_HOST line is correct for each docker container. If you prefer more control (or have one certificate for multiple domains), you can instead set the CERT_NAME variable in the container’s environment. If your files are called example.crt and example.key, the CERT_NAME would then just read ‘example’. For ease of use and managing the variables, I’d recommend using docker-compose, as opposed to doing it directly with docker run.
Possible issues I ran into an issue where I had mistakenly linked the cert file in place of the private key, which resulted in nginx -s reload failing on nginx-proxy. There were no obvious errors, but it resulted in the port 443 being closed, and the connection being refused. So if nginx-proxy isn’t working properly for you, make sure you are linking the correct folder, and have read/write permissions; then run nginx -s reload manually to see if there are any errors.
Where can I find more information on Docker? The docker hub pages for the various images typically tell you how to configure them. If you read the documentation page on docker-compose, you’ll also be able to use that without issue. If you want to read my article on Docker, you can find it in FCM#107. I hope this article proves useful for anyone who, like me, was making the process much more complicated than necessary, or was running into a similar issue as I did. If you have any questions, comments, or article suggestions, feel free to contact me at lswest34+fcm@gmail.com.