caddy example
This commit is contained in:
@@ -52,9 +52,12 @@ docker-compose*.yml
|
|||||||
# Documentation
|
# Documentation
|
||||||
README.md
|
README.md
|
||||||
CLAUDE.md
|
CLAUDE.md
|
||||||
|
DEPLOY.md
|
||||||
|
README.production.md
|
||||||
|
|
||||||
# Nginx config
|
# Reverse proxy configs
|
||||||
nginx.conf.example
|
nginx.conf.example
|
||||||
|
Caddyfile.example
|
||||||
|
|
||||||
# Frontend build output (not needed during image build)
|
# Frontend build output (not needed during image build)
|
||||||
frontend/frontend/dist
|
frontend/frontend/dist
|
||||||
|
|||||||
@@ -153,6 +153,12 @@ docker compose -f docker-compose.production.yml exec backend uv run flask db upg
|
|||||||
- Set `SESSION_COOKIE_SECURE=true` for HTTPS
|
- Set `SESSION_COOKIE_SECURE=true` for HTTPS
|
||||||
- Configure OIDC URLs to match your domain
|
- Configure OIDC URLs to match your domain
|
||||||
|
|
||||||
|
**Reverse Proxy:**
|
||||||
|
- Example configurations provided: `nginx.conf.example` and `Caddyfile.example`
|
||||||
|
- Caddy recommended for automatic HTTPS with Let's Encrypt
|
||||||
|
- Nginx for more control and advanced configurations
|
||||||
|
- See `README.production.md` for detailed setup instructions
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
### Application Factory Pattern
|
### Application Factory Pattern
|
||||||
|
|||||||
98
Caddyfile.example
Normal file
98
Caddyfile.example
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
# Example Caddyfile for production deployment
|
||||||
|
# Caddy automatically handles HTTPS with Let's Encrypt!
|
||||||
|
|
||||||
|
# Basic configuration - Caddy handles SSL automatically
|
||||||
|
trivia.torrtle.co {
|
||||||
|
# Reverse proxy to Flask app
|
||||||
|
reverse_proxy localhost:5001
|
||||||
|
|
||||||
|
# Increase client upload size for images (default is 10MB)
|
||||||
|
request_body {
|
||||||
|
max_size 10MB
|
||||||
|
}
|
||||||
|
|
||||||
|
# Enable compression
|
||||||
|
encode gzip zstd
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
log {
|
||||||
|
output file /var/log/caddy/trivia.log
|
||||||
|
format json
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Alternative: More explicit configuration with WebSocket support
|
||||||
|
# (Though Caddy handles WebSocket upgrades automatically)
|
||||||
|
trivia.torrtle.co {
|
||||||
|
# Main reverse proxy
|
||||||
|
reverse_proxy localhost:5001 {
|
||||||
|
# Forward real client IP
|
||||||
|
header_up X-Real-IP {remote_host}
|
||||||
|
header_up X-Forwarded-For {remote_host}
|
||||||
|
header_up X-Forwarded-Proto {scheme}
|
||||||
|
header_up X-Forwarded-Host {host}
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
health_uri /api/health
|
||||||
|
health_interval 30s
|
||||||
|
health_timeout 5s
|
||||||
|
}
|
||||||
|
|
||||||
|
# Upload size
|
||||||
|
request_body {
|
||||||
|
max_size 10MB
|
||||||
|
}
|
||||||
|
|
||||||
|
# Compression
|
||||||
|
encode gzip zstd
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
header {
|
||||||
|
# Enable HSTS
|
||||||
|
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
||||||
|
|
||||||
|
# Prevent clickjacking
|
||||||
|
X-Frame-Options "SAMEORIGIN"
|
||||||
|
|
||||||
|
# XSS protection
|
||||||
|
X-Content-Type-Options "nosniff"
|
||||||
|
|
||||||
|
# Referrer policy
|
||||||
|
Referrer-Policy "strict-origin-when-cross-origin"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
log {
|
||||||
|
output file /var/log/caddy/trivia.log {
|
||||||
|
roll_size 100mb
|
||||||
|
roll_keep 5
|
||||||
|
roll_keep_for 720h
|
||||||
|
}
|
||||||
|
format json
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Optional: Expose Celery Flower monitoring on subdomain
|
||||||
|
flower.torrtle.co {
|
||||||
|
reverse_proxy localhost:5555
|
||||||
|
|
||||||
|
# Optional: Basic auth for protection
|
||||||
|
basicauth {
|
||||||
|
admin $2a$14$Zkx19XLiW6VYouLHR5NmfOFU0z2GTNmpkT/5qqR4M5.laVvNFqEAa
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Optional: Redirect www to non-www
|
||||||
|
www.trivia.torrtle.co {
|
||||||
|
redir https://trivia.torrtle.co{uri} permanent
|
||||||
|
}
|
||||||
|
|
||||||
|
# Optional: Development/staging environment on different subdomain
|
||||||
|
staging.trivia.torrtle.co {
|
||||||
|
reverse_proxy localhost:5002
|
||||||
|
|
||||||
|
# Basic auth to protect staging
|
||||||
|
basicauth {
|
||||||
|
staging $2a$14$Zkx19XLiW6VYouLHR5NmfOFU0z2GTNmpkT/5qqR4M5.laVvNFqEAa
|
||||||
|
}
|
||||||
|
}
|
||||||
125
DEPLOY.md
Normal file
125
DEPLOY.md
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
# Quick Deploy Guide
|
||||||
|
|
||||||
|
Minimal steps to deploy the trivia app to production with Caddy.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Linux server with Docker and Docker Compose installed
|
||||||
|
- Domain name pointing to your server (e.g., `trivia.torrtle.co` → your server IP)
|
||||||
|
- Port 80 and 443 open in firewall
|
||||||
|
|
||||||
|
## 5-Minute Deploy
|
||||||
|
|
||||||
|
### 1. Clone and Configure
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone repository
|
||||||
|
git clone <your-repo-url>
|
||||||
|
cd trivia-thang
|
||||||
|
|
||||||
|
# Configure environment
|
||||||
|
cp .env.production.example .env.production
|
||||||
|
nano .env.production # Update with your values
|
||||||
|
```
|
||||||
|
|
||||||
|
**Required settings in `.env.production`:**
|
||||||
|
```bash
|
||||||
|
CORS_ORIGINS=https://trivia.torrtle.co
|
||||||
|
OIDC_ISSUER=https://auth.torrtle.co
|
||||||
|
OIDC_CLIENT_SECRET=your_secret_here
|
||||||
|
OIDC_REDIRECT_URI=https://trivia.torrtle.co/api/auth/callback
|
||||||
|
FRONTEND_URL=https://trivia.torrtle.co
|
||||||
|
SESSION_COOKIE_SECURE=true
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Start Application
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build and start
|
||||||
|
docker compose -f docker-compose.production.yml up -d
|
||||||
|
|
||||||
|
# Initialize database
|
||||||
|
docker compose -f docker-compose.production.yml exec backend uv run flask db upgrade
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Setup Caddy (Automatic HTTPS)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install Caddy
|
||||||
|
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
|
||||||
|
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
|
||||||
|
sudo apt update && sudo apt install caddy
|
||||||
|
|
||||||
|
# Create minimal Caddyfile
|
||||||
|
sudo tee /etc/caddy/Caddyfile << 'EOF'
|
||||||
|
trivia.torrtle.co {
|
||||||
|
reverse_proxy localhost:5001
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Start Caddy
|
||||||
|
sudo systemctl restart caddy
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Done!
|
||||||
|
|
||||||
|
Visit `https://trivia.torrtle.co` - Caddy automatically handles HTTPS!
|
||||||
|
|
||||||
|
## Verify Deployment
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check if app is running
|
||||||
|
curl http://localhost:5001/api/health
|
||||||
|
|
||||||
|
# Check Docker containers
|
||||||
|
docker compose -f docker-compose.production.yml ps
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
docker compose -f docker-compose.production.yml logs -f backend
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Restart application
|
||||||
|
docker compose -f docker-compose.production.yml restart
|
||||||
|
|
||||||
|
# Update application
|
||||||
|
git pull
|
||||||
|
docker compose -f docker-compose.production.yml up -d --build
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
docker compose -f docker-compose.production.yml logs -f
|
||||||
|
|
||||||
|
# Stop application
|
||||||
|
docker compose -f docker-compose.production.yml down
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Can't connect to HTTPS
|
||||||
|
|
||||||
|
Check Caddy logs:
|
||||||
|
```bash
|
||||||
|
sudo journalctl -u caddy -f
|
||||||
|
```
|
||||||
|
|
||||||
|
Caddy needs ports 80 and 443 open for Let's Encrypt challenge.
|
||||||
|
|
||||||
|
### WebSocket issues
|
||||||
|
|
||||||
|
Ensure your domain's DNS is properly configured and Caddy is running. Caddy handles WebSocket upgrades automatically.
|
||||||
|
|
||||||
|
### Database errors
|
||||||
|
|
||||||
|
Run migrations:
|
||||||
|
```bash
|
||||||
|
docker compose -f docker-compose.production.yml exec backend uv run flask db upgrade
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
For detailed documentation, see:
|
||||||
|
- `README.production.md` - Full deployment guide
|
||||||
|
- `Caddyfile.example` - Advanced Caddy configuration
|
||||||
|
- `nginx.conf.example` - Alternative Nginx configuration
|
||||||
@@ -67,17 +67,49 @@ sudo nginx -t
|
|||||||
sudo systemctl reload nginx
|
sudo systemctl reload nginx
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Option B: Caddy (Simpler)
|
#### Option B: Caddy (Recommended - Automatic HTTPS!)
|
||||||
|
|
||||||
Create `/etc/caddy/Caddyfile`:
|
Caddy is simpler than Nginx and handles HTTPS automatically with Let's Encrypt.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install Caddy (if not already installed)
|
||||||
|
# Ubuntu/Debian:
|
||||||
|
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
|
||||||
|
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
|
||||||
|
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install caddy
|
||||||
|
|
||||||
|
# Copy and edit the example Caddyfile
|
||||||
|
sudo cp Caddyfile.example /etc/caddy/Caddyfile
|
||||||
|
|
||||||
|
# Update your domain in the Caddyfile
|
||||||
|
sudo nano /etc/caddy/Caddyfile
|
||||||
|
|
||||||
|
# Validate configuration
|
||||||
|
caddy validate --config /etc/caddy/Caddyfile
|
||||||
|
|
||||||
|
# Restart Caddy
|
||||||
|
sudo systemctl restart caddy
|
||||||
|
|
||||||
|
# Check status
|
||||||
|
sudo systemctl status caddy
|
||||||
|
```
|
||||||
|
|
||||||
|
**Simple Caddyfile (minimal):**
|
||||||
```caddy
|
```caddy
|
||||||
trivia.torrtle.co {
|
trivia.torrtle.co {
|
||||||
reverse_proxy localhost:5001
|
reverse_proxy localhost:5001
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Caddy automatically handles HTTPS with Let's Encrypt!
|
**That's it!** Caddy automatically:
|
||||||
|
- Obtains SSL certificate from Let's Encrypt
|
||||||
|
- Handles WebSocket upgrades
|
||||||
|
- Redirects HTTP to HTTPS
|
||||||
|
- Renews certificates automatically
|
||||||
|
|
||||||
|
See `Caddyfile.example` for advanced configuration with security headers, logging, and optional features.
|
||||||
|
|
||||||
## Services
|
## Services
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user