Root-Server Tutorial

ROOT-SERVER TUTORIAL

Setting up an nginx Reverse Proxy with Docker

Learn how to set up a reverse proxy to forward HTTP traffic on different subdomains to different containers. Also includes setup descriptions for a LetsEncrypt CertBot.

Author:

Leonard Seibold

Last updated:

04/11/2021

Introduction

In this tutorial, we will set up an nginx reverse proxy using Docker and docker-compose. This will allow us to route HTTP requests arriving through different subdomains to web services running in different Docker containers. We will also set up a LetsEncrypt CertBot to automatically create and renew TLS certificates.

Requirements

  • Server (root or VPS)
  • Working Docker installation
  • Working docker-compose installation.

Step 1 - Define the services using docker-compose

Create a new YAML file reverse-proxy.yml and open it using an editor of your choice:

vim reverse-proxy.yml

Insert the following:

version: '3'

services:
    nginx:
        image: jwilder/nginx-proxy
        container_name: nginx-proxy
        restart: always
        logging:
            driver: "json-file"
            options:
                max-size: "50m"
                max-file: "1"
        ports:
            - '80:80'
            - '443:443'
        volumes:
            - conf:/etc/nginx/conf.d
            - certs:/etc/nginx/certs
            - vhost:/etc/nginx/vohost.d
            - html:/usr/share/nginx/html
            - dhparam:/etc/nginx/dhparam
            - '/var/run/docker.sock:/tmp/docker.sock:ro'

    nginx-proxy-le:
        image: jrcs/letsencrypt-nginx-proxy-companion
        container_name: nginx-proxy-le
        restart: always
        logging:
            driver: "json-file"
            options:
                max-size: "50m"
                max-file: "1"
        volumes:
            - conf:/etc/nginx/conf.d
            - certs:/etc/nginx/certs:rw
            - vhost:/etc/nginx/vhost.d
            - html:/usr/share/nginx/html
            - '/var/run/docker.sock:/var/run/docker.sock:ro'
        environment:
            NGINX_PROXY_CONTAINER: nginx-proxy

networks:
    default:
        external:
            name: compose-net

volumes:
    conf:
    vhost:
    html:
    certs:
    dhparam:

This docker-compose file will create two services: The nginx-proxy container will run the nginx reverse proxy, while nginx-proxy-le will manage LetsEncrypt's TLS certificates. Please note that the log files have a size limit to avoid running out of disk space. You can of course change this. The nginx config can be found in the conf Docker volume (though it should not be necessary to edit it manually).

Step 2 - Create the Docker network

Run the following Docker command:

docker network create compose-net

If you are currently not the root user and did not set up your user to use Docker, you may have to run this command with sudo privileges.

Step 3 - Deploy the services

Use docker-compose to deploy both containers and auto-create the Docker network and volumes:

docker-compose -f reverse-proxy.yml up -d

Just as in Step 2, you might need sudo privileges depending on your system setup.

Step 4 - Set up your web services

You can now set up your web services to be reachable under a given subdomain. Just define the subdomain you want to route to a service using the VIRTUAL_HOST environment variable. If you use a different docker-compose file for your services, make sure to use the same Docker network as for the reverse proxy:

## my-service.yml
version: '3'
services:
    whoami:
        image: jwilder/whoami
        environment:
          - VIRTUAL_HOST=whoami.your-domain.de

networks:
    default:
        external:
            name: compose-net

Make sure that your subdomain resolves to your server's public IP address, then deploy your web service:

docker-compose -f my-service.yml up -d

The LetsEncrypt companion container should now automatically request a TLS certificate and set up the reverse proxy in order to route requests to your service afterwards. Give it a few minutes (as key generation might take a while), then try reaching your service at whoami.your-domain.de (or whatever subdomain you used) from your web browser.

Conclusion

This fully automated setup makes it easy to deploy multiple web services without having to use multiple IP addresses. It also handles TLS certificates for you, making it easy to make services publicly available.

License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Contributor's Certificate of Origin

By making a contribution to this project, I certify that:

  1. The contribution was created in whole or in part by me and I have the right to submit it under the license indicated in the file; or

  2. The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same license (unless I am permitted to submit under a different license), as indicated in the file; or

  3. The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it.

  4. I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the license(s) involved.

Published 04/11/2021 by Leonard Seibold

Submit your tutorial

Get 60€ netcup vouchers for every published tutorial.