A couple of weeks ago I started playing around with Docker. I set up a small server at home and I wanted to host several applications like a mailserver, nextcloud, an apache webserver hosting my panorama fotos, gitlab for my code and so on.
It was not as complicated as I thought setting up my first Docker container. Just pull the container from Docker-Hub, start it by binding ports to the Docker host.
As I don’t want to remember the lengthy Docker starup commands I started using docker-compose which puts all Docker arguments into a yml file.
That was much better, but what if I have multiple application running on port 80 or 443 in the same docker host?
The simplest approach was to bind ports like 10080 or 10443 of the docker host to an application. Great, I managed to simplify the Docker container startup by using docker-compose and now I have to remember all that ports? No way!
Traefik reverse proxy as solution
A couple of months ago I attended a Docker meetup at Zanlando in Dortmund. The speaker, Peter Rossbach, gave a rough introduction to Docker and he spoke about the reverse proxy Traefik which he was very keen of.
At that time I experminted with the spring-cloud-netflix stack which promised a service discovery, proxying and load-balancing, so the grace of Traefik did not show to myself.
But it was not easy to get this stack running and it only helped for spring-boot applications – not for the applications I wanted to run in my Docker machine.
So I remembered the reverse proxy Traefik and gave it a try.
Traefik – what is it?
Traefik is a reverse proxy which runs in a Docker container. The ports 80 and 443 are exposed to the Docker host so it can be acccessed from the outside.
All other containers which need to be accessed from the outside then register to Traefik and Traefik does the routing. If there are more than one instance of the Docker application container, Traefik also does load-balaning.
As a nice bonus Traefik supports Let’s encrypt which means it automatically gets valid SSL certificates for each routed application.
The Traefik Docker documentation shows nicely how to configure your Docker container.
Traefik and Docker network
In my first attempts I could not get Traefik up and running with my Docker containers. The simple reason was I did not understand one main principle: Traefik and the Docker container must reside in a same Docker virtual network.
Prepare Traefik for virtual network
The following examples are based on docker-compose.
The following gives the complete docker-compose.yml containing an virtual reverse-proxy network.
version: '2' services: traefik: restart: always image: traefik command: --configFile=/var/traefik/traefik.toml ports: - "80:80" - "8080:8080" - "443:443" volumes: - /var/run/docker.sock:/var/run/docker.sock - $PWD/traefik.toml:/var/traefik/traefik.toml - $PWD/acme:/acme networks: default: external: name: reverseproxy_default
The configuration “networks” puts Traefik into a virtual network called “reverse_proxy”.
Prepare application for virtual network
All application which use Traefik as reverse proxy must also be put into the virtual network “reverse_proxy”.
There is no need to expose any ports of the application to the docker host as Traefik does the routing internally via the shared virtual network.
The following docker-compose.yml of the container hosting my panorama pictures look like this:
version: '2' services: apache: restart: always container_name: panos build: . volumes: - /media/files/samba/stitches:/usr/local/apache2/htdocs/ networks: - "reverseproxy_default" labels: - "traefik.enable=true" - "traefik.backend=panos" - "traefik.docker.network=reverseproxy_default" networks: reverseproxy_default: external: name: reverseproxy_default
As you can see, the “networks” part is the same like in the Traefik configuration.
The “labels” section configures how the aplication container is bound to Traefik (please refer to Traefik Docker configuration).
In my usecase Traefik works well and is easy to configure.
In some cases the functionality of Traefik can be compared to the spring-cloud-netflix stack. It provides:
- service discovery
- load balancing
- simple monitoring dashboard
But Traefik some – for me very important – features, which spring-cloud-netflix does not provide:
- Let’s encrypt support out of the box
- tecchnology agnostic, not limited to the Java world
As Traefik is the more flexible solution and works well in my usecase, I decided to use it in a production environment.