Using Traefik to Route HTTP Requests to Multiple Docker Microservices
By Tony Mackay ·
When hosting multiple microservices on a server, a reverse proxy can be used to route traffic coming in on port 80/443 to one of the many backend services running in containers. This tutorial shows you how to use Traefik to run multiple microservices on a single Ubuntu Server.
Before we begin
First we need Docker and Docker Compose installed on our machine before we can do the steps in this tutorial. Read How to Install Docker to learn how to install it on Ubuntu 20.04.
In a previous tutorial, I wrote how to use Docker Compose to launch multiple microservices on a server. We will edit the docker-compose.yml file from that tutorial so that both services can be accessed over port 80 instead of from their own ports.
Step 1: Add Traefik to the Docker Compose File
After following the steps in the previous tutorial, you should have a Docker Compose file that looks like the following.
version: '3'
services:
kitchenservice:
image: tonymackay/demoservice:1.0.0
restart: always
environment:
- APP_PORT=8081
- APP_NAME=KitchenService
ports:
- "8081:8081"
orderservice:
image: tonymackay/demoservice:1.0.0
restart: always
environment:
- APP_PORT=8082
- APP_NAME=OrderService
ports:
- "8082:8082"
Add the following config below services:
traefik:
image: traefik:v2.3.6
restart: always
command:
- --accesslog
- --api.insecure=true
- --providers.docker
- --providers.docker.exposedbydefault=false
volumes:
- /var/run/docker.sock:/var/run/docker.sock
ports:
- 80:80
- 8080:8080
This will add the Traefik image and listen on ports 80 and 8080. Port 80 will be used for the traffic to our microservices and port 8080 is used to access the Traefik dashboard.
Step 2: Remove Port Config
The next thing we need to do is remove the ports config from the two services so they can’t be accessed from outside the server.
The config of the services should now look like this.
kitchenservice:
image: tonymackay/demoservice:1.0.0
restart: always
environment:
- APP_PORT=8081
- APP_NAME=KitchenService
orderservice:
image: tonymackay/demoservice:1.0.0
restart: always
environment:
- APP_PORT=8082
- APP_NAME=OrderService
Step 3: Add Expose and Labels
The next thing we will do is add an expose
config option which contains the port number each Go program is listening on. This is used by Traefik so it knows how to communicate with the service.
The config should now look like this.
kitchenservice:
image: tonymackay/demoservice:1.0.0
restart: always
environment:
- APP_PORT=8081
- APP_NAME=KitchenService
expose:
- 8081
orderservice:
image: tonymackay/demoservice:1.0.0
restart: always
environment:
- APP_PORT=8082
- APP_NAME=OrderService
expose:
- 8082
Now we need to add routing rules so Traefik knows what requests to forward to what service. Add the following labels
config to the kitchenservice.
labels:
- traefik.enable=true
- traefik.http.routers.kitchenservice.rule=Host(`mydemoapp.com`) && Path(`/v1/kitchen`)
Add the following labels
config to the orderservice.
labels:
- traefik.enable=true
- traefik.http.routers.orderservice.rule=Host(`mydemoapp.com`) && Path(`/v1/order`)
With these rules, requests to http://mydemoapp.com/v1/order
will go to the orderservice and requests to http://mydemoapp.com/v1/kitchen
will go to the kitchenservice.
The full docker-compose.yml should now look like this.
version: '3'
services:
traefik:
image: traefik:v2.3
restart: always
command:
- --accesslog
- --api.insecure=true
- --providers.docker
- --providers.docker.exposedbydefault=false
volumes:
- /var/run/docker.sock:/var/run/docker.sock
ports:
- "80:80"
- "8080:8080"
kitchenservice:
image: tonymackay/demoservice:1.0.0
restart: always
environment:
- APP_PORT=8081
- APP_NAME=KitchenService
expose:
- 8081
labels:
- traefik.enable=true
- traefik.http.routers.kitchenservice.rule=Host(`mydemoapp.com`) && Path(`/v1/kitchen`)
orderservice:
image: tonymackay/demoservice:1.0.0
restart: always
environment:
- APP_PORT=8082
- APP_NAME=OrderService
expose:
- 8082
labels:
- traefik.enable=true
- traefik.http.routers.orderservice.rule=Host(`mydemoapp.com`) && Path(`/v1/order`)
Step 4: Test the Services
Let’s test the app by runing docker compose up -d

As you can see from the screenshot above, the two microservices are now running and so is the Traefik proxy. You should be able to view the dashboard by navigating to http://mydemoapp.com:8080

Clicking on Explore of the Routers section will show you the rules and what services they map to.

As you can see in the screenshot above, /v1/kitchen
routes requests to the kicthenservice and /v1/order
routes requests to the orderservice. We can test this by running the following curl commands and checking the headers.
curl http://mydemoapp.com/v1/kitchen -i
curl http://mydemoapp.com/v1/order -i

Conclusion
In this post, we learned how to use Traefik to route HTTP requests over port 80 to multiple backend microservices running in Docker containers. This is just scratching the surface on what’s possible with Traefik and I intend to write more tutorials on using it in the future.
Read Next
- The Best Books to Learn Virtualization, Linux and Automation
- Recommended Tools and Software for System Administrators
- How to Rate Limit Requests to WordPress Using Traefik
- Deploy a WordPress Blog with Docker Compose and Traefik
Tony is the founder and editor of GraspingTech, a blog that helps developers and business owners deploy modern web applications to the cloud. He has written over one hundred tutorials which have been read by more than a million people. Some of the topics he covers are Linux, Virtualization, DevOps and web development.