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:
-
web (Port 80)
- HTTP traffic entry point
- Automatically redirects to HTTPS (websecure)
- Redirect scheme:
https
-
websecure (Port 443)
- HTTPS traffic entry point
- TLS enabled by default
- Certificate resolver: Cloudflare DNS challenge
-
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
- Base URL: http://10.3.3.3:8080/api/
- Authentication: None (insecure mode enabled)
- Format: JSON
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.3Docker Commands
View container status:
docker ps | grep traefikView container logs:
docker logs traefik
docker logs -f traefik # Follow logs in real-time
docker logs --tail 100 traefik # Last 100 linesStop Traefik:
docker stop traefikStart Traefik:
docker start traefikRestart Traefik:
docker restart traefikRedis 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
Method 1: Standard Update (Recommended)
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
- Navigate to http://10.3.3.3:8080/dashboard/
- Verify all routes are active
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.shImportant 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
Via Redis (Recommended for Dynamic 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"
EOFVerify 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
- compress - GZIP compression
- headers-default - Security headers
X-Forwarded-Proto: https- STS headers for HSTS
- STS max-age, includeSubdomains, preload
- 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 traefikCheck resource usage:
docker stats traefik --no-streamView recent logs:
docker logs --tail 50 traefikRoute Health
Dashboard Overview:
- Navigate to http://10.3.3.3:8080/dashboard/
- Check "HTTP" section for router/service status
- Look for errors or warnings (red indicators)
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
-
Dashboard Access: The dashboard is exposed with
--api.insecure=truefor local network access. Do not expose port 8080 to the public internet. -
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 -
Cloudflare API Token: Store the CF_DNS_API_TOKEN securely in the .env file with restricted permissions:
chmod 600 /opt/traefik/.env -
ACME Certificate Storage: The acme.json file contains private keys. Ensure proper permissions:
chmod 600 /opt/traefik/acme.json -
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
-
TLS Configuration: All routes should use the
websecureentrypoint 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:
- DNS_DESIGN.md - DNS architecture and design
- TRAEFIK_MIGRATION_GUIDE.md - Traefik integration with Convex
- TECHNITIUM_DNS_SERVER.md - DNS server documentation
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=60sRate 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 argsReferences
- Official Documentation: https://doc.traefik.io/traefik/
- GitHub Repository: https://github.com/traefik/traefik
- Docker Hub: https://hub.docker.com/_/traefik
- API Documentation: https://doc.traefik.io/traefik/operations/api/
- Middleware Reference: https://doc.traefik.io/traefik/middlewares/overview/
- Let's Encrypt: https://letsencrypt.org/
Change Log
| Date | Change | Author |
|---|---|---|
| 2025-11-20 | Initial documentation created | Claude |
| 2025-11-20 | Added --api.insecure=true to enable dashboard access | Claude |
| 2025-11-20 | Fixed dashboard accessibility issue | Claude |