# 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 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/)