gcp-hockey-results/DOCKER.md
2025-09-29 20:06:07 +08:00

363 lines
8.2 KiB
Markdown

# Docker Containerization Guide
This guide explains how to run the Hockey Results Application using Docker containers with support for multiple database backends.
## 🏒 Quick Start
### Using Docker Compose (Recommended)
```bash
# Start with PostgreSQL (default)
docker-compose up -d
# Start with MariaDB
docker-compose --profile mariadb up -d
# Start with SQLite (no database container needed)
DATABASE_TYPE=sqlite docker-compose up -d
```
### Using Docker Commands
```bash
# Build the image
./docker/build.sh
# Run with SQLite
./docker/run.sh
# Run with PostgreSQL
./docker/run.sh -d postgresql
# Run with MariaDB
./docker/run.sh -d mysql
```
## 🗄️ Database Options
### 1. SQLite (Default)
- **Pros**: No external dependencies, perfect for development
- **Cons**: Not suitable for production with multiple users
- **Use case**: Development, testing, single-user deployments
```bash
# Using docker-compose
DATABASE_TYPE=sqlite docker-compose up -d
# Using docker run
./docker/run.sh -d sqlite
```
### 2. PostgreSQL (Recommended for Production)
- **Pros**: Robust, ACID compliant, excellent performance
- **Cons**: Requires external database container
- **Use case**: Production deployments, multi-user applications
```bash
# Using docker-compose (default)
docker-compose up -d
# Using docker run (requires external PostgreSQL)
./docker/run.sh -d postgresql
```
### 3. MariaDB/MySQL
- **Pros**: Widely supported, good performance
- **Cons**: Requires external database container
- **Use case**: Legacy systems, specific MySQL requirements
```bash
# Using docker-compose
docker-compose --profile mariadb up -d
# Using docker run (requires external MariaDB)
./docker/run.sh -d mysql
```
## 🚀 Deployment Options
### Development Environment
```bash
# Clone the repository
git clone <repository-url>
cd gcp-hockey-results
# Start with SQLite for development
./docker/run.sh -d sqlite -p 5000:5000
# Access the application
open http://localhost:5000
```
### Production Environment
#### Option 1: Docker Compose (Single Server)
```bash
# Set production environment variables
export SECRET_KEY="your-production-secret-key"
export BASIC_AUTH_PASSWORD="strong-production-password"
export POSTGRES_PASSWORD="strong-database-password"
# Start production stack
docker-compose up -d
# Scale the application (optional)
docker-compose up -d --scale hockey-app=3
```
#### Option 2: Kubernetes (Multi-Server)
```yaml
# kubernetes/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hockey-app
spec:
replicas: 3
selector:
matchLabels:
app: hockey-app
template:
metadata:
labels:
app: hockey-app
spec:
containers:
- name: hockey-app
image: hockey-results:latest
ports:
- containerPort: 5000
env:
- name: DATABASE_TYPE
value: "postgresql"
- name: POSTGRES_HOST
value: "postgres-service"
```
#### Option 3: Cloud Platforms
**Google Cloud Run:**
```bash
# Build and push to Google Container Registry
./docker/build.sh --registry gcr.io/your-project-id --push
# Deploy to Cloud Run
gcloud run deploy hockey-app \
--image gcr.io/your-project-id/hockey-results:latest \
--platform managed \
--region us-central1 \
--set-env-vars DATABASE_TYPE=postgresql
```
**AWS ECS:**
```bash
# Build and push to ECR
./docker/build.sh --registry your-account.dkr.ecr.region.amazonaws.com --push
# Create ECS task definition with the image
```
## 🔧 Configuration
### Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `DATABASE_TYPE` | `sqlite` | Database type: sqlite, postgresql, mysql |
| `SECRET_KEY` | `your-secret-key-change-in-production` | Flask secret key |
| `FLASK_ENV` | `production` | Flask environment |
| `BASIC_AUTH_USERNAME` | `admin` | Basic auth username |
| `BASIC_AUTH_PASSWORD` | `letmein` | Basic auth password |
### PostgreSQL Configuration
| Variable | Default | Description |
|----------|---------|-------------|
| `POSTGRES_HOST` | `postgres` | PostgreSQL host |
| `POSTGRES_PORT` | `5432` | PostgreSQL port |
| `POSTGRES_DATABASE` | `hockey_results` | Database name |
| `POSTGRES_USER` | `hockey_user` | Database user |
| `POSTGRES_PASSWORD` | `hockey_password` | Database password |
### MySQL/MariaDB Configuration
| Variable | Default | Description |
|----------|---------|-------------|
| `MYSQL_HOST` | `mariadb` | MySQL host |
| `MYSQL_PORT` | `3306` | MySQL port |
| `MYSQL_DATABASE` | `hockey_results` | Database name |
| `MYSQL_USER` | `hockey_user` | Database user |
| `MYSQL_PASSWORD` | `hockey_password` | Database password |
## 📊 Monitoring and Logs
### View Logs
```bash
# Docker Compose
docker-compose logs -f hockey-app
# Docker Run
docker logs -f hockey-results-app
```
### Health Checks
```bash
# Check container health
docker ps
# Manual health check
curl -f http://localhost:5000/ || echo "Application is not healthy"
```
### Database Connection Test
```bash
# Test PostgreSQL connection
docker exec hockey-results-app python -c "
from motm_app.database import db_config
print('Database URL:', db_config.database_url)
"
# Test application database initialization
docker exec hockey-results-app python -c "
from motm_app.database import init_database
init_database()
print('Database initialized successfully')
"
```
## 🛠️ Development
### Local Development with Docker
```bash
# Build development image
./docker/build.sh -t dev
# Run with volume mount for live code changes
docker run -it --rm \
-p 5000:5000 \
-v $(pwd):/app \
-e FLASK_ENV=development \
-e FLASK_DEBUG=true \
hockey-results:dev
```
### Database Migrations
```bash
# Run migrations inside container
docker exec hockey-results-app python -c "
from motm_app.database import init_database
init_database()
"
```
### Backup and Restore
```bash
# Backup PostgreSQL data
docker exec hockey-postgres pg_dump -U hockey_user hockey_results > backup.sql
# Restore PostgreSQL data
docker exec -i hockey-postgres psql -U hockey_user hockey_results < backup.sql
# Backup SQLite data
docker cp hockey-results-app:/app/data/hockey_results.db ./backup.db
```
## 🔒 Security Considerations
### Production Security
1. **Change default passwords**:
```bash
export SECRET_KEY="$(openssl rand -hex 32)"
export BASIC_AUTH_PASSWORD="$(openssl rand -base64 32)"
export POSTGRES_PASSWORD="$(openssl rand -base64 32)"
```
2. **Use secrets management**:
```yaml
# docker-compose.prod.yml
services:
hockey-app:
environment:
- SECRET_KEY_FILE=/run/secrets/secret_key
secrets:
- secret_key
secrets:
secret_key:
file: ./secrets/secret_key.txt
```
3. **Network security**:
```yaml
# Use custom networks
networks:
hockey-network:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
```
## 🚨 Troubleshooting
### Common Issues
**Container won't start:**
```bash
# Check logs
docker logs hockey-results-app
# Check if port is already in use
netstat -tlnp | grep :5000
```
**Database connection issues:**
```bash
# Check database container status
docker-compose ps
# Test database connectivity
docker exec hockey-results-app python -c "
import psycopg2
conn = psycopg2.connect(host='postgres', port=5432, database='hockey_results', user='hockey_user', password='hockey_password')
print('Database connected successfully')
"
```
**Permission issues:**
```bash
# Fix file permissions
sudo chown -R $USER:$USER ./data
chmod -R 755 ./data
```
### Performance Tuning
**Database Optimization:**
```bash
# PostgreSQL tuning
docker exec hockey-postgres psql -U hockey_user hockey_results -c "
ALTER SYSTEM SET shared_buffers = '256MB';
ALTER SYSTEM SET effective_cache_size = '1GB';
SELECT pg_reload_conf();
"
```
**Application Scaling:**
```bash
# Scale application containers
docker-compose up -d --scale hockey-app=3
# Use load balancer
docker-compose --profile nginx up -d
```
## 📚 Additional Resources
- [Docker Documentation](https://docs.docker.com/)
- [Docker Compose Documentation](https://docs.docker.com/compose/)
- [PostgreSQL Docker Image](https://hub.docker.com/_/postgres)
- [MariaDB Docker Image](https://hub.docker.com/_/mariadb)
- [SQLAlchemy Documentation](https://docs.sqlalchemy.org/)