Prev

[Docker] How to setup træfik as a reverse proxy

@ 2025.05.01 05:36:11

Træfik is an open-source routing service that can be used when communication is needed between containers or services, such as in a Kubernetes environment.

In my case, I wanted to deploy multiple backend services on a single VPS (Virtual Private Server), so I needed to route incoming DNS requests to the appropriate service. While this can be done using services like Nginx or Apache, these solutions can be cumbersome and complex when deploying multiple containerized services. Træfik simplifies and streamlines this process.

In this article, I’ll briefly explain how to use Træfik with a simple example.

Concept

To summarize, Træfik can be understood through four main concepts:

  1. Entrypoints: Define where the requests come in.
  2. Routers: Define how to process the requests.
  3. Middlewares: Define what processing should happen to the requests.
  4. Services: Define where the requests should go.

Since this article focuses on docker-compose, we’ll let Træfik handle the services part under-the-hood. In short, you only need to define where the request comes from, how it should be processed, and where it should be routed.

Installation

Installing træfik in a docker environment is as simple as running the following command:

docker run traefik[:version]

In this case, the container will start and load settings from a traefik.yml configuration file, so the file needs to be created beforehand.

Alternatively, you can define the service using docker-compose like this:

name: traefik-example

services:
  traefik:
    image: traefik
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"  # For accessing the internal dashboard; can be enabled with --api-insecure
    command:
      - "--api-insecure"
      - "--providers.docker"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock  
      # For Docker internal monitoring

In this setup, most of the configuration is handled via the command: and labels: fields, allowing Træfik to interact directly with Docker.

✅ Example Usage

Let’s connect Træfik with the services we want to route traffic to. Suppose you have two personal Docker Hub repositories: myRepo/backendapi and myRepo/reactserver.

We’ll define the services like this:

services:
  backendapi:
    image: myRepo/backendapi
    restart: always
    ports:
      - "80:80"

  reactserver:
    image: myRepo/reactserver
    restart: always
    ports:
      - "3000:3000"

In this example, backendapi uses port 80, and reactserver uses port 3000 internally.

Goals:

Assuming both services don’t support HTTPS by default, let’s start by adding two entrypoints to the Træfik service:

command:
  - "--entrypoints.web.address=:80"
  - "--entrypoints.websecure.address=:443"

Next, we’ll define routers for each container to route incoming traffic. Use the following label format:

traefik.http.routers.<router-name>.rule=...

This defines the router’s name and rule it will use to process incoming requests.

Let’s say:

backendapi:
  ...
  labels:
    - "traefik.http.routers.backendrouter.rule=Host(`api.domain.com`)"

reactserver:
  ...
  labels:
    - "traefik.http.routers.frontendrouter.rule=Host(`domain.com`)"

Since reactserver should use HTTPS and backendapi should support both HTTP and HTTPS, assign the appropriate entrypoints:

We’ll also remove the exposed ports from the containers and instead inform Træfik of the internal port using:

traefik.http.services.<service-name>.loadbalancer.server.port=[port]

So now,

backendapi:
  ...
  labels:
    - "traefik.http.routers.backendrouter.rule=Host(`api.domain.com`)"
    - "traefik.http.routers.backendrouter.entrypoints=web,websecure"
    - "traefik.http.services.backendapi.loadbalancer.server.port=80"

reactserver:
  ...
  labels:
    - "traefik.http.routers.frontendrouter.rule=Host(`domain.com`)"
    - "traefik.http.routers.frontendrouter.entrypoints=websecure"
    - "traefik.http.services.reactserver.loadbalancer.server.port=3000"

This sets up routing rules for both services based on the entrypoint and host name.

TLS Setup for HTTPS

First, obtain an origin TLS certificate and private key from your DNS provider, and store them securely (e.g., in /traefik/certificates).

Mount the certificates so Træfik can access them:

volumes:
  - ./traefik/certificates:/etc/traefik/certificates

Since træfik does not yet support directly configuring tls certificates within docker-compose.yml, a dynamic configuration file (e.g., certificates.yml) must be created like so:

# certificates.yml
tls:
  certificates:
    - certFile: /etc/traefik/certificates/<certificate>.crt
      keyFile: /etc/traefik/certificates/<certificate>.key
  stores:
    default:
      defaultCertificate:
        certFile: /etc/traefik/certificates/<certificate>.crt
        keyFile: /etc/traefik/certificates/<certificate>.key

Also mount the configuration directory:

volumes:
  - ./traefik/certificates:/etc/traefik/certificates
  - ./traefik/config:/etc/traefik

Then, instruct Træfik to load the config file:

command:
  - "--api-insecure"
  - "--providers.docker"
  - "--entrypoints.web.address=:80"
  - "--entrypoints.websecure.address=:443"
  - "--providers.file.directory=/etc/traefik"

Finally, enable TLS by default for HTTPS traffic:

- "--entrypoints.websecure.http.tls=true"

Happy shipping 🙂