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 ~/traefikNext we need to create network for Traefik to communicate with other containers, and it should be exposed externally.
docker create network traefikNow, let’s create docker-compose.yml
vi docker-compose.ymlnetworks:
  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-stoppedAbove config also adds Traefik Dashboard and https with letsencrypt.
Replace
your-domainwith your actual domain name and setup correct DNS.
Replace
your_usernameand{SHA}your_hashwith ones generated from https://hostingcanada.org/htpasswd-generator/
Finally, lets start Traefik container.
docker compose up -dVerify the container is running successfully
docker psYou 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 traefikfrom 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-stoppedFor running different apps, the settings are mostly the same except the router name and service name.