docs: comprehensive documentation overhaul

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
This commit is contained in:
Fusion
2026-05-19 14:18:20 +02:00
parent 6807f449b7
commit 83f94b1f09
31 changed files with 5498 additions and 0 deletions
+201
View File
@@ -0,0 +1,201 @@
# Authentik OAuth Configuration
## Overview
Headquarter uses Authentik as its OAuth2 provider for authentication. This guide covers setting up Authentik and configuring Headquarter to work with it.
## Prerequisites
- Running Authentik instance
- Admin access to Authentik
- Headquarter deployed and accessible
## Authentik Setup
### Step 1: Create Application
1. Log in to Authentik Admin interface
2. Navigate to **Applications****Applications**
3. Click **Create**
4. Fill in:
- **Name**: Headquarter
- **Slug**: `headquarter-web` (or your preferred slug)
- **Provider**: Create new
### Step 2: Create OAuth Provider
1. In the provider creation form:
- **Name**: Headquarter OAuth
- **Authentication flow**: `default-authentication-flow`
- **Authorization flow**: `default-provider-authorization-explicit-consent`
- **Client type**: Confidential
- **Client ID**: Generate or use your own UUID
- **Client Secret**: Generate strong secret
- **Redirect URIs**: `https://api.yourdomain.com/auth/callback`
2. **Advanced protocol settings**:
- **Signing Key**: Select a signing key (required)
- **Access Token validity**: Minutes (default: 5)
- **Refresh Token validity**: Days (default: 30)
3. Save provider
### Step 3: Configure Application
1. Return to Application configuration
2. Select the created provider
3. Save application
### Step 4: Verify URLs
Note these URLs from your Authentik instance:
- **Authorize URL**: `https://auth.yourdomain.com/application/o/authorize/`
- **Token URL**: `https://auth.yourdomain.com/application/o/token/`
- **UserInfo URL**: `https://auth.yourdomain.com/application/o/userinfo/`
- **JWKS URL**: `https://auth.yourdomain.com/application/o/headquarter-web/jwks/`
## Headquarter Configuration
### Environment Variables
Add to your `.env` file:
```bash
# Authentik Configuration
AUTHENTIK_DOMAIN=auth.yourdomain.com
AUTHENTIK_CLIENT_ID=your-client-id-uuid
AUTHENTIK_CLIENT_SECRET=your-generated-secret
AUTHENTIK_APPLICATION_SLUG=headquarter-web
AUTHENTIK_AUDIENCE=your-client-id-uuid
# Optional: Override default URLs if needed
# AUTHENTIK_AUTHORIZE_URL=https://auth.yourdomain.com/application/o/authorize/
# AUTHENTIK_TOKEN_URL=https://auth.yourdomain.com/application/o/token/
# AUTHENTIK_JWKS_URL=https://auth.yourdomain.com/application/o/headquarter-web/jwks/
# AUTHENTIK_ISSUER=https://auth.yourdomain.com/application/o/headquarter-web/
```
### Important Notes
- **AUTHENTIK_CLIENT_ID**: The UUID from Authentik (used for OAuth)
- **AUTHENTIK_APPLICATION_SLUG**: The URL-friendly name (e.g., `headquarter-web`)
- **AUTHENTIK_AUDIENCE**: Usually same as Client ID
## User Synchronization
On first login, Headquarter creates a local user record:
```python
user = User(
email="user@example.com",
name="User Name",
authentik_id="authentik-user-id",
)
```
### Synced Fields
| Authentik Field | Headquarter Field |
|----------------|-------------------|
| email | email |
| name | name |
| sub (user ID) | authentik_id |
| groups | (future: team membership) |
## Troubleshooting
### Redirect URI Error
**Problem**: "Redirect URI Error" from Authentik
**Solution**:
1. Check redirect URI in Authentik matches exactly
2. Must include protocol: `https://api.yourdomain.com/auth/callback`
3. No trailing slash difference
### Invalid Client
**Problem**: "invalid_client" error
**Solution**:
1. Verify Client ID matches
2. Verify Client Secret is correct
3. Check application slug in URLs
### Missing Refresh Token
**Problem**: Authentik doesn't return refresh token
**Solution**:
This is normal. Headquarter creates its own session cookies and doesn't need refresh tokens from Authentik.
### CORS Errors
**Problem**: CORS errors in browser
**Solution**:
1. Ensure API domain is in CORS origins
2. Check `WEB_BASE_URL` environment variable
3. Verify cookies have correct domain
## Security Best Practices
1. **Use HTTPS** - Never use HTTP in production
2. **Strong Client Secret** - Use generated secret, don't reuse
3. **Short Token Lifetime** - Keep access tokens short-lived
4. **Validate State** - Always verify state parameter
5. **Secure Cookies** - Use httpOnly, Secure, SameSite
## Advanced Configuration
### Custom Claims
To add custom claims to the token:
1. In Authentik, go to **Customization****Property Mappings**
2. Create new **Scope Mapping**
3. Add custom attributes
4. Assign to provider
### Group Mapping
For team/organization support:
1. Configure group property mapping in Authentik
2. Headquarter will sync groups on login
3. Use groups for authorization
### Multiple Applications
If running multiple environments:
1. Create separate applications in Authentik
2. Use different client IDs
3. Configure environment-specific redirect URIs
## Testing
### Manual Test
1. Visit `https://app.yourdomain.com`
2. Click "Login"
3. Should redirect to Authentik
4. Login with Authentik credentials
5. Should redirect back to app, logged in
### API Test
```bash
# Check auth endpoint
curl https://api.yourdomain.com/auth/me
# Should return 401 (not authenticated)
# After login, should return user data
curl https://api.yourdomain.com/auth/me --cookie "session=..."
```
## Resources
- [Authentik Documentation](https://goauthentik.io/docs/)
- [OAuth2 Provider Setup](https://goauthentik.io/docs/providers/oauth2/)
- [Headquarter Auth Documentation](../features/auth.md)
+266
View File
@@ -0,0 +1,266 @@
# Docker Deployment Guide
## Overview
Headquarter is deployed as a multi-container Docker application using Docker Compose. The stack includes:
- **API** (FastAPI/Python)
- **Web** (React/Vite)
- **PostgreSQL** (Database)
- **Redis** (Cache)
## Quick Start
### Prerequisites
- Docker Engine 20.10+
- Docker Compose 2.0+
- 2GB RAM minimum
- 10GB disk space
### Development Deployment
```bash
# Clone repository
git clone https://github.com/your-org/headquarter.git
cd headquarter
# Copy environment file
cp .env.example .env
# Edit .env with your settings
# Start all services
docker compose up -d
# Run database migrations
docker compose exec api alembic upgrade head
# Access the app
# Frontend: http://localhost:5173
# API: http://localhost:8000
```
### Production Deployment
```bash
# Use production compose file
cp .env.example .env
# Configure production values in .env
docker compose -f docker-compose.traefik.yml up -d
# Run migrations
docker compose -f docker-compose.traefik.yml exec api alembic upgrade head
```
## Configuration
### Environment Variables
Required variables:
```bash
# Domains
API_DOMAIN=api.yourdomain.com
WEB_DOMAIN=app.yourdomain.com
# Database
POSTGRES_USER=headquarter
POSTGRES_PASSWORD=secure-password
POSTGRES_DB=headquarter
# Authentik OAuth
AUTHENTIK_DOMAIN=auth.yourdomain.com
AUTHENTIK_CLIENT_ID=your-client-id
AUTHENTIK_CLIENT_SECRET=your-client-secret
AUTHENTIK_APPLICATION_SLUG=headquarter
# Session
SESSION_SECRET=your-session-secret-min-32-chars
# Storage
REPO_BASE_PATH=/data/repos
```
### Volume Mounts
| Volume | Container Path | Purpose |
|--------|---------------|---------|
| postgres_data | /var/lib/postgresql/data | Database persistence |
| repo_data | /data/repos | Git repositories |
| avatar_uploads | /app/uploads | User avatars |
## Docker Compose Files
### docker-compose.yml (Development)
Standard development setup with:
- Hot reload for API
- Vite dev server for frontend
- Direct port access
- Local PostgreSQL
### docker-compose.traefik.yml (Production)
Production setup with:
- Traefik reverse proxy
- Let's Encrypt SSL
- External Traefik network
- Optimized builds
## SSL/TLS
### Development
Self-signed certificates or HTTP only.
### Production
Automatic Let's Encrypt certificates via Traefik.
```bash
# Traefik labels for SSL
traefik.http.routers.api.tls=true
traefik.http.routers.api.tls.certresolver=letsencrypt
```
## Health Checks
All services include health checks:
```yaml
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
```
## Backup and Restore
### Database Backup
```bash
# Automated daily backup
docker compose exec postgres pg_dump -U headquarter headquarter > backup.sql
# Restore
docker compose exec -T postgres psql -U headquarter < backup.sql
```
### Repository Backup
```bash
# Backup repos volume
docker run --rm -v headquarter_repo_data:/data -v $(pwd):/backup alpine tar czf /backup/repos.tar.gz /data
# Restore
docker run --rm -v headquarter_repo_data:/data -v $(pwd):/backup alpine tar xzf /backup/repos.tar.gz -C /
```
## Monitoring
### Logs
```bash
# All services
docker compose logs -f
# Specific service
docker compose logs -f api
# Last 100 lines
docker compose logs --tail=100 api
```
### Resource Usage
```bash
# Container stats
docker stats
# Disk usage
docker system df -v
```
## Troubleshooting
### Common Issues
**Database connection failed**
```bash
# Check PostgreSQL is running
docker compose ps
# Check logs
docker compose logs postgres
# Verify credentials in .env match
```
**Migrations failing**
```bash
# Check current migration version
docker compose exec api alembic current
# Manual upgrade
docker compose exec api alembic upgrade head
```
**Permission denied on repos**
```bash
# Fix permissions
docker compose exec api chown -R appuser:appuser /data/repos
```
## Updates
### Rolling Update
```bash
# Pull latest images
docker compose pull
# Restart with new images
docker compose up -d
# Run migrations if needed
docker compose exec api alembic upgrade head
```
### Zero-Downtime Update
```bash
# Scale API to 2 instances
docker compose up -d --scale api=2
# Update one instance at a time
# (Requires load balancer configuration)
```
## Security Best Practices
1. **Use strong passwords** for database and session secret
2. **Enable HTTPS** in production
3. **Keep images updated** with security patches
4. **Use read-only volumes** where possible
5. **Limit container capabilities**
6. **Use secrets management** for sensitive data
```yaml
# Example security hardening
api:
read_only: true
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
cap_add:
- CHOWN
- SETGID
- SETUID
```
## Resources
- [Docker Documentation](https://docs.docker.com/)
- [Docker Compose Reference](https://docs.docker.com/compose/)
- [Traefik Documentation](https://doc.traefik.io/traefik/)
+268
View File
@@ -0,0 +1,268 @@
# Environment Variables Reference
## Overview
This document describes all environment variables used by Headquarter. Variables are categorized by component and purpose.
## Required Variables
These variables must be set for the application to function:
### Domains
| Variable | Default | Description |
|----------|---------|-------------|
| `API_DOMAIN` | `localhost` | API server domain (e.g., `api.example.com`) |
| `WEB_DOMAIN` | `localhost` | Web frontend domain (e.g., `app.example.com`) |
### Database
| Variable | Default | Description |
|----------|---------|-------------|
| `POSTGRES_USER` | `headquarter` | PostgreSQL username |
| `POSTGRES_PASSWORD` | `headquarter` | PostgreSQL password (change in production!) |
| `POSTGRES_DB` | `headquarter` | PostgreSQL database name |
### Authentication
| Variable | Default | Description |
|----------|---------|-------------|
| `AUTHENTIK_DOMAIN` | `authentik.local` | Authentik server domain |
| `AUTHENTIK_CLIENT_ID` | `headquarter-web` | OAuth client ID from Authentik |
| `AUTHENTIK_CLIENT_SECRET` | `change-me` | OAuth client secret (change immediately!) |
| `AUTHENTIK_APPLICATION_SLUG` | `headquarter-web` | Authentik application slug |
| `SESSION_SECRET` | `change-me-session-secret` | Secret for signing session cookies (min 32 chars) |
## Optional Variables
### Application
| Variable | Default | Description |
|----------|---------|-------------|
| `APP_ENV` | `development` | Environment: `development`, `staging`, `production` |
| `LOG_LEVEL` | `INFO` | Logging level: `DEBUG`, `INFO`, `WARNING`, `ERROR` |
### Database
| Variable | Default | Description |
|----------|---------|-------------|
| `DATABASE_URL` | (constructed) | Full PostgreSQL connection URL |
| `POSTGRES_HOST` | `postgres` | PostgreSQL hostname |
| `POSTGRES_PORT` | `5432` | PostgreSQL port |
When `DATABASE_URL` is not set, it's constructed from:
```
postgresql+asyncpg://POSTGRES_USER:POSTGRES_PASSWORD@POSTGRES_HOST:POSTGRES_PORT/POSTGRES_DB
```
### URLs
| Variable | Default | Description |
|----------|---------|-------------|
| `API_PUBLIC_URL` | (constructed) | Public API URL (e.g., `https://api.example.com`) |
| `WEB_PUBLIC_URL` | (constructed) | Public web URL (e.g., `https://app.example.com`) |
Constructed from domains when not set:
```
API: https://API_DOMAIN (production) or http://API_DOMAIN:8000 (development)
WEB: https://WEB_DOMAIN (production) or http://WEB_DOMAIN:5173 (development)
```
### Authentik Overrides
| Variable | Default | Description |
|----------|---------|-------------|
| `AUTHENTIK_AUTHORIZE_URL` | (constructed) | OAuth authorization endpoint |
| `AUTHENTIK_TOKEN_URL` | (constructed) | OAuth token endpoint |
| `AUTHENTIK_JWKS_URL` | (constructed) | JWKS endpoint |
| `AUTHENTIK_ISSUER` | (constructed) | OAuth issuer URL |
| `AUTHENTIK_AUDIENCE` | `headquarter-web` | Token audience |
Constructed URLs:
```
https://AUTHENTIK_DOMAIN/application/o/authorize/
https://AUTHENTIK_DOMAIN/application/o/token/
https://AUTHENTIK_DOMAIN/application/o/AUTHENTIK_APPLICATION_SLUG/jwks/
https://AUTHENTIK_DOMAIN/application/o/AUTHENTIK_APPLICATION_SLUG/
```
### Session
| Variable | Default | Description |
|----------|---------|-------------|
| `SESSION_TTL_HOURS` | `24` | Session cookie lifetime in hours |
| `COOKIE_DOMAIN` | (none) | Cookie domain (set for cross-subdomain) |
| `COOKIE_SECURE` | `true` (prod) | Secure cookie flag |
| `COOKIE_SAMESITE` | `lax` | SameSite cookie attribute |
### Storage
| Variable | Default | Description |
|----------|---------|-------------|
| `REPO_BASE_PATH` | `/data/repos` | Base path for git repositories |
| `UPLOAD_DIR` | `uploads` | Directory for file uploads |
### Development
| Variable | Default | Description |
|----------|---------|-------------|
| `VITE_API_BASE_URL` | `http://localhost:8000` | Frontend API URL |
## Docker Compose Variables
### Traefik
| Variable | Default | Description |
|----------|---------|-------------|
| `TRAEFIK_NETWORK` | `traefik` | Docker network name for Traefik |
| `TRAEFIK_CERT_RESOLVER` | `letsencrypt` | Certificate resolver name |
### Docker Specific
| Variable | Default | Description |
|----------|---------|-------------|
| `COMPOSE_PROJECT_NAME` | `headquarter` | Docker Compose project name |
## Configuration Examples
### Development
```bash
APP_ENV=development
API_DOMAIN=localhost
WEB_DOMAIN=localhost
DATABASE_URL=postgresql+asyncpg://headquarter:headquarter@localhost:5432/headquarter
AUTHENTIK_DOMAIN=authentik.local
AUTHENTIK_CLIENT_ID=headquarter-web
AUTHENTIK_CLIENT_SECRET=dev-secret
SESSION_SECRET=dev-session-secret-change-in-production
VITE_API_BASE_URL=http://localhost:8000
```
### Production
```bash
APP_ENV=production
API_DOMAIN=api.headquarter.example.com
WEB_DOMAIN=app.headquarter.example.com
POSTGRES_PASSWORD=very-secure-password-here
AUTHENTIK_DOMAIN=auth.example.com
AUTHENTIK_CLIENT_ID=your-uuid-from-authentik
AUTHENTIK_CLIENT_SECRET=your-secret-from-authentik
AUTHENTIK_APPLICATION_SLUG=headquarter-web
SESSION_SECRET=minimum-32-characters-long-secret-key
SESSION_TTL_HOURS=24
COOKIE_DOMAIN=.headquarter.example.com
TRAEFIK_NETWORK=web
TRAEFIK_CERT_RESOLVER=letsencrypt
REPO_BASE_PATH=/data/repos
```
### Testing
```bash
APP_ENV=testing
DATABASE_URL=postgresql+asyncpg://headquarter:headquarter@localhost:5432/headquarter_test
SESSION_SECRET=test-secret
AUTHENTIK_CLIENT_ID=test-client
AUTHENTIK_CLIENT_SECRET=test-secret
```
## Security Checklist
Before deploying to production, verify:
- [ ] `POSTGRES_PASSWORD` is strong and unique
- [ ] `AUTHENTIK_CLIENT_SECRET` is kept secret
- [ ] `SESSION_SECRET` is at least 32 characters
- [ ] `APP_ENV` is set to `production`
- [ ] `COOKIE_SECURE` is enabled
- [ ] `COOKIE_DOMAIN` is set for your domain
- [ ] No default secrets in production
- [ ] `.env` file is not committed to git
- [ ] `.env` file has restricted permissions (600)
## Troubleshooting
### Variable Not Set
```bash
# Error: "Environment variable not set"
# Solution: Export the variable or add to .env file
export SESSION_SECRET="your-secret-here"
```
### Invalid URL
```bash
# Error: "Invalid URL"
# Solution: Check domain variables don't include protocol
# Bad: API_DOMAIN=https://api.example.com
# Good: API_DOMAIN=api.example.com
```
### Database Connection Failed
```bash
# Check DATABASE_URL or individual components
# Verify PostgreSQL is running
# Check credentials match
```
## Migration from Old Config
If upgrading from older versions:
1. `JWT_SECRET` → Removed (not needed with session auth)
2. `ACCESS_TOKEN_TTL_MINUTES` → Removed
3. `REFRESH_TOKEN_TTL_DAYS` → Removed
4. `AUTHENTIK_AUDIENCE` → Now defaults to `AUTHENTIK_CLIENT_ID`
5. `AUTHENTIK_APPLICATION_SLUG` → New variable for URL construction
## Environment Files
### Files Structure
```
headquarter/
├── .env # Main environment (not committed)
├── .env.example # Example/template
├── apps/
│ ├── api/
│ │ └── .env # API-specific overrides
│ └── web/
│ └── .env # Frontend-specific overrides
└── docker-compose.traefik.yml # References .env
```
### Loading Order
1. System environment variables
2. `.env` file in project root
3. Component-specific `.env` files
4. Default values in code
Later values override earlier ones.
## Validation
The application validates required variables on startup:
```python
# Missing critical variable
if not settings.session_secret or settings.session_secret == "change-me":
logger.warning("SESSION_SECRET not configured properly!")
# Invalid configuration
if settings.app_env == "production" and "localhost" in settings.api_domain:
logger.warning("Using localhost in production!")
```
## Best Practices
1. **Never commit `.env` files**
2. **Use strong passwords** for database and secrets
3. **Rotate secrets** regularly
4. **Use different secrets** per environment
5. **Document custom variables** in this file
6. **Validate configuration** before deployment
+305
View File
@@ -0,0 +1,305 @@
# 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 IP
- `app.yourdomain.com` → Server IP
- Ports 80 and 443 open in firewall
## Configuration
### 1. Environment Variables
```bash
# .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:
```yaml
# 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:
```yaml
networks:
traefik:
external: true
name: ${TRAEFIK_NETWORK:-traefik}
```
## Deployment Steps
### Step 1: Verify DNS
Ensure DNS records resolve to your server:
```bash
nslookup api.headquarter.example.com
nslookup app.headquarter.example.com
```
### Step 2: Start Services
```bash
# 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
```bash
# 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
```bash
docker compose -f docker-compose.traefik.yml exec api alembic upgrade head
```
## SSL Configuration
### Let's Encrypt (Default)
Automatic certificate generation and renewal:
```yaml
labels:
- "traefik.http.routers.headquarter-api.tls.certresolver=letsencrypt"
```
### Custom Certificates
For custom or wildcard certificates:
```yaml
labels:
- "traefik.http.routers.headquarter-api.tls=true"
- "traefik.http.routers.headquarter-api.tls.certresolver=myresolver"
```
### Self-Signed (Development)
```yaml
labels:
- "traefik.http.routers.headquarter-api.tls=true"
- "traefik.http.routers.headquarter-api.tls.certresolver=selfsigned"
```
## Advanced Configuration
### Rate Limiting
```yaml
labels:
- "traefik.http.middlewares.ratelimit.ratelimit.average=100"
- "traefik.http.routers.headquarter-api.middlewares=ratelimit"
```
### Basic Auth (for staging)
```yaml
labels:
- "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/"
- "traefik.http.routers.headquarter-api.middlewares=auth"
```
### CORS Headers
```yaml
labels:
- "traefik.http.middlewares.cors.headers.accesscontrolalloworiginlist=*"
- "traefik.http.routers.headquarter-api.middlewares=cors"
```
## Troubleshooting
### Certificate Issues
**Problem**: Certificate not generated
```bash
# 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
```bash
# Force renewal
docker compose restart traefik
# Or delete acme.json and restart
rm acme.json
docker compose restart traefik
```
### Routing Issues
**Problem**: 404 errors
```bash
# 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
```bash
# 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
```bash
# 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):
```yaml
# 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
1. **Always use HTTPS** in production (redirect HTTP to HTTPS)
2. **Secure Traefik dashboard** with authentication
3. **Use strong certificate resolver** (Let's Encrypt production)
4. **Keep Traefik updated** for security patches
5. **Restrict Docker socket access** if using Docker provider
## Example Complete Configuration
```yaml
# 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
```
## Resources
- [Traefik Documentation](https://doc.traefik.io/traefik/)
- [Docker Compose Integration](https://doc.traefik.io/traefik/providers/docker/)
- [Let's Encrypt Configuration](https://doc.traefik.io/traefik/https/acme/)