If you have a lot of applications that you want to host in docker, you can use this article to get SSL for free. You additionally separate all your containerized apps nicely with different, automatically managed subdomains.

This is especially useful if you for example have a VPS (virtual private server) that runs docker, and you want to use it to deploy all your applications, via a single host.

We're gonna use two handy docker containers for that. nginx-proxy and letsencrypt-nginx-proxy-companion check our their documentation for more info about how you can customize them further.

First we want to start up nginx-proxy

docker run --detach \
  --name nginx-proxy \
  --publish 80:80 \
  --publish 443:443 \
  --volume /etc/nginx/certs \
  --volume /etc/nginx/vhost.d \
  --volume /usr/share/nginx/html \
  --volume /var/run/docker.sock:/tmp/docker.sock:ro \
  jwilder/nginx-proxy

This will make sure that nginx-proxy is running and listening on port 80 and 443. Next we start the letsencrypt-nginx-proxy-companion container, which handles the SSL stuff for us, whenever we run a new application. Update the DEFAULT_EMAIL to your own email.

docker run --detach \
  --name nginx-proxy-letsencrypt \
  --volumes-from nginx-proxy \
  --volume /var/run/docker.sock:/var/run/docker.sock:ro \
  --volume /etc/acme.sh \
  --env "DEFAULT_EMAIL=mail@yourdomain.tld" \
  jrcs/letsencrypt-nginx-proxy-companion

Now we're set up. All we have to do now is run any container we want, and pass our desired subdomain via --env variables.

Lets run a demo nginx container

docker run --detach \
  --name your-proxied-app \
  --env "VIRTUAL_HOST=subdomain.yourdomain.tld" \
  --env "LETSENCRYPT_HOST=subdomain.yourdomain.tld" \
  nginx

Your application should now be available via the subdomain with a valid SSL certificate.