Running a (read: just one) web application in Docker is easy.
So you're developing or running web applications in Docker but how do you expose them to the outside world?
When you have just one application the most common option when you're starting with Docker is to just bind a port to the host the container runs on like:
Now you can reach the application by
That would work for development or even for production if you have just one web service per host.
But what if you want more?
- You want run multiple web services?
- You want to run multiple instances of a service?
- You want to run services on multiple hosts?
- You just want a more descriptive hostname than 'http://localhost'?
Reverse proxy to the rescue!
A very nice approach to these problems is to use a reverse proxy. Reverse proxy servers have existed for ages, their job is to distribute incoming traffic (so called ingress) to application(s).
However since we're dealing with containers now there is one big difference: In comparison to 'classic' servers/virtual machines containers tend to be very volatile. Each time a service is deployed or scaled new containers come and old ones go. The proxy needs to be able to keep track of all these changes which means it's not possible to rely on manual configuration. Instead some automated reconfiguration is required.
Træfɪk is an proxy that does just that.
It reconfigures itself continuously by listening to events on the system the containers are running on.
When using Docker (Swarm) it listens to the Docker socket (
When a container is started it will be automatically be accesible via Træfɪk. When a container stops (either intended or unintended) it will be removed from the proxy config again.
You can now let Træfɪk listen to a given (number of) port number(s) like
443 and let it decided which traffic should go to which containers based on hostname.
Containers as in plural? yes it does load balancing! It can also do SSL termination, maybe more on that later.
I can only say this is absolutely awesome. I'm using it for quite a while now and I'm still wondering how I could work without it. And yes there are other products too but this is so simple yet so powerful.
How does Træfɪk work?
So I said Træfɪk configures itself automatically?, Well almost. You have to add some configuration to your application to help Træfɪk understand how it should proxy requests to it. To be able to do this you'll need to understand the basics of how Træfɪk works. Træfɪk works with the concepts frontend and backend and makes sure traffic from a given frontend (accessible from the web) goes to a given backend (running on the orchestrator).
^Image is courtesy of traefik.io
Træfɪk can be configured via labels, these labels can be set either as part of the container image or by an orchestration tool. I prefer the latter since I like decoupling in general because it allows different settings for different environments.
At minimum Træfɪk needs to know the following things of your web application:
- To which backend it belongs
- On which domain it should be reachable from outside
- On which port it is running
- Via which network it can be reached
Furthermore I choose to explicitly enable services for Træfɪk. This way Træfɪk is not bothered by containers I don't want to expose like backend applications and databases. Also this keeps the UI a lot cleaner.
Configuration is done by setting labels on the container.
A minimum configuration looks like this:
Note 1: In the examples below I use
docker-compose but Træfɪk supports many other systems too.
Note 2: I left out all the usual stuff
For a more complete example see the
docker-compose.yml of this site
Note if you use Docker Compose files to deploy to a Docker Swarm Cluster the
labels configuration goes under
deploy rather than directly under the service.
For the sake of completeness an example of how you could configure this directly in a
While Træfɪk itself is a Go binary you - off course - run it as a Docker container. There's even an example Docker Compose configuration.
Note that I prefer to explicitly enable services to be proxies by Træfɪk rather than having it autodetect all containers.
This can be achieved by running it with
For all other options: Træfɪk has pretty good documentation
And now a quick look at the user interface
The user interface is pretty basic but shows the info you need about front and back ends, hosts, http protocols, load balancing protocols etc.
Note it also has a tab where you can get some stats about application health but that's out of the scope of this article
And now try it yourself!
I hope Træfɪk will be as valuable to you as it is to me, let me know how it worked out for you!
If you want to need more, take a look at the documentation.