DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Josh Wulf
Josh Wulf

Posted on • Originally published at Medium on

Easily run multiple apps with HTTPS using Docker and LetsEncrypt

I frequently deploy Web APIs in Docker. On a single VM I might have up to five or six services running.

All of them have TLS certificates and are accessible via port 443 using SNIβ€Šβ€”β€ŠServer Name Indication, where the request is routed to the correct backend based on the domain name of the request.

This is very easy to set up using letsencrypt-nginx-sidecar, (which builds on this project and this project).

This approach is super-quick to set up and use, and reliableβ€Šβ€”β€ŠI’ve been using it for a couple of years now, with no issues. It uses an nginx reverse proxy that listens to a Docker network. When a container joins the Docker network, the nginx reverse proxy adds an entry to route requests to it, and a companion container contacts LetsEncrypt to automatically provision a certificate for TLS connections to that domain.

Setting it up is easy.

Set up

  • Git clone the repo:
git clone [https://github.com/jwulf/letsencrypt-nginx-sidecar.git](https://github.com/jwulf/letsencrypt-nginx-sidecar.git)
Enter fullscreen mode Exit fullscreen mode
  • Now create a Docker network for your containers:
docker network create letsencrypt
Enter fullscreen mode Exit fullscreen mode
  • Start the nginx proxy and LetsEncrypt companion:
cd sidecar && docker-compose up -d
Enter fullscreen mode Exit fullscreen mode

That’s it! You can now deploy multiple webapps to this host using docker-compose and have them automatically proxied with TLS.

You have a proxy running that can route requests to your webapps based on the domain name of the request, and which will automatically get (and renew) a certificate for TLS as you add new webapps.

Adding a web app

Any time you want to add another web app to this network:

  • First set up the DNS record for the domain to point to the host machine’s external interface.
  • In the docker-compose.yml file for the webapp, add the following environment variables:
environment:
  # Set to the port that your webapp listens on
  VIRTUAL\_PORT=3000

  # Can be comma-separated list
  VIRTUAL\_HOST=mysubdomain.mydomain.com 

  # The domain for the cert, can also be comma-separated
  LETSENCRYPT\_HOST=mysubdomain.mydomain.com

  # Your email for the cert
  LETSENCRYPT\_EMAIL=me@gmail.com
Enter fullscreen mode Exit fullscreen mode
  • Add a networks entry to have your webapp join the letsencrypt network:
networks:
  default:
    external:
      name: letsencrypt
Enter fullscreen mode Exit fullscreen mode

Thats it!

Your webapp container will join the network, and the proxy and companion containers will do the rest.

Your webapp container does not need to map any ports in the docker-compose.yml file. The nginx proxy handles all external communication and routes requests over the Docker network.

You can see an example of a complete docker-compose.yml file in this repo.

Top comments (0)

🌚 Friends don't let friends browse without dark mode.

Sorry, it's true.