knowledge › Self Hosting
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
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]