• 9 Dec 2019
  • TYPO3
  • Alexander Bohndorf

Docker-compose setup with nginx reverse proxy

How to run several independent projects on a single server.

We wanted to run several independent projects with docker-compose on a single server, which are accessible externally via a reverse proxy.

When an additional project is added, the reverse pro xy should neither have to be configured manually nor restarted manually.

Instead, the reverse proxy should automatically recognize the new project and make it available under a vhost name that can be configured in the project.

We have achieved this by using the docker image jwilder/nginx-proxy.

The directory structure of the server in the home directory of the SSH user /home/myuser looks like this:

Bash

The configuration of the reverse proxy in the file /home/myuser/frontproxy/docker-compose.yml is as follows:

YAML

The container is now started using :

Bash

This causes docker to create a network with the name frontproxy_default.

Now you can add any new project with a suitable docker-compose configuration, which must contain the following directives for communication with the front proxy:

YAML

The decisive factor here is the addition of the frontproxy_default network as an external network. External here means that it was not created within this docker-compose setup, but by the docker-compose setup of the frontproxy.

In this way, any number of projects can be added. As soon as these have been started with docker-compose up -d, the frontproxy recognizes from the environment variable VIRTUAL_HOST that it must forward requests to this virtual host to this Docker container.

The port specified by the project image in the Dockerfile via EXPOSE is automatically used as the port. This can also be specified using another environment variable VIRTUAL_PORT.

What is interesting about this setup is that any number of projects can be added that all run on the same port (usually port 80 for HTTP). It is therefore not necessary to manually ensure that there are no port overlaps.

It is important that the frontproxy is started first when commissioning this setup. This is because it creates the network frontproxy_default, which all other projects require.

When the server is restarted, this sequence is retained so that docker automatically starts the front proxy first using "restart:always" and then the projects.

SSL certificates

If you create the projects as subdomains of meinedomain.de, you can have all projects delivered via SSL with a single SSL wildcard certificate for *.meinedomain.de.

If you want to use different domain names, you can store an appropriately named certificate and the corresponding key for each domain name in the /home/myuser/frontproxy/certs/ directory.

The addendum below describes how to manage SSL certificates automatically via Let's Encrypt.

Default vhost

The DEFAULT_HOST environment variable in the configuration of the front proxy specifies which content is to be delivered if the front proxy is called with a host name for which no registered vhost exists. If no specification is made here, the content of the first registered vhost would be output, which is not always optimal.

In particular, this can become a problem if a vhost is unavailable due to a failure of the relevant Docker container. We have therefore set up a docker container with a simple web server as the default.vhost, which simply delivers a static HTML page indicating that the vhost is either unknown or currently unavailable.

Addendum: Manage SSL certificates via Let's Encrypt

If you use official domains that can also be resolved via DNS in the public network, you can also have the SSL certificate generation done completely automatically (and free of charge!) using Let's Encrypt.

The docker image docker-letsencrypt-nginx-proxy-companion is available for this purpose.

The docker-compose.yml file must then be extended to include this service:

YAML

A project that is to use this front proxy together with the SSL certificate management then needs the following information in its docker-compose.yml:

YAML

The environment variables LETSENCRYPT_HOST and LETSENCRYPT_EMAIL are crucial here. The former defines the domain name for which the Let's Encrypt service is to create the SSL certificate and the latter the contact (e-mail) for the certificate.

The regular, timely renewal of the certificate is fully automatic.

Alexander Bohndorf

Alexander Bohndorf