Run several Docker containers accessible on the same HTTP port

Max Kotliar
formapro
Published in
2 min readNov 16, 2017

--

The article describes the neat and elegant solution for having several Docker containers accessible on the same port (i.e 80) and reachable via its virtual host names.

Sometime ago I stumbled upon a pearl container called nginx-proxy. It fetches some info from a Docker engine about other containers around and generates Nginx reverse-proxy config for them. Simple but yet genius idea.

Nowadays, It is common to have several apps working with each other. It might be a backend that exposes REST API and a frontend that utilizes it. Or, It might be a set of micro services communicating one another. By default, you have to use a service name (one from docker-compose.yml) to reach it. Another problem comes into play if you want to bridge some container 80 ports to the host. They should be unique on host side.

That’s not convenient.

As an example, I’d like to show you how to use it in local development environment. Let’s say we have two applications that expose 80 port. The first one is a backend application based on Symfony where the second is a frontend one based on Angular.

Check a real life example

As for Symfony we use formapro/nginx-php-fpm Docker image, where for the frontend we need a build file:

The docker-compose.yml looks like this:

As you might notice the proxy container is the only one which exposes a HTTP port to outside, other containers stay behind it. In order to tell proxy what to proxy the apps have to define VIRTUAL_HOST environment var.

There is a finishing touch to be done. You either have to mapbackend.loc and frontend.loc to localhost in host’s /etc/hosts file or setup Dnsmasq service to redirect all *.loc requests to localhost.

Now you can type in a browser http://frontend.loc and it will show you it.

I have a small trick for those of you who uses RabbitMQ. You can proxy its manager UI just like the other apps:

Now, it’s available on http://rabbitmq.loc address and default 80 port. No need to remember its default port (15672).

Conclusion

I found this little proxy container extremely useful. The proxy is also capable of proxying FastCGI requests, though I haven’t had a change to test it.

--

--