Setup Traefik Reverse Proxy and Add Routing Using Docker Compose

Reverse proxy is essential for any service being accessed publicly. Traefik is a popular reverse proxy and load balancer designed for microservices and containerized applications. Please make sure Docker is installed with Docker Compose.

Setup Traefik with built-in dashboard app

Let’s first create a folder for Traefik reverse proxy.

mkdir ~/traefik && cd ~/traefik

Next we need to create network for Traefik to communicate with other containers, and it should be exposed externally.

docker create network traefik

Now, let’s create docker-compose.yml

vi docker-compose.yml
networks:
  traefik:
    external: true

volumes:
  traefik-certificates:

services:
  traefik:
    image: "traefik:latest"
    command:
      - "--log.level=DEBUG"
      - "--accesslog=true"
      - "--api.dashboard=true"
      - "--api.insecure=true"
      - "--ping=true"
      - "--ping.entrypoint=ping"
      - "--entryPoints.ping.address=:8082"
      - "--entryPoints.web.address=:80"
      - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      - "--entryPoints.websecure.address=:443"
      - "--providers.docker=true"
      - "--providers.docker.endpoint=unix:///var/run/docker.sock"
      - "--providers.docker.exposedByDefault=false"
      - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
      # For requesting dev cert (if prod cert has issue during development)
      # - "--certificatesresolvers.myhttpchallenge.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
      - "--certificatesresolvers.letsencrypt.acme.email=admin@bill-min.com"
      - "--certificatesresolvers.letsencrypt.acme.storage=/etc/traefik/acme/acme.json"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - traefik-certificates:/etc/traefik/acme
    networks:
      - traefik
    ports:
      - "80:80"
      - "443:443"
    healthcheck:
      test: ["CMD", "wget", "http://localhost:8082/ping","--spider"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 5s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.dashboard.rule=Host(`traefik.your-domain.com`)"
      - "traefik.http.routers.dashboard.service=api@internal"
      - "traefik.http.routers.dashboard.entrypoints=websecure"
      - "traefik.http.routers.dashboard.tls=true"
      - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
      - "traefik.http.routers.dashboard.middlewares=authtraefik"
      - "traefik.http.middlewares.authtraefik.basicauth.users=your_username:{SHA}your_hash"
    restart: unless-stopped

Above config also adds Traefik Dashboard and https with letsencrypt.

Replace your-domain with your actual domain name and setup correct DNS.

Replace your_username and {SHA}your_hash with ones generated from https://hostingcanada.org/htpasswd-generator/

Finally, lets start Traefik container.

docker compose up -d

Verify the container is running successfully

docker ps

You can also check Traefik dashboard by visiting https://traefik.your-domain.com. (you will need to enter the username and password used when generating htpasswd)

Add routing to other containerized apps

After setting up Traefik, adding routes is simple. In most cases, there are 2 things get involved:

  • Communicating with Traffic through network that can be accessed externally, which is traefik from above setting.
  • Running the container from Docker image behind Traefik load balancer at exposed port.

Traefik will config properly based on labels and below is an example of running Next.js app through Docker Compose.

networks:
  traefik:
    external: true

services:
  app:
    image: your_username/nextjs-docker:latest
    ports:
      - 3000:3000
    networks:
      - traefik
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nextjs.rule=Host(`www.your-domain.com`)"
      - "traefik.http.routers.nextjs.service=nextjs"
      - "traefik.http.routers.nextjs.entrypoints=websecure"
      - "traefik.http.services.nextjs.loadbalancer.server.port=3000"
      - "traefik.http.services.nextjs.loadbalancer.passhostheader=true"
      - "traefik.http.routers.nextjs.tls=true"
      - "traefik.http.routers.nextjs.tls.certresolver=letsencrypt"
      - "traefik.http.routers.nextjs.middlewares=compresstraefik"
      - "traefik.http.middlewares.compresstraefik.compress=true"
      - "traefik.docker.network=traefik"
    restart: unless-stopped

For running different apps, the settings are mostly the same except the router name and service name.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *