83f94b1f09
Add complete documentation structure: - Frontend architecture documentation - Database schema documentation - Deployment guides (Docker, Traefik, Authentik, Environment) - Development guides (Setup, Testing, Contributing, Quality Gates) - Deployment architecture documentation - Updated docs README with complete navigation All new features and APIs are now documented. Quality gates: docs only, no code changes
7.2 KiB
7.2 KiB
Traefik Reverse Proxy Setup
Overview
Traefik serves as the reverse proxy and load balancer for Headquarter in production, handling:
- SSL/TLS termination
- Automatic HTTPS via Let's Encrypt
- Route-based traffic distribution
- WebSocket support
Architecture
Internet
↓
Traefik (443)
├───▶ api.yourdomain.com → Headquarter API (8000)
└───▶ app.yourdomain.com → Headquarter Web (80)
Prerequisites
- Docker Compose installed
- DNS records pointing to your server:
api.yourdomain.com→ Server IPapp.yourdomain.com→ Server IP
- Ports 80 and 443 open in firewall
Configuration
1. Environment Variables
# .env file
API_DOMAIN=api.headquarter.example.com
WEB_DOMAIN=app.headquarter.example.com
# Traefik network (shared with other Traefik instances)
TRAEFIK_NETWORK=web
# SSL Certificate resolver
TRAEFIK_CERT_RESOLVER=letsencrypt
2. Traefik Labels
Services are configured via Docker labels:
# API Service labels
labels:
- "traefik.enable=true"
- "traefik.http.routers.headquarter-api.rule=Host(`api.headquarter.example.com`)"
- "traefik.http.routers.headquarter-api.entrypoints=websecure"
- "traefik.http.routers.headquarter-api.tls=true"
- "traefik.http.routers.headquarter-api.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-letsencrypt}"
- "traefik.http.services.headquarter-api.loadbalancer.server.port=8000"
# Web Service labels
labels:
- "traefik.enable=true"
- "traefik.http.routers.headquarter-frontend.rule=Host(`app.headquarter.example.com`)"
- "traefik.http.routers.headquarter-frontend.entrypoints=websecure"
- "traefik.http.routers.headquarter-frontend.tls=true"
- "traefik.http.routers.headquarter-frontend.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-letsencrypt}"
- "traefik.http.services.headquarter-frontend.loadbalancer.server.port=80"
3. External Network
Connect to existing Traefik instance:
networks:
traefik:
external: true
name: ${TRAEFIK_NETWORK:-traefik}
Deployment Steps
Step 1: Verify DNS
Ensure DNS records resolve to your server:
nslookup api.headquarter.example.com
nslookup app.headquarter.example.com
Step 2: Start Services
# Start with Traefik compose file
docker compose -f docker-compose.traefik.yml up -d
# Verify containers are running
docker compose -f docker-compose.traefik.yml ps
Step 3: Check SSL Certificates
# View Traefik logs
docker compose -f docker-compose.traefik.yml logs -f
# Check certificate status
curl -v https://api.headquarter.example.com/health
Step 4: Run Migrations
docker compose -f docker-compose.traefik.yml exec api alembic upgrade head
SSL Configuration
Let's Encrypt (Default)
Automatic certificate generation and renewal:
labels:
- "traefik.http.routers.headquarter-api.tls.certresolver=letsencrypt"
Custom Certificates
For custom or wildcard certificates:
labels:
- "traefik.http.routers.headquarter-api.tls=true"
- "traefik.http.routers.headquarter-api.tls.certresolver=myresolver"
Self-Signed (Development)
labels:
- "traefik.http.routers.headquarter-api.tls=true"
- "traefik.http.routers.headquarter-api.tls.certresolver=selfsigned"
Advanced Configuration
Rate Limiting
labels:
- "traefik.http.middlewares.ratelimit.ratelimit.average=100"
- "traefik.http.routers.headquarter-api.middlewares=ratelimit"
Basic Auth (for staging)
labels:
- "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/"
- "traefik.http.routers.headquarter-api.middlewares=auth"
CORS Headers
labels:
- "traefik.http.middlewares.cors.headers.accesscontrolalloworiginlist=*"
- "traefik.http.routers.headquarter-api.middlewares=cors"
Troubleshooting
Certificate Issues
Problem: Certificate not generated
# Check Traefik logs
docker compose logs traefik
# Verify DNS resolution
nslookup your-domain.com
# Check port 80 is accessible (required for HTTP challenge)
curl -I http://your-domain.com
Problem: Certificate expired
# Force renewal
docker compose restart traefik
# Or delete acme.json and restart
rm acme.json
docker compose restart traefik
Routing Issues
Problem: 404 errors
# Check Traefik dashboard (if enabled)
# http://traefik.yourdomain.com
# Verify labels are correct
docker compose -f docker-compose.traefik.yml config
# Check container is on correct network
docker network inspect ${TRAEFIK_NETWORK:-traefik}
Problem: Services not detected
# Verify traefik.enable label
docker compose -f docker-compose.traefik.yml exec api labels
# Check Docker provider in Traefik
docker compose logs traefik | grep "Provider connection established"
Maintenance
Update Traefik
# Pull latest Traefik image
docker compose -f docker-compose.traefik.yml pull traefik
# Restart
docker compose -f docker-compose.traefik.yml up -d traefik
View Dashboard
Enable Traefik dashboard (secure it in production):
# traefik.yml
dashboard:
enabled: true
# Add to docker-compose.traefik.yml
labels:
- "traefik.http.routers.dashboard.rule=Host(`traefik.yourdomain.com`)"
- "traefik.http.routers.dashboard.tls=true"
- "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
Security Considerations
- Always use HTTPS in production (redirect HTTP to HTTPS)
- Secure Traefik dashboard with authentication
- Use strong certificate resolver (Let's Encrypt production)
- Keep Traefik updated for security patches
- Restrict Docker socket access if using Docker provider
Example Complete Configuration
# docker-compose.traefik.yml
services:
api:
build:
context: ./apps/api
environment:
API_DOMAIN: ${API_DOMAIN}
WEB_DOMAIN: ${WEB_DOMAIN}
# ... other env vars
labels:
- "traefik.enable=true"
- "traefik.http.routers.headquarter-api.rule=Host(`${API_DOMAIN}`)"
- "traefik.http.routers.headquarter-api.entrypoints=websecure"
- "traefik.http.routers.headquarter-api.tls=true"
- "traefik.http.routers.headquarter-api.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-letsencrypt}"
- "traefik.http.services.headquarter-api.loadbalancer.server.port=8000"
networks:
- backend
- traefik
web:
build:
context: ./apps/web
labels:
- "traefik.enable=true"
- "traefik.http.routers.headquarter-frontend.rule=Host(`${WEB_DOMAIN}`)"
- "traefik.http.routers.headquarter-frontend.entrypoints=websecure"
- "traefik.http.routers.headquarter-frontend.tls=true"
- "traefik.http.routers.headquarter-frontend.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-letsencrypt}"
- "traefik.http.services.headquarter-frontend.loadbalancer.server.port=80"
networks:
- traefik
networks:
traefik:
external: true
name: ${TRAEFIK_NETWORK:-traefik}
backend:
internal: true