Traefik reverse proxy & Docker
Route all your applications in an easy and flexible manner
Route all your applications in an easy and flexible manner.
When building applications you might quickly run into issues like multiple co-dependent apps on the same environment/server/host.
A simple example is a website with an api. You might have a very cool Symfony application and you want to build a separate api.
You'll end up with your application on
and your application api on
These two apps can become two independent containers. But unfortunately port 80 (http) and 443 (https) can only be used once per host.
When you create a webserver container using docker you can use
docker run -d -p 80:80 nginx
This will start an nginx container on port 80. Imagine this being your application running on port 80. Nginx will be now visible on
Now you have your second application. Also running a webserver on port 80. Mapping port 80 again won't work because it's already being used. Now you could map port 81 or 82 etc.. But let's be honest, that's just plain ugly (or so i think). And not usable in the long run, for development it can be ok. But in production you do not want to use url's with port suffixes.
This is where Traefik comes in the picture.
Traefik serves as reverse proxy. You'll use Traefik to catch all the requests and use rules to decide which request using what url will go to which application/Docker container.
In the following example we'll use Traefik to route the url
http://apache.localhost to an Apache2 container and
http://nginx.localhost tot a Nginx container.
Stop the running nginx container.
docker stop nginx
First we will create a virtual Docker network to work in.
docker network create traefik
This command does nothing more then create an empty network.
Then we will setup the different parts in the application.
My Docker compose file:
version: '3.4' services: proxy: image: traefik:1.4-alpine command: --web --docker --docker.domain=docker.localhost networks: - traefik ports: - 80:80 - 8080:8080 volumes: - /var/run/docker.sock:/var/run/docker.sock apache: image: httpd:alpine labels: - "traefik.frontend.rule=Host:apache.localhost" networks: - traefik nginx: image: nginx:alpine labels: - "traefik.frontend.rule=Host:nginx.localhost" networks: - traefik networks: traefik: external: true
Lets break this down a bit. At the bottom you see the definition of the external Traefik network. That's the one you've just created.
We have 3 services here.
Definition of the image used.
command: --web --docker --docker.domain=docker.localhost
The command executed.
--web enables the web interface for Traefik on port 8080.
--docker tells Traefik you're using Docker configuration.
--docker.domain=docker.localhost sets all the default url's for containers on *.docker.localhost.
This container maps the ports.
80 for the all default http requests
8080 the port Traefik uses for it's web interface.
This gives the Traefik container access to the host Docker socket. Which it uses to route the right container.
This one probably speaks for it self but is very important, this adds this container to the network we created. If Traefik wants to route something to a container, that container has to be in the same network. Otherwise it will fail.
The apache webserver container.
Apache2 image with alpine tag. Images based on Linux alpine are a lot smaller and for most usages a good way to go to keep the disk space usage low.
This is were the Traefik magic comes in. Traefik uses this label to as a frontend rule. When the host catches a request with the uri apache.localhost, Traefik now knows that the request has to go to that container. Is it really that easy? Yes.
Same story here. If this container is not in the same network Traefik cannot see it.
The nginx webserver container.
This is exactly the same with one difference. The traefik label is different. For this container we're telling Traefik to send it here when the uri is
nginx.localhost using the label.
To use the url's locally make sure apache.localhost and nginx.localhost are directed to 127.0.0.1.
Add these to your hosts file.
The only thing left is to head over to your terminal, navigate to the directory containing the docker-compose.yml file and run:
docker-compose up -d
That's it. The three containers will be started, and you can now go to
If everything works out you'll see the nginx start page and the apache start page on their respective url's.
The last one is the Traefik web interface which shows the containers traefik sees and which frontend rules maps to which backend container.
Just the start
There are a lot more configuration options with Traefik and a lot more possibilities. You can fully customize the usage of Traefik, enable automatic usage of Let's Encrypt for ssl certificates and more. But this is a good place to start.