feat: Add CI/CD setup guide with Gitea Actions for trading analysis application

feat: Implement multi-user support with separate brokerage accounts and user authentication

feat: Configure SSO authentication setup using Google OAuth 2.0 for secure access

refactor: Update index page to reflect new Trading Analysis Dashboard features and descriptions

docs: Enhance quickstart guide for deploying Trading Analysis Dashboard with detailed steps

chore: Add runner configuration for Gitea Actions with logging and container settings
This commit is contained in:
Peter Wood
2025-11-14 12:43:09 -05:00
parent 2f5e59b40f
commit c6eb26037b
24 changed files with 3594 additions and 169 deletions

393
guides/deployment/caddy.mdx Normal file
View File

@@ -0,0 +1,393 @@
---
title: 'Caddy Configuration'
description: 'Configure Caddy reverse proxy for different deployment scenarios'
---
## Overview
Caddy is a powerful web server that automatically handles HTTPS with Let's Encrypt. This guide explains how to configure Caddy for different deployment scenarios.
## Local Development
The default `Caddyfile` is configured for local development:
```caddy Caddyfile
localhost {
reverse_proxy trading_app:5000
encode gzip
header {
X-Content-Type-Options nosniff
X-Frame-Options DENY
X-XSS-Protection "1; mode=block"
Referrer-Policy "strict-origin-when-cross-origin"
-Server
}
}
```
<Info>
Access your app at: `http://localhost`
</Info>
## Production Deployment
### Step 1: Domain Setup
<Steps>
<Step title="Configure DNS">
Point your domain's DNS A record to your server's IP
</Step>
<Step title="Copy Production Template">
```bash
cp Caddyfile.production Caddyfile
```
</Step>
<Step title="Edit Caddyfile">
Replace `your-domain.com` with your actual domain
</Step>
</Steps>
### Step 2: Environment Configuration
Update your `.env` file:
```env .env
DOMAIN=your-domain.com
FLASK_ENV=production
```
### Step 3: Deploy
```bash
docker-compose up -d
```
<Check>
Caddy will automatically:
- Obtain SSL certificates from Let's Encrypt
- Handle HTTP to HTTPS redirects
- Renew certificates automatically
</Check>
## Configuration Options
### Basic Reverse Proxy
```caddy
your-domain.com {
reverse_proxy trading_app:5000
}
```
### With Compression and Security Headers
```caddy
your-domain.com {
reverse_proxy trading_app:5000
encode gzip
header {
X-Content-Type-Options nosniff
X-Frame-Options DENY
Strict-Transport-Security "max-age=31536000"
}
}
```
### Static File Caching
```caddy
your-domain.com {
reverse_proxy trading_app:5000
@static path /static/*
handle @static {
header Cache-Control "public, max-age=3600"
reverse_proxy trading_app:5000
}
}
```
### Rate Limiting
```caddy
your-domain.com {
rate_limit {
zone general 10r/s
}
reverse_proxy trading_app:5000
}
```
### Basic Authentication
```caddy
admin.your-domain.com {
basicauth {
admin $2a$14$hashed_password_here
}
reverse_proxy trading_app:5000
}
```
## SSL/TLS Configuration
### Automatic HTTPS (Default)
Caddy automatically obtains certificates from Let's Encrypt:
```caddy
your-domain.com {
reverse_proxy trading_app:5000
}
```
<Note>
No additional configuration needed! Caddy handles everything automatically.
</Note>
### Custom Certificates
```caddy
your-domain.com {
tls /path/to/cert.pem /path/to/key.pem
reverse_proxy trading_app:5000
}
```
### Internal/Self-Signed Certificates
```caddy
your-domain.com {
tls internal
reverse_proxy trading_app:5000
}
```
## Monitoring and Logging
### Access Logs
```caddy
your-domain.com {
reverse_proxy trading_app:5000
log {
output file /var/log/caddy/access.log
format json
}
}
```
### Error Handling
```caddy
your-domain.com {
reverse_proxy trading_app:5000
handle_errors {
@404 expression {http.error.status_code} == 404
handle @404 {
rewrite * /404.html
reverse_proxy trading_app:5000
}
}
}
```
## Advanced Features
### Multiple Domains
```caddy
site1.com, site2.com {
reverse_proxy trading_app:5000
}
```
### Subdomain Routing
```caddy
api.your-domain.com {
reverse_proxy trading_app:5000/api
}
app.your-domain.com {
reverse_proxy trading_app:5000
}
```
### Load Balancing
```caddy
your-domain.com {
reverse_proxy trading_app1:5000 trading_app2:5000 {
lb_policy round_robin
health_path /health
}
}
```
## Troubleshooting
### Check Caddy Status
```bash
docker-compose logs caddy
```
### Certificate Issues
```bash
# Check certificate status
docker-compose exec caddy caddy list-certificates
# Force certificate renewal
docker-compose exec caddy caddy reload --config /etc/caddy/Caddyfile
```
### Configuration Validation
```bash
# Validate Caddyfile syntax
docker-compose exec caddy caddy validate --config /etc/caddy/Caddyfile
```
### Common Issues
<AccordionGroup>
<Accordion title="Port 80/443 already in use">
```bash
# Check what's using the ports
netstat -tlnp | grep :80
netstat -tlnp | grep :443
```
Stop the conflicting service or change Caddy's ports in docker-compose.yml
</Accordion>
<Accordion title="DNS not pointing to server">
```bash
# Check DNS resolution
nslookup your-domain.com
```
Verify your domain's A record points to the correct IP address
</Accordion>
<Accordion title="Let's Encrypt rate limits">
Use staging environment for testing:
```caddy
your-domain.com {
tls {
ca https://acme-staging-v02.api.letsencrypt.org/directory
}
reverse_proxy trading_app:5000
}
```
</Accordion>
<Accordion title="Certificate validation fails">
- Ensure port 80 is accessible from the internet
- Verify DNS is propagated: `dig your-domain.com`
- Check firewall rules allow incoming connections
- Review Caddy logs for specific errors
</Accordion>
</AccordionGroup>
## Performance Tuning
### Enable HTTP/2 and HTTP/3
```caddy
your-domain.com {
protocols h1 h2 h3
reverse_proxy trading_app:5000
}
```
### Connection Limits
```caddy
your-domain.com {
reverse_proxy trading_app:5000 {
transport http {
max_conns_per_host 100
}
}
}
```
### Timeout Configuration
```caddy
your-domain.com {
reverse_proxy trading_app:5000 {
transport http {
read_timeout 30s
write_timeout 30s
}
}
}
```
## Security Best Practices
<CardGroup cols={2}>
<Card title="Strong TLS" icon="lock">
Use TLS 1.2+ with strong cipher suites (Caddy's default)
</Card>
<Card title="Security Headers" icon="shield-halved">
Add security headers like CSP, HSTS, X-Frame-Options
</Card>
<Card title="Rate Limiting" icon="gauge-high">
Implement rate limiting to prevent abuse
</Card>
<Card title="Access Control" icon="user-shield">
Use basic auth or OAuth for sensitive routes
</Card>
</CardGroup>
### Recommended Security Configuration
```caddy
your-domain.com {
reverse_proxy trading_app:5000
encode gzip
header {
# Security headers
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
X-XSS-Protection "1; mode=block"
Referrer-Policy "strict-origin-when-cross-origin"
Permissions-Policy "geolocation=(), microphone=(), camera=()"
# Hide server info
-Server
-X-Powered-By
}
}
```
## Additional Resources
<CardGroup cols={2}>
<Card title="Caddy Documentation" icon="book" href="https://caddyserver.com/docs/">
Official Caddy documentation
</Card>
<Card title="Caddyfile Syntax" icon="code" href="https://caddyserver.com/docs/caddyfile">
Learn Caddyfile syntax
</Card>
<Card title="Automatic HTTPS" icon="certificate" href="https://caddyserver.com/docs/automatic-https">
How Caddy handles HTTPS automatically
</Card>
<Card title="Docker Deployment" icon="docker" href="/guides/deployment/docker">
Back to Docker deployment guide
</Card>
</CardGroup>

View File

@@ -0,0 +1,426 @@
---
title: 'Docker Deployment'
description: 'Deploy the Trading Analysis Dashboard using Docker containers'
---
## Quick Start
<Steps>
<Step title="Install Prerequisites">
Install [Docker Desktop](https://www.docker.com/products/docker-desktop/) (includes Docker Compose)
</Step>
<Step title="Run Deployment Script">
<Tabs>
<Tab title="Windows">
```batch
deploy.bat
```
</Tab>
<Tab title="Linux/macOS">
```bash
chmod +x deploy.sh
./deploy.sh
```
</Tab>
</Tabs>
</Step>
<Step title="Manual Deployment (Alternative)">
```bash
# Copy environment file
cp .env.docker .env
# Build and start services
docker compose up -d
# Check status
docker compose ps
```
</Step>
</Steps>
## Services Overview
The deployment includes these services:
| Service | Port | Description |
|---------|------|-------------|
| **trading_app** | 8080 | Main Flask application |
| **postgres** | 5432 | PostgreSQL database |
| **caddy** | 80, 443 | Reverse proxy with automatic HTTPS |
## Access URLs
<CardGroup cols={2}>
<Card title="Production" icon="globe">
https://performance.miningwood.com
</Card>
<Card title="Main Application" icon="laptop">
http://localhost:8080
</Card>
<Card title="Via Caddy" icon="server">
http://localhost
</Card>
<Card title="Database" icon="database">
localhost:5432
</Card>
</CardGroup>
## Docker Compose Configuration
The complete `docker-compose.yml` file for the application:
```yaml docker-compose.yml
services:
server:
image: docker.gitea.com/gitea:latest
container_name: gitea
environment:
- USER_UID=${USER_UID}
- USER_GID=${USER_GID}
- GITEA__database__DB_TYPE=postgres
- GITEA__database__HOST=db:5432
- GITEA__database__NAME=${POSTGRES_USER}
- GITEA__database__USER=${POSTGRES_USER}
- GITEA__database__PASSWD=${POSTGRES_PASSWORD}
restart: always
networks:
- gitea
volumes:
- gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- ${GITEA_HTTP_PORT:-3500}:3000
- ${GITEA_SSH_PORT:-2229}:22
depends_on:
- db
labels:
- diun.enable=true
healthcheck:
test:
- CMD
- curl
- -f
- http://localhost
interval: 10s
retries: 3
start_period: 30s
timeout: 10s
db:
image: docker.io/library/postgres:14
restart: always
environment:
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB}
networks:
- gitea
volumes:
- postgres:/var/lib/postgresql/data
runner:
image: gitea/act_runner:latest
container_name: gitea-runner
restart: always
networks:
- gitea
volumes:
- runner:/data
- /var/run/docker.sock:/var/run/docker.sock
- ./runner-config.yaml:/data/config.yaml:ro
environment:
- GITEA_INSTANCE_URL=http://server:3000
- GITEA_RUNNER_REGISTRATION_TOKEN=${GITEA_RUNNER_REGISTRATION_TOKEN}
- GITEA_RUNNER_NAME=docker-runner
- CONFIG_FILE=/data/config.yaml
command: >
sh -c "
if [ ! -f /data/.runner ]; then
act_runner register --no-interactive --instance http://server:3000 --token $${GITEA_RUNNER_REGISTRATION_TOKEN} --name docker-runner;
fi;
act_runner --config /data/config.yaml daemon
"
depends_on:
- server
labels:
- diun.enable=true
networks:
gitea:
external: false
volumes:
gitea:
postgres:
runner:
```
## Configuration
### Environment Variables
Edit the `.env` file to customize your deployment:
```env .env
# Database Configuration
DB_HOST=postgres
DB_PORT=5432
DB_NAME=mining_wood
DB_USER=trading_user
DB_PASSWORD=your_secure_password
# Flask Configuration
FLASK_SECRET_KEY=your-super-secret-key-change-this
FLASK_ENV=production
# Gitea Configuration
USER_UID=1000
USER_GID=1000
POSTGRES_USER=gitea
POSTGRES_PASSWORD=gitea_password
POSTGRES_DB=gitea
GITEA_HTTP_PORT=3500
GITEA_SSH_PORT=2229
GITEA_RUNNER_REGISTRATION_TOKEN=your_token_here
```
<Warning>
Always change default passwords before deploying to production!
</Warning>
### SSL/HTTPS Setup with Caddy
Caddy provides automatic HTTPS with Let's Encrypt:
<Tabs>
<Tab title="Local Development">
No setup needed - uses HTTP by default
</Tab>
<Tab title="Production with Domain">
```bash
# Edit Caddyfile and replace localhost with your domain
cp Caddyfile.production Caddyfile
# Edit the domain in Caddyfile: your-domain.com
```
Caddy will automatically get and renew SSL certificates!
</Tab>
</Tabs>
## Database Setup
The PostgreSQL database is automatically initialized with:
- **Database**: `mining_wood`
- **Schema**: `trading_analysis`
- **User**: `trading_user`
### Import Your Trading Data
After deployment, import your trading data:
<Steps>
<Step title="Access the database">
```bash
docker compose exec postgres psql -U trading_user -d mining_wood
```
</Step>
<Step title="Import your data">
```bash
# Copy your CSV files to the container
docker cp your-data.csv trading_app:/app/data/
# Run your import script
docker compose exec trading_app python your_import_script.py
```
</Step>
</Steps>
## Management Commands
### View Logs
```bash
# All services
docker compose logs -f
# Specific service
docker compose logs -f trading_app
docker compose logs -f postgres
docker compose logs -f caddy
```
### Restart Services
```bash
# Restart all services
docker compose restart
# Restart specific service
docker compose restart trading_app
```
### Stop/Start
```bash
# Stop all services
docker compose down
# Start services
docker compose up -d
# Stop and remove volumes (⚠️ removes database data)
docker compose down -v
```
### Update Application
```bash
# Pull latest images and restart
docker compose pull
docker compose up -d
```
### Database Backup
```bash
# Backup database
docker compose exec postgres pg_dump -U trading_user mining_wood > backup.sql
# Restore database
docker compose exec -T postgres psql -U trading_user mining_wood < backup.sql
```
## Security Considerations
### For Production Deployment
<CardGroup cols={2}>
<Card title="Change Passwords" icon="key">
Update `POSTGRES_PASSWORD` and `FLASK_SECRET_KEY` in docker compose.yml/.env
</Card>
<Card title="Enable HTTPS" icon="lock">
Configure SSL certificates and enable HTTPS redirect
</Card>
<Card title="Firewall" icon="shield">
Only expose necessary ports (80, 443). Restrict database access (5432)
</Card>
<Card title="Regular Updates" icon="rotate">
Keep Docker images updated and monitor security advisories
</Card>
</CardGroup>
## Production Deployment
### Domain Setup
<Steps>
<Step title="DNS Configuration">
- Point your domain to your server's IP address
- For performance.miningwood.com: Create an A record pointing to your server IP
</Step>
<Step title="Automatic SSL">
```bash
# Caddy handles SSL automatically with Let's Encrypt
# The domain is already configured for performance.miningwood.com
# Just deploy and Caddy will handle the rest
docker compose up -d
```
</Step>
<Step title="Environment">
- Domain is already set to `performance.miningwood.com` in `.env.docker`
- Set `FLASK_ENV=production`
- Use strong passwords
</Step>
</Steps>
### Monitoring
Consider adding monitoring services:
```yaml docker-compose.yml
# Add to docker compose.yml
prometheus:
image: prom/prometheus
ports:
- "9090:9090"
grafana:
image: grafana/grafana
ports:
- "3000:3000"
```
## Troubleshooting
<AccordionGroup>
<Accordion title="Application Won't Start">
```bash
# Check logs
docker compose logs trading_app
# Common issues:
# - Database connection failure
# - Missing environment variables
# - Port conflicts
```
</Accordion>
<Accordion title="Database Connection Issues">
```bash
# Check database status
docker compose exec postgres pg_isready -U trading_user
# Reset database
docker compose down -v
docker compose up -d
```
</Accordion>
<Accordion title="Performance Issues">
```bash
# Check resource usage
docker stats
# Scale services
docker compose up -d --scale trading_app=2
```
</Accordion>
<Accordion title="SSL Certificate Issues">
- Ensure DNS is pointing to correct server
- Wait a few minutes for certificate provisioning
- Check Caddy logs: `docker compose logs caddy`
</Accordion>
</AccordionGroup>
## Development Mode
To run in development mode:
```bash
# Use development override
docker compose -f docker compose.yml -f docker compose.dev.yml up -d
```
This enables:
- Live code reloading
- Debug mode
- Development tools
## Next Steps
<CardGroup cols={2}>
<Card title="Caddy Configuration" icon="server" href="/guides/deployment/caddy">
Learn more about Caddy reverse proxy setup
</Card>
<Card title="CI/CD Setup" icon="rocket" href="/guides/setup/cicd">
Automate deployments with CI/CD
</Card>
</CardGroup>