Skip to content

Traefik + Docker Reverse Proxy Setup Guide (Production)

1. Architecture

Internet -> Traefik (80/443) -> Docker App -> Application

Traefik handles:

  • Reverse proxy
  • SSL certificates (Let’s Encrypt)
  • HTTPS redirects
  • Routing

2. Install Docker

sudo apt update
sudo apt install docker.io docker-compose -y

Enable Docker:

sudo systemctl enable docker
sudo systemctl start docker

3. DNS Setup

Create DNS A record:

Host: traefik.domain.com Value: YOUR_SERVER_PUBLIC_IP

Verify:

nslookup yourdomain.com

OR

dig yourdomain.com

4. Create Project Structure

mkdir -p /opt/traefik
cd /opt/traefik

Create files:

touch traefik.yml
touch acme.json

Set permissions:

chmod 600 acme.json

5. Create traefik.yml

api:
  dashboard: true
  insecure: true

entryPoints:
  web:
    address: ":80"
  websecure:
    address: ":443"

providers:
  docker:
    exposedByDefault: false

certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@test.com
      storage: acme.json
      httpChallenge:
        entryPoint: web

6. Create docker-compose.yml

services:
  traefik:
    image: traefik:v2.11
    container_name: traefik
    command:
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
      - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
      - "--certificatesresolvers.letsencrypt.acme.email=admin@test.com"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./acme.json:/letsencrypt/acme.json
    restart: always

  aiv-app:
    image: YOUR_APP_IMAGE
    container_name: aiv-app
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.aiv.rule=Host(`yourdomain.com`) && PathPrefix(`/aiv`)"
      - "traefik.http.routers.aiv.entrypoints=websecure"
      - "traefik.http.routers.aiv.tls.certresolver=letsencrypt"
      - "traefik.http.routers.aiv-http.rule=Host(`yourdomain.com`) && PathPrefix(`/aiv`)" 
      - "traefik.http.routers.aiv-http.entrypoints=web"
      - "traefik.http.middlewares.aiv-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.aiv-http.middlewares=aiv-redirect"
      - "traefik.http.services.aiv.loadbalancer.server.port=8080"
    restart: always

7. Start Traefik

docker compose up -d

Check:

docker ps

8. Verify SSL

Open:

https://yourdomain.com/aiv/


9. Debugging Commands

Check containers:

docker ps

Check Traefik logs:

docker logs traefik

Check application logs:

docker logs aiv-app

Check ports:

sudo ss -tulpn | grep -E ':80|:443'

Check backend:

curl http://127.0.0.1:8080/aiv/

10. Common Issues & Fixes

SSL Not Generated

Check:

docker logs traefik

Fix:

  • Verify DNS
  • Ensure ports 80/443 open
  • Restart containers

404 Error

Check:

curl http://127.0.0.1:8080/aiv/

Fix:

  • Ensure backend serves /aiv
  • Verify Traefik labels
  • Restart containers

Port Conflict

Check:

sudo ss -tulpn | grep :80
sudo ss -tulpn | grep :443

Fix:

Stop Apache if using Traefik:

sudo systemctl stop apache2
sudo systemctl disable apache2

Mixed Content Error

Replace:

http://yourdomain.com

With:

https://yourdomain.com


11. Restart Commands

Restart all:

docker compose restart

Stop all:

docker compose down

12. Final Working Flow

User -> https://yourdomain.com/aiv/ ↓ Traefik ↓ Docker App