Traefik Reverse Proxy Server Documentation

Server IP: 10.3.3.3 Hostname: ha.local.dev Dashboard: http://10.3.3.3:8080/dashboard/ API: http://10.3.3.3:8080/api/ Last Updated: November 20, 2025

Overview

Traefik is a modern HTTP reverse proxy and load balancer that manages routing for the local.dev infrastructure. It provides automatic HTTPS via Let's Encrypt, dynamic configuration via Redis, and serves as the central entry point for all web traffic.

What We Have

  • Reverse Proxy Software: Traefik
  • Version: 3.0.4 (Codename: beaufort)
  • Built: July 2, 2024
  • Deployment Method: Docker container
  • Container Name: traefik
  • Image: traefik:v3.0
  • Go Version: go1.22.4
  • Platform: linux/amd64

Where It Runs

Server Details

  • Host: ha.local.dev (10.3.3.3)
  • Platform: Docker on Linux
  • Container Runtime: Docker

Container Configuration

Container Name: traefik

Port Mappings:

  • 80/tcp → Host port 80 (HTTP)
  • 443/tcp → Host port 443 (HTTPS)
  • 8080/tcp → Host port 8080 (Dashboard & API)

Volume Mounts:

  • Docker Socket: /var/run/docker.sock:/var/run/docker.sock:ro (Read-only access to Docker for container discovery)
  • ACME Storage: /opt/traefik/acme.json:/acme.json (SSL certificate storage)

Restart Policy: unless-stopped (automatically restarts unless manually stopped)

Network: traefik-net (external network shared with other services)

Configuration

Entry Points

Traefik is configured with three entry points:

  1. web (Port 80)

    • HTTP traffic entry point
    • Automatically redirects to HTTPS (websecure)
    • Redirect scheme: https
  2. websecure (Port 443)

    • HTTPS traffic entry point
    • TLS enabled by default
    • Certificate resolver: Cloudflare DNS challenge
  3. traefik (Port 8080)

    • Dashboard and API access
    • Insecure mode enabled (no authentication required)
    • Local network access only

Providers

Redis Provider (Primary):

  • Endpoint: 10.3.3.3:6379
  • Database: 0
  • Root Key: traefik
  • Password: Configured via environment (secured)
  • Purpose: Dynamic routing configuration storage

Docker Provider: Not enabled (routes configured via Redis only)

SSL/TLS Certificates

Certificate Resolver: Cloudflare DNS Challenge

  • Email: tim@do.dev
  • Storage: /opt/traefik/acme.json
  • Provider: Cloudflare DNS challenge
  • DNS Resolvers: 1.1.1.1:53, 8.8.8.8:53
  • Auto-renewal: Enabled (Let's Encrypt 90-day certificates)

Environment Variables:

  • CF_DNS_API_TOKEN: Cloudflare API token for DNS challenge (set in .env file)

Logging

  • Log Level: INFO
  • Access Log: Enabled
  • Format: Standard Traefik log format

Feature Flags

  • --global.checkNewVersion=false (Disable version check)
  • --global.sendAnonymousUsage=false (Disable telemetry)
  • --api.debug=true (Enable debug mode for API)

Current Routes

Configured Routers: 6 Configured Services: 4 Configured Middlewares: 6

Example Router (do.dev):

  • Rule: Host(\do.dev`)`
  • Service: service-do-dev
  • Entry Point: websecure (HTTPS)
  • TLS: Enabled
  • Middlewares: compress, headers-default, rate-limit-default

Access and Management

Web Dashboard

  • URL: http://10.3.3.3:8080/dashboard/
  • Authentication: None (insecure mode enabled)
  • Features:
    • Router overview
    • Service health status
    • Middleware configuration
    • Real-time metrics
    • TLS certificate information

Important: Dashboard is accessible without authentication. Restrict access to local network only.

API Access

Common API Endpoints:

# Overview
curl http://10.3.3.3:8080/api/overview | jq .

# List all HTTP routers
curl http://10.3.3.3:8080/api/http/routers | jq .

# List all HTTP services
curl http://10.3.3.3:8080/api/http/services | jq .

# List all middlewares
curl http://10.3.3.3:8080/api/http/middlewares | jq .

# Get specific router
curl http://10.3.3.3:8080/api/http/routers/router-do-dev | jq .

SSH Access

ssh root@10.3.3.3

Docker Commands

View container status:

docker ps | grep traefik

View container logs:

docker logs traefik
docker logs -f traefik  # Follow logs in real-time
docker logs --tail 100 traefik  # Last 100 lines

Stop Traefik:

docker stop traefik

Start Traefik:

docker start traefik

Restart Traefik:

docker restart traefik

Redis Configuration Management

Traefik uses Redis for dynamic configuration. Routes, services, and middlewares are stored in Redis and automatically loaded by Traefik.

Accessing Redis

# Connect to Redis CLI
docker exec -it traefik-redis redis-cli -a "e7374de72f110d1609feec2febe68d300feeafb4f6ab1236dfc598b37ae0a662"

# List all Traefik configuration keys
redis-cli -a "password" KEYS "traefik/*"

Example Router Configuration in Redis

To add a new route, store the configuration in Redis:

# Set router rule
redis-cli -a "password" SET traefik/http/routers/my-app/rule "Host(\`my-app.local.dev\`)"

# Set router service
redis-cli -a "password" SET traefik/http/routers/my-app/service "my-app-service"

# Set router entrypoint
redis-cli -a "password" SET traefik/http/routers/my-app/entrypoints "websecure"

# Enable TLS
redis-cli -a "password" SET traefik/http/routers/my-app/tls "true"

# Set service URL
redis-cli -a "password" SET traefik/http/services/my-app-service/loadBalancer/servers/0/url "http://10.3.0.33:3000"

Traefik will automatically detect the changes within seconds.

Viewing Current Configuration

# Get all routers
docker exec traefik-redis redis-cli -a "password" --no-auth-warning KEYS "traefik/http/routers/*"

# Get specific router rule
docker exec traefik-redis redis-cli -a "password" --no-auth-warning GET traefik/http/routers/router-do-dev/rule

# Get all services
docker exec traefik-redis redis-cli -a "password" --no-auth-warning KEYS "traefik/http/services/*"

Configuration Files

Docker Compose File Location

  • Path: /opt/traefik/docker-compose.yml
  • Backup: /opt/traefik/docker-compose.yml.backup

Environment File

  • Path: /opt/traefik/.env
  • Contains: Cloudflare API token

ACME Certificate Storage

  • Path: /opt/traefik/acme.json
  • Permissions: 600 (read/write for owner only)
  • Format: JSON
  • Contains: Let's Encrypt certificates and private keys

How to Update

Step 1: Pull the latest image

ssh root@10.3.3.3 'cd /opt/traefik && docker-compose pull'

Step 2: Recreate the container with new image

ssh root@10.3.3.3 'cd /opt/traefik && docker-compose up -d'

Step 3: Verify the update

ssh root@10.3.3.3 'docker exec traefik traefik version'

Step 4: Check the dashboard

Method 2: Manual Update

# Stop and remove old container
ssh root@10.3.3.3 'docker stop traefik && docker rm traefik'

# Pull new image
ssh root@10.3.3.3 'docker pull traefik:v3.0'

# Recreate container
ssh root@10.3.3.3 'cd /opt/traefik && docker-compose up -d'

Update Script

Create a script file update-traefik.sh:

#!/bin/bash
set -e

echo "=== Traefik Update ==="
cd /opt/traefik

echo "Creating backup of current configuration..."
cp docker-compose.yml docker-compose.yml.backup-$(date +%Y%m%d)

echo "Pulling latest Traefik image..."
docker-compose pull

echo "Recreating container with new image..."
docker-compose up -d

echo "Waiting for Traefik to start..."
sleep 5

echo "Verifying version..."
docker exec traefik traefik version

echo "Checking container status..."
docker ps | grep traefik

echo "=== Update Complete ==="
echo "Dashboard: http://10.3.3.3:8080/dashboard/"

Run it on the server:

ssh root@10.3.3.3 'bash -s' < update-traefik.sh

Important Notes

⚠️ Certificate Persistence: The acme.json file is mounted as a bind mount and will persist across updates.

⚠️ Configuration Persistence: Redis stores all routing configuration, which persists independently of Traefik updates.

⚠️ Zero Downtime: Docker Compose will handle graceful shutdown and startup, typically resulting in minimal downtime (1-2 seconds).

Adding New Routes

Example: Add a new service at my-service.local.dev

# SSH to server
ssh root@10.3.3.3

# Set router configuration
docker exec traefik-redis redis-cli -a "e7374de72f110d1609feec2febe68d300feeafb4f6ab1236dfc598b37ae0a662" --no-auth-warning << EOF
SET traefik/http/routers/my-service/rule "Host(\`my-service.local.dev\`)"
SET traefik/http/routers/my-service/service "my-service-backend"
SET traefik/http/routers/my-service/entrypoints "websecure"
SET traefik/http/routers/my-service/tls "true"
SET traefik/http/routers/my-service/priority "100"

# Configure service backend
SET traefik/http/services/my-service-backend/loadBalancer/servers/0/url "http://10.3.0.33:3000"

# Add health check
SET traefik/http/services/my-service-backend/loadBalancer/healthCheck/path "/health"
SET traefik/http/services/my-service-backend/loadBalancer/healthCheck/interval "10s"

# Add middlewares (optional)
SET traefik/http/routers/my-service/middlewares "compress,rate-limit-default"
EOF

Verify the route:

curl http://10.3.3.3:8080/api/http/routers/my-service | jq .

Via Convex Integration

For routes managed by the local.dev infrastructure, use the Convex backend to create routes. The Convex mutations will automatically update Redis with the appropriate Traefik configuration.

See TRAEFIK_MIGRATION_GUIDE.md for details on Convex integration.

Middlewares

Traefik supports various middlewares for request/response manipulation:

Available Middlewares

  1. compress - GZIP compression
  2. headers-default - Security headers
    • X-Forwarded-Proto: https
    • STS headers for HSTS
    • STS max-age, includeSubdomains, preload
  3. rate-limit-default - Rate limiting
    • Average: Configurable requests per period
    • Burst: Configurable burst size
    • Period: Configurable time window

Adding Custom Middleware

# Example: Add CORS middleware
redis-cli -a "password" << EOF
SET traefik/http/middlewares/cors/headers/accessControlAllowMethods "GET,POST,PUT,DELETE,OPTIONS"
SET traefik/http/middlewares/cors/headers/accessControlAllowOriginList "https://my-app.local.dev"
SET traefik/http/middlewares/cors/headers/accessControlAllowHeaders "Content-Type,Authorization"
SET traefik/http/middlewares/cors/headers/accessControlMaxAge "3600"
EOF

# Apply to router
redis-cli -a "password" SET traefik/http/routers/my-service/middlewares "compress,cors,rate-limit-default"

Backup and Restore

Backup

Option 1: Configuration Backup

ssh root@10.3.3.3 'cd /opt/traefik && tar czf /root/backups/traefik-config-$(date +%Y%m%d).tar.gz docker-compose.yml .env acme.json'

Option 2: Redis Configuration Backup

ssh root@10.3.3.3 'docker exec traefik-redis redis-cli -a "password" --no-auth-warning --rdb /data/dump-$(date +%Y%m%d).rdb SAVE'

Option 3: Full System Backup

ssh root@10.3.3.3 'tar czf /root/backups/traefik-full-$(date +%Y%m%d).tar.gz /opt/traefik /var/lib/docker/volumes/redis_redis-data'

Restore

From Configuration Backup:

# Stop Traefik
ssh root@10.3.3.3 'docker stop traefik'

# Restore files
ssh root@10.3.3.3 'cd /opt/traefik && tar xzf /root/backups/traefik-config-YYYYMMDD.tar.gz'

# Restart Traefik
ssh root@10.3.3.3 'docker start traefik'

From Redis Backup:

# Stop Redis
ssh root@10.3.3.3 'docker stop traefik-redis'

# Restore dump file
ssh root@10.3.3.3 'docker cp /path/to/dump.rdb traefik-redis:/data/dump.rdb'

# Start Redis
ssh root@10.3.3.3 'docker start traefik-redis'

Troubleshooting

Traefik Not Responding

Check if container is running:

ssh root@10.3.3.3 'docker ps | grep traefik'

Check container logs:

ssh root@10.3.3.3 'docker logs --tail 100 traefik'

Restart the container:

ssh root@10.3.3.3 'docker restart traefik'

Dashboard Not Accessible

Verify port 8080 is listening:

ssh root@10.3.3.3 'netstat -tlnp | grep 8080'

Test local access:

ssh root@10.3.3.3 'curl -I http://localhost:8080/dashboard/'

Check API insecure flag:

ssh root@10.3.3.3 'docker inspect traefik | grep "api.insecure"'

Should return: "--api.insecure=true"

SSL Certificate Issues

Check ACME storage:

ssh root@10.3.3.3 'ls -la /opt/traefik/acme.json'

Verify permissions (must be 600):

ssh root@10.3.3.3 'chmod 600 /opt/traefik/acme.json'

Check certificate resolver logs:

ssh root@10.3.3.3 'docker logs traefik | grep -i acme'

Verify Cloudflare API token:

ssh root@10.3.3.3 'cat /opt/traefik/.env | grep CF_DNS_API_TOKEN'

Route Not Working

Check if route exists in Redis:

ssh root@10.3.3.3 'docker exec traefik-redis redis-cli -a "password" --no-auth-warning KEYS "traefik/http/routers/*"'

Verify router configuration:

ssh root@10.3.3.3 'curl http://localhost:8080/api/http/routers/your-router-name | jq .'

Check service health:

ssh root@10.3.3.3 'curl http://localhost:8080/api/http/services/your-service-name | jq .'

Test backend directly:

ssh root@10.3.3.3 'curl -I http://backend-ip:backend-port/'

Redis Connection Issues

Check Redis container:

ssh root@10.3.3.3 'docker ps | grep redis'

Test Redis connection:

ssh root@10.3.3.3 'docker exec traefik-redis redis-cli -a "password" --no-auth-warning PING'

Should return: PONG

Check Traefik Redis provider logs:

ssh root@10.3.3.3 'docker logs traefik | grep -i redis'

Monitoring

Container Health

Check container status:

docker ps | grep traefik

Check resource usage:

docker stats traefik --no-stream

View recent logs:

docker logs --tail 50 traefik

Route Health

Dashboard Overview:

API Health Check:

# Overview
curl http://10.3.3.3:8080/api/overview | jq .

# Router errors
curl http://10.3.3.3:8080/api/http/routers | jq '.[] | select(.status != "enabled")'

# Service errors
curl http://10.3.3.3:8080/api/http/services | jq '.[] | select(.serverStatus | length == 0)'

Access Logs

Access logs are enabled and written to Docker stdout:

# View all access logs
docker logs traefik | grep -v "WRN\|ERR"

# View errors only
docker logs traefik | grep "ERR"

# View specific route access
docker logs traefik | grep "do.dev"

Security Considerations

  1. Dashboard Access: The dashboard is exposed with --api.insecure=true for local network access. Do not expose port 8080 to the public internet.

  2. Redis Password: The Redis password is configured in the docker-compose file. Rotate it periodically:

    # Generate new password
    openssl rand -hex 32
    
    # Update docker-compose.yml with new password
    # Update Redis configuration
    # Restart both Traefik and Redis
  3. Cloudflare API Token: Store the CF_DNS_API_TOKEN securely in the .env file with restricted permissions:

    chmod 600 /opt/traefik/.env
  4. ACME Certificate Storage: The acme.json file contains private keys. Ensure proper permissions:

    chmod 600 /opt/traefik/acme.json
  5. Firewall Rules: Configure firewall to:

    • Allow ports 80, 443 from public internet
    • Restrict port 8080 to local network only (10.3.0.0/16)
    • Restrict port 6379 (Redis) to localhost only
  6. TLS Configuration: All routes should use the websecure entrypoint with TLS enabled. HTTP (port 80) is automatically redirected to HTTPS.

Integration with Local Development

Traefik is the central reverse proxy for the local.dev infrastructure:

  • Local.dev Domain: Routes *.local.dev subdomains to local services
  • Development Domains: Handles do.dev, sell.dev, and other development domains
  • SSL/TLS: Automatic HTTPS for all domains via Let's Encrypt
  • Convex Integration: Routes are managed through Convex backend mutations
  • DNS Integration: Works with Technitium DNS Server for local domain resolution

For more information on the local.dev infrastructure, see:

Performance Tuning

Connection Limits

Add to docker-compose.yml command section:

- --entrypoints.web.transport.respondingTimeouts.readTimeout=60s
- --entrypoints.web.transport.respondingTimeouts.writeTimeout=60s
- --entrypoints.websecure.transport.respondingTimeouts.readTimeout=60s
- --entrypoints.websecure.transport.respondingTimeouts.writeTimeout=60s

Rate Limiting

Adjust in Redis:

# Increase rate limit
redis-cli -a "password" SET traefik/http/middlewares/rate-limit-default/rateLimit/average "200"
redis-cli -a "password" SET traefik/http/middlewares/rate-limit-default/rateLimit/burst "400"

Compression

Enable for all routes:

# Enable compression middleware globally
redis-cli -a "password" SET traefik/http/routers/your-router/middlewares "compress,headers-default"

Useful Commands Reference

# Container Management
docker ps | grep traefik                    # Check status
docker logs -f traefik                      # Follow logs
docker restart traefik                      # Restart
docker stats traefik --no-stream            # Resource usage

# API Queries
curl http://10.3.3.3:8080/api/overview | jq .                  # Overview
curl http://10.3.3.3:8080/api/http/routers | jq .              # List routers
curl http://10.3.3.3:8080/api/http/services | jq .             # List services
curl http://10.3.3.3:8080/api/version | jq .                   # Version info

# Redis Queries
docker exec traefik-redis redis-cli -a "password" --no-auth-warning KEYS "traefik/*"
docker exec traefik-redis redis-cli -a "password" --no-auth-warning GET "traefik/http/routers/router-do-dev/rule"

# Certificate Management
cat /opt/traefik/acme.json | jq .           # View certificates
ls -la /opt/traefik/acme.json               # Check permissions

# Configuration
cat /opt/traefik/docker-compose.yml         # View config
docker inspect traefik | jq .[0].Args       # View runtime args

References

Change Log

DateChangeAuthor
2025-11-20Initial documentation createdClaude
2025-11-20Added --api.insecure=true to enable dashboard accessClaude
2025-11-20Fixed dashboard accessibility issueClaude

On this page