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:
@@ -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/)
|
||||
Reference in New Issue
Block a user