← Back to traefik/traefik

How to Deploy & Use traefik/traefik

Traefik Deployment and Usage Guide

1. Prerequisites

Required

  • Go 1.22+ (for building from source)
  • Git (for cloning the repository)

Optional (depending on deployment target)

  • Docker Engine 20.10+ or Podman (for containerized deployment)
  • Kubernetes cluster 1.28+ with Gateway API support (for K8s deployment)
  • Docker Compose (for local multi-service stacks)
  • kubectl configured with cluster access

2. Installation

Option A: Binary Installation (Recommended for Production)

# Download latest release
curl -L https://github.com/traefik/traefik/releases/download/v3.0.0/traefik_v3.0.0_linux_amd64.tar.gz -o traefik.tar.gz

# Extract
tar -xzf traefik.tar.gz
chmod +x traefik
sudo mv traefik /usr/local/bin/

# Verify
traefik version

Option B: Build from Source

# Clone repository
git clone https://github.com/traefik/traefik.git
cd traefik

# Build binary (requires Go 1.22+)
go build -o traefik ./cmd/traefik

# Or build with specific version flags
go build -ldflags "-s -w -X github.com/traefik/traefik/v3/pkg/version.Version=3.0.0" -o traefik ./cmd/traefik

Option C: Docker Image

# Pull official image
docker pull traefik:v3.0

# Run with sample config
docker run -d \
  -p 8080:8080 \
  -p 80:80 \
  -v $PWD/traefik.toml:/etc/traefik/traefik.toml \
  --name traefik \
  traefik:v3.0

3. Configuration

Traefik uses two types of configuration:

Static Configuration (Startup Configuration)

Create traefik.toml or traefik.yaml:

[global]
  checkNewVersion = true
  sendAnonymousUsage = false

[api]
  dashboard = true
  insecure = true  # Only for dev! Use auth in production

[entryPoints]
  [entryPoints.web]
    address = ":80"
  
  [entryPoints.websecure]
    address = ":443"

[providers]
  [providers.docker]
    exposedByDefault = false
    network = "traefik"
  
  [providers.file]
    directory = "/etc/traefik/dynamic"
    watch = true

[certificatesResolvers.letsencrypt]
  [certificatesResolvers.letsencrypt.acme]
    email = "admin@example.com"
    storage = "/etc/traefik/acme.json"
    caServer = "https://acme-v02.api.letsencrypt.org/directory"
    [certificatesResolvers.letsencrypt.acme.httpChallenge]
      entryPoint = "web"

Dynamic Configuration (Runtime Configuration)

Create dynamic/conf.toml:

[http]
  [http.routers]
    [http.routers.api]
      rule = "Host(`traefik.example.com`)"
      service = "api@internal"
      middlewares = ["auth"]
      entryPoints = ["websecure"]
      [http.routers.api.tls]
        certResolver = "letsencrypt"

  [http.services]
    [http.services.my-service]
      [http.services.my-service.loadBalancer]
        [[http.services.my-service.loadBalancer.servers]]
          url = "http://192.168.1.10:8080"
        [[http.services.my-service.loadBalancer.servers]]
          url = "http://192.168.1.11:8080"
        [http.services.my-service.loadBalancer.healthCheck]
          path = "/health"
          interval = "10s"

  [http.middlewares]
    [http.middlewares.auth.basicAuth]
      users = [
        "admin:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
      ]

Environment Variables

# Override static config via env vars
export TRAEFIK_API_DASHBOARD=true
export TRAEFIK_PROVIDERS_DOCKER_EXPOSEDBYDEFAULT=false
export TRAEFIK_ENTRYPOINTS_WEB_ADDRESS=:80
export TRAEFIK_CERTIFICATESRESOLVERS_LETSENCRYPT_ACME_EMAIL=admin@example.com

4. Build & Run

Local Development

# Run with static config
./traefik --configFile=traefik.toml

# Or with command line flags only
./traefik \
  --api.dashboard=true \
  --api.insecure=true \
  --entrypoints.web.address=:80 \
  --providers.docker=true \
  --providers.docker.exposedbydefault=false

# Access dashboard
open http://localhost:8080/dashboard/

Docker Compose (Recommended for Local Stacks)

Create docker-compose.yml:

version: '3'

services:
  traefik:
    image: traefik:v3.0
    command:
      - "--api.dashboard=true"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
      - "--certificatesresolvers.letsencrypt.acme.email=admin@example.com"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./letsencrypt:/letsencrypt
    networks:
      - traefik

  whoami:
    image: traefik/whoami
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls.certresolver=letsencrypt"
      - "traefik.http.services.whoami.loadbalancer.server.port=80"
    networks:
      - traefik

networks:
  traefik:
    external: true

Run:

docker network create traefik
docker-compose up -d

5. Deployment

Kubernetes (Production Recommended)

Option 1: Kubernetes Gateway API (v3 Recommended)

# gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: traefik-gateway
  namespace: default
spec:
  gatewayClassName: traefik
  listeners:
    - name: web
      protocol: HTTP
      port: 80
    - name: websecure
      protocol: HTTPS
      port: 443
      tls:
        certificateRefs:
          - name: my-tls-secret
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: my-route
  namespace: default
spec:
  parentRefs:
    - name: traefik-gateway
  hostnames:
    - "app.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: my-service
          port: 80

Deploy Traefik with Gateway API support:

helm repo add traefik https://traefik.github.io/charts
helm repo update
helm install traefik traefik/traefik \
  --set providers.kubernetesGateway.enabled=true \
  --set providers.kubernetesIngress.enabled=false

Option 2: Kubernetes Ingress (Traditional)

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: traefik
  namespace: kube-system
spec:
  replicas: 2
  selector:
    matchLabels:
      app: traefik
  template:
    metadata:
      labels:
        app: traefik
    spec:
      serviceAccountName: traefik
      containers:
        - name: traefik
          image: traefik:v3.0
          args:
            - --api.dashboard=true
            - --entrypoints.web.address=:80
            - --entrypoints.websecure.address=:443
            - --providers.kubernetescrd=true
            - --certificatesresolvers.letsencrypt.acme.tlschallenge=true
            - --certificatesresolvers.letsencrypt.acme.email=admin@example.com
            - --certificatesresolvers.letsencrypt.acme.storage=/data/acme.json
          ports:
            - name: web
              containerPort: 80
            - name: websecure
              containerPort: 443
            - name: admin
              containerPort: 8080
          volumeMounts:
            - name: data
              mountPath: /data
      volumes:
        - name: data
          emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
  name: traefik
  namespace: kube-system
spec:
  type: LoadBalancer
  selector:
    app: traefik
  ports:
    - protocol: TCP
      port: 80
      name: web
    - protocol: TCP
      port: 443
      name: websecure
    - protocol: TCP
      port: 8080
      name: admin

Cloud Deployment (AWS/Azure/GCP)

AWS ECS (Elastic Container Service)

// task-definition.json
{
  "family": "traefik",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "512",
  "memory": "1024",
  "containerDefinitions": [
    {
      "name": "traefik",
      "image": "traefik:v3.0",
      "essential": true,
      "command": [
        "--api.dashboard=true",
        "--entrypoints.web.address=:80",
        "--entrypoints.websecure.address=:443",
        "--providers.ecs=true",
        "--providers.ecs.region=us-east-1",
        "--providers.ecs.exposedbydefault=false"
      ],
      "portMappings": [
        {
          "containerPort": 80,
          "protocol": "tcp"
        },
        {
          "containerPort": 443,
          "protocol": "tcp"
        },
        {
          "containerPort": 8080,
          "protocol": "tcp"
        }
      ]
    }
  ]
}

Deploy:

aws ecs register-task-definition --cli-input-json file://task-definition.json
aws ecs create-service --cluster my-cluster --service-name traefik --task-definition traefik:1 --desired-count 2 --launch-type FARGATE --network-configuration "awsvpcConfiguration={subnets=[subnet-12345678],securityGroups=[sg-12345678],assignPublicIp=ENABLED}"

6. Troubleshooting

Common Issues

1. Dashboard Not Accessible

Symptom: Cannot access http://localhost:8080/dashboard/

Solution:

# Check if API is enabled
./traefik --api.dashboard=true --api.insecure=true  # Dev only!

# For production, use secure mode with basic auth
./traefik --api.dashboard=true \
  --api.basicauth.users=admin:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/

2. Let's Encrypt Certificate Issues

Symptom: unable to generate a certificate for the domains

Solutions:

# Verify storage permissions
chmod 600 /etc/traefik/acme.json
chown traefik:traefik /etc/traefik/acme.json

# Check DNS resolution from container
docker exec traefik nslookup yourdomain.com

# Use staging server for testing
./traefik --certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory

3. Docker Provider Not Detecting Containers

Symptom: Services not appearing in dashboard

Solution:

# Verify Docker socket access
docker run -v /var/run/docker.sock:/var/run/docker.sock:ro traefik:v3.0

# Check container labels
docker inspect your_container | grep -A 10 Labels

# Required labels example:
# traefik.enable=true
# traefik.http.routers.myapp.rule=Host(`example.com`)
# traefik.http.services.myapp.loadbalancer.server.port=80

4. Kubernetes Gateway API Routes Not Working

Symptom: HTTPRoute created but getting 404

Solutions:

# Check GatewayClass
kubectl get gatewayclass traefik -o yaml

# Verify Gateway status
kubectl describe gateway traefik-gateway

# Check HTTPRoute parent refs
kubectl get httproute my-route -o yaml | grep parentRefs -A 5

# View Traefik logs
kubectl logs -n kube-system deployment/traefik -f

5. High Memory Usage

Symptom: Traefik consuming excessive RAM

Solution:

[global]
  # Disable anonymous usage reporting
  sendAnonymousUsage = false

[serversTransport]
  # Limit idle connections
  maxIdleConnsPerHost = 100

[entryPoints.web]
  address = ":80"
  # Enable connection limits
  [entryPoints.web.transport]
    [entryPoints.web.transport.lifeCycle]
      requestAcceptGraceTimeout = 0
      graceTimeOut = "10s"

Debug Mode

Enable debug logging:

# Command line
./traefik --log.level=DEBUG

# Or in config
[log]
  level = "DEBUG"
  format = "json"

Health Check Endpoint

Verify Traefik is healthy:

curl http://localhost:8080/ping
# Returns: OK

Getting Help

Migration Notes

When upgrading from v2 to v3:

  • Review the migration guide
  • Update deprecated middleware configurations
  • Verify Kubernetes CRD versions
  • Test certificate renewal behavior