Nginx Proxy
The jwilder/nginx-proxy container is a great way to automatically manage easy access to various other docker containers on the same network. It also provides a simple way to generate and renew Let's Encrypt certificates for any container that is internet-facing.
Using docker compose, getting set up with HTTPS is trivial. The following is an annotated example of how it would all hang together.
version: '3.2'
services:
proxy:
image: jwilder/nginx-proxy:alpine
restart: always
# The proxy will be the only container running on port 80 and 443. This is
# to ensure that we can access any service via the browser without having
# to specify any ports.
ports:
- '80:80'
- '443:443'
volumes:
# Add custom nginx config to the ./nginx/proxy.conf file. This is useful
# for disabling version numbers or increasing the maximum file size for
# uploading files.
- './nginx/proxy.conf:/etc/nginx/conf.d/proxy.conf:ro'
# This is where the magic happens. The proxy container watches the
# docker socket for any changes to containers and inspects their
# environment variable to set up vhost entries for. Make sure this is a
# read only mount.
- '/var/run/docker.sock:/tmp/docker.sock:ro'
# The following 3 mounts allow the nginx process read and set up vhost
# entries that the Let's Encrypt companion container has generated for us.
# In the next service definition we see how this hooks up.
- './nginx/vhost.d:/etc/nginx/vhost.d'
- './nginx/html:/usr/share/nginx/html'
- './nginx/certs:/etc/nginx/certs'
# This label is required as the Let's Encrypt companion container needs to
# identify which container the nginx proxy is running in.
labels:
- com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy
proxy_letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion
restart: always
# When setting up new SSL enabled domains, it's useful to have a testing
# environment before rolling out fully fledged SSL certificates for your
# service. Setting the `ACME_CA_URI` environment variable to the below URL
# allows for multiple attempts at certificate generation. Once this
# container is generating certificates, comment this line out and recreate
# the container.
environment:
ACME_CA_URI: https://acme-staging.api.letsencrypt.org/directory
volumes:
# Similar to the main proxy container, this one also needs to watch the
# docker socker to know when certification generation should occur. Make
# sure this is a read only mount.
- '/var/run/docker.sock:/var/run/docker.sock:ro'
# As noted above, these mounts should be the same as the main nginx
# container. This is where Let's Encrypt certificates are saved so the
# main container can read and configure the vhosts appropriately.
- './nginx/vhost.d:/etc/nginx/vhost.d'
- './nginx/html:/usr/share/nginx/html'
- './nginx/certs:/etc/nginx/certs'
# This is more of a convenience configuration to make sure that the proxy
# container is running when starting up the Let's Encrypt one.
depends_on: ['proxy']
The next step is to create appropriate environment variables and host records to map your containers to the proxy. This is done by creating VIRTUAL_HOST
, VIRTUAL_PORT
, LETSENCRYPT_HOST
, and LETSENCRYPT_EMAIL
environment variables.
version: '3.2'
services:
proxy:
# ...snip...
my_new_service:
# ...snip...
environment:
# The `VIRTUAL_HOST` environment variable specified the vhost names to be
# generated by the proxy. Here we're telling the proxy to forward both
# my.service.home and my.domain.com to the my_new_service container
VIRTUAL_HOST: my.service.home,my.domain.com
# Sometimes containers may not specify (EXPOSE) which port their software
# is running on. If necessary, use `VIRTUAL_PORT` to amend this.
VIRTUAL_PORT: 8080
# The following 2 environment variables are required for the generation of
# Let's Encrypt SSL certificates. Note that the `LETSENCRYPT_HOST`
# **must** be specified in the `VIRTUAL_HOST` environment variable for
# forwarding to be successful.
# It's also worth noting that the current version of this container must
# be accessible over the internet on both port 80 and 443. So check with
# your ISP and router settings that these ports are unblocked and open.
LETSENCRYPT_HOST: my.domain.com
LETSENCRYPT_EMAIL: [email protected]