Learning Center
Docker

Using Traefik in Docker as a Reverse Proxy for Docker Containers

17 Jan 2025
Hostman Team
Hostman Team

Docker containers allow for quick and easy deployment of services and applications. However, as the number of deployed applications grows, and when multiple instances of a single service are required (especially relevant for microservices architecture), we must distribute network traffic. For this purpose, you can use Traefik, a modern open-source reverse proxy server designed specifically to work with Docker containers. In this guide, we will configure Traefik as a reverse proxy for several applications running in Docker containers.

Prerequisites
Copy link

To use Traefik, the following are required:

  • A cloud server or a virtual machine with any pre-installed Linux distribution. We will be using Ubuntu 22.04.

  • Docker and Docker Compose installed. See our installation guide

In this guide, we will use two containers with the Nginx web server. Each container will display a specific message when accessed by its domain name. We will cover the creation of these containers further below.

Configuring Traefik
Copy link

Let's start by setting up Traefik:

  1. Create a directory for storing configuration files and navigate into it:

mkdir ~/test-traefik && cd ~/test-traefik
  1. Inside the project’s root directory, create three subdirectories: one for the Traefik configuration file and two others for the configuration files of the applications that will use Traefik:

mkdir traefik app1 app2
  1. Create the main configuration file for Traefik named traefik.yml in the previously created traefik directory:

nano traefik/traefik.yml

Insert the following code into the file:

entryPoints:
  web:
    address: ":80"

providers:
  docker:
    exposedByDefault: false

api:
  dashboard: true
  insecure: true

Image13

Let’s look closer at the parameters.

  • entryPoints define the ports and protocols through which Traefik will accept requests. They specify on which port and IP address the service will listen for traffic.
    • web — A unique name for the entry point, which can be referenced in routes. In this example, we use the name web.

    • address: ":80" — Indicates that the entry point will listen for traffic on port 80 (HTTP) across all available network interfaces on the system.

  • providers specify the sources of information about which routes and services should be used (e.g., Docker, Kubernetes, files, etc.).
    • docker — Enables and uses the Docker provider. When using the Docker provider, Traefik automatically detects running containers and routes traffic to them.

    • exposedByDefault: false — Disables automatic exposure of all Docker containers as services. This makes the configuration more secure: only containers explicitly enabled through labels (traefik.enable=true) will be routed (i.e., will accept and handle traffic).

  • The api section contains settings for the administrative API and Traefik's built-in monitoring web interface.
    • dashboard: true — Enables Traefik's web-based monitoring dashboard, which allows you to track active routes, entry points, and services. The dashboard is not a mandatory component and can be disabled by setting this to false.

    • insecure: true — Allows access to the monitoring dashboard over HTTP. This is convenient for testing and getting familiar with the system but is unsafe to use in a production environment. To ensure secure access to the dashboard via HTTPS, set this to false.

Now, let's prepare the configuration files for the applications that will use Traefik as a reverse proxy. We will deploy two Nginx containers, each displaying a specific message when accessed via its address.

  1. Create the Nginx configuration file for the first application:
nano app1/default.conf

Contents:

server {
    listen 80;
    server_name app1.test.com;

    location / {
        root /usr/share/nginx/html;
        index index.html;
    }
}

For the server name, we specify the local domain app1.test.com. You can use either an IP address or a domain name. If you don't have a global domain name, you can use any name that is accessible only at the local level. Additionally, you will need to add the chosen domain to the /etc/hosts file (explained later).

Next, create the html directory where the index.html file for the first application will be stored:

mkdir app1/html

Write the message "Welcome to App 1" into the index.html file using input redirection:

echo "<h1>Welcome to App 1</h1>" > app1/html/index.html
  1. Repeat the same steps for the second application, but use values specific to the second app:
nano app2/default.conf

Contents:

server {
    listen 80;
    server_name app2.test.com;

    location / {
        root /usr/share/nginx/html;
        index index.html;
    }
}

Set the local domain name for the second application as app2.test.com.

Create the html directory for the second application:

mkdir app2/html

Write the message "Welcome to App 2" into the index.html file:

echo "<h1>Welcome to App 2</h1>" > app2/html/index.html
  1. Since we used local domain names, they need to be registered in the system. To do this, open the hosts file using any text editor:
nano /etc/hosts

Add the following entries:

127.0.0.1 app1.test.com  
127.0.0.1 app2.test.com  

Image8

The final project structure should look like this:

test-traefik/  
├── app1/  
│   ├── default.conf  
│   └── html/  
│       └── index.html  
├── app2/  
│   ├── default.conf  
│   └── html/  
│       └── index.html  
└── traefik/  
    └── traefik.yml

E23b1f62 96b1 4425 A8a9 8e740b279f80

Launching Traefik and Applications
Copy link

Now let's proceed with launching Traefik and the applications. To do this, create a docker-compose.yml file in the root project directory (test-traefik):

nano docker-compose.yml

Insert the following configuration:

version: "3.9"

services:
  traefik:
    image: traefik:v2.10
    container_name: traefik
    restart: always
    command:
      - "--configFile=/etc/traefik/traefik.yml"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "./traefik/traefik.yml:/etc/traefik/traefik.yml"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  app1:
    image: nginx:1.26-alpine
    container_name: nginx-app1
    restart: always
    volumes:
      - "./app1/default.conf:/etc/nginx/conf.d/default.conf"
      - "./app1/html:/usr/share/nginx/html"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.app1.rule=Host(`app1.test.com`)"
      - "traefik.http.services.app1.loadbalancer.server.port=80"

  app2:
    image: nginx:1.26-alpine
    container_name: nginx-app2
    restart: always
    volumes:
      - "./app2/default.conf:/etc/nginx/conf.d/default.conf"
      - "./app2/html:/usr/share/nginx/html"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.app2.rule=Host(`app2.test.com`)"
      - "traefik.http.services.app2.loadbalancer.server.port=80"

Use the following command to launch the containers:

docker compose up -d

F8ae5be1 349d 4054 Af8f A00fdce25a85

If Docker Compose was installed using the docker-compose-plugin package, the command to launch the containers will be as follows:

docker-compose up -d

Check the status of the running containers using the command:

docker ps

E73bb250 77b0 4da7 918b 58aa5c754d2f

All containers should have the status Up.

Let's verify whether the running containers with Nginx services can handle the traffic. To do this, send a request to the domain names using the curl utility.

For the first application:

curl -i app1.test.com

851b355a Aafc 4d87 Beb1 0a44a8c13e87

For the second application:

curl -i app2.test.com

7c476c77 Cf9d 4ffe 8dcf 4594fc3b6a95

As you can see, both services returned the previously specified messages.

Next, let's check the Traefik monitoring dashboard. Open a browser and go to the server's IP address on port 8080:

A5cc2af2 6bcf 44d2 B33d 1e318432f40e

In the Routers section, you will see the previously defined routes app1.test.com and app2.test.com.

Image3

Conclusion
Copy link

Today, we explored Traefik's functionality using two Nginx services as an example. With Traefik, you can easily proxy applications running in Docker containers.