Hosting multiple SSL-enabled sites with Docker and Nginx

Docker Nginx multiple websites: a comprehensive tutorial
In one of our most popular tutorials—Host multiple websites on one VPS with Docker and Nginx—I covered how you can use the nginx-proxy Docker container to host multiple websites or web apps on a single VPS using different containers. As I was looking to enable HTTPS on some of my self-hosted services recently, I thought it was about time to take that tutorial a step further and show you how to set it up to request Let's Encrypt HTTPS certificates. With the help of docker-letsencrypt-nginx-proxy-companion (Github), we'll be able to have SSL automatically enabled on any new website or app we deploy with Docker containers.

Prerequisites

  • Any of our OS options—Ubuntu, Debian, or CentOS. Just a note: we've only tested Ubuntu 16.04 as of now.
  • A running Docker installation, plus docker-compose—see our Getting Started with Docker guide for more information.
[cta_inline]

Step 1. Getting set up, and a quick note

I'm a rather big fan of using docker-compose whenever possible, as it seems to simplify troubleshooting containers that are giving you trouble. Instead of parsing a long terminal command, you can simply edit the docker-compose.yml file, re-run docker-compose up -d, and see the results. As a result, this tutorial will be heavily biased toward using docker-compose over docker commands, particularly when it comes to setting up the docker-letsencrypt-nginx-proxy-companion service. If you're interested creating these containers via docker commands, check out the docker-letsencrypt-nginx-proxy-companion documentation. Already have nginx-proxy set up via our previous tutorial? You can simply overwrite your existing docker-compose.yml file with the file you'll find in Step 2. If you're just getting started with nginx-proxy, start here. You'll want to start by creating a separate directory to contain your docker-compose.yml file.
$ mkdir nginx-proxy && cd nginx-proxy
Once that's finished, issue the following command to create a unique network for nginx-proxy and other Docker containers to communicate through.
docker network create nginx-proxy

Step 2. Creating the docker-compose.yml file

In the nginx-proxy directory, create a new file named docker-compose.yml and paste in the following text:
version: '3'

services:
  nginx:
    image: nginx:1.13.1
    container_name: nginx-proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - conf:/etc/nginx/conf.d
      - vhost:/etc/nginx/vhost.d
      - html:/usr/share/nginx/html
      - certs:/etc/nginx/certs
    labels:
      - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true"

  dockergen:
    image: jwilder/docker-gen:0.7.3
    container_name: nginx-proxy-gen
    depends_on:
      - nginx
    command: -notify-sighup nginx-proxy -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
    volumes:
      - conf:/etc/nginx/conf.d
      - vhost:/etc/nginx/vhost.d
      - html:/usr/share/nginx/html
      - certs:/etc/nginx/certs
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - ./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro

  letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    container_name: nginx-proxy-le
    depends_on:
      - nginx
      - dockergen
    environment:
      NGINX_PROXY_CONTAINER: nginx-proxy
      NGINX_DOCKER_GEN_CONTAINER: nginx-proxy-gen
    volumes:
      - conf:/etc/nginx/conf.d
      - vhost:/etc/nginx/vhost.d
      - html:/usr/share/nginx/html
      - certs:/etc/nginx/certs
      - /var/run/docker.sock:/var/run/docker.sock:ro

volumes:
  conf:
  vhost:
  html:
  certs:

# Do not forget to 'docker network create nginx-proxy' before launch, and to add '--network nginx-proxy' to proxied containers.
Continue reading this article
by subscribing to our newsletter.
Subscribe now