# MonacoUSA Portal - Docker & CI/CD Deployment Guide This guide covers the complete Docker containerization and Gitea CI/CD setup for the MonacoUSA Portal. ## 📋 Overview The deployment setup includes: - **Multi-stage Docker build** for optimized production images - **Docker Compose** for local development and deployment - **Gitea Actions CI/CD** pipeline with staging and production environments - **Health checks** and monitoring - **Volume management** for persistent data - **Zero-downtime deployments** ## 🐳 Docker Configuration ### Files Included 1. **`Dockerfile`** - Multi-stage build configuration 2. **`docker-compose.yml`** - Local development and deployment 3. **`docker-entrypoint.sh`** - Runtime configuration script 4. **`.dockerignore`** - Build context optimization 5. **`.env.docker`** - Environment variables template ### Docker Features - **Multi-stage build**: Optimized for production (reduces image size from ~1GB to ~200MB) - **Non-root user**: Runs as `nuxt` user for security - **Health checks**: Built-in health monitoring using `/api/health` endpoint - **Signal handling**: Proper shutdown with dumb-init - **Volume support**: Persistent data storage ## 🚀 Quick Start ### 1. Local Development ```bash # Clone your MonacoUSA Portal repository git clone cd monacousa-portal # Copy Docker files from foundation cp monacousa-portal-foundation/* . # Create environment file cp .env.docker .env # Edit .env with your actual values # Create data directory mkdir -p data logs # Build and run docker-compose up -d # Check health curl http://localhost:3000/api/health ``` ### 2. Production Deployment ```bash # On your server mkdir -p /opt/monacousa-portal cd /opt/monacousa-portal # Copy deployment files # (docker-compose.yml, .env, etc.) # Create required directories mkdir -p data logs nginx/ssl # Deploy docker-compose up -d # Verify curl https://monacousa.org/api/health ``` ## 🔧 Environment Configuration ### Required Environment Variables Copy `.env.docker` to `.env` and configure: ```bash # Generate secure keys openssl rand -base64 48 # For NUXT_SESSION_SECRET openssl rand -base64 32 # For NUXT_ENCRYPTION_KEY # Update all placeholder values with your actual configuration ``` ### Key Configuration Sections 1. **Keycloak Authentication** - Issuer URL - Client ID and secret - Callback URL 2. **NocoDB Database** - API URL and token - Base ID 3. **MinIO File Storage** - Endpoint and credentials - Bucket name 4. **Security** - Session secret - Encryption key ## 📁 Volume Management ### Volume Structure ``` /opt/monacousa-portal/ ├── data/ # Persistent application data │ ├── .env # Environment configuration │ └── uploads/ # File uploads (if local storage used) ├── logs/ # Application and nginx logs │ ├── app/ │ └── nginx/ └── nginx/ # Nginx configuration ├── nginx.conf └── ssl/ ``` ### Volume Configuration The Docker setup includes volumes for: - **Configuration**: `.env` file and settings - **Logs**: Application and web server logs - **Data**: Any persistent application data ## 🔄 CI/CD Pipeline (Gitea Actions) ### Workflow Overview The `.gitea/workflows/deploy.yml` provides: 1. **Test Stage** - Dependency installation - Linting and type checking - Build verification - Health endpoint testing 2. **Build Stage** - Docker build and push to registry - Uses Gitea variables for registry configuration - Tags with branch name and latest 3. **Deploy Stages** - **Staging**: Automatic deployment on `develop` branch - **Production**: Automatic deployment on `main` branch - Zero-downtime deployments - Health check verification 4. **Notification Stage** - Success/failure notifications - Webhook support ### Required Gitea Configuration #### Variables (Repository Settings > Actions > Variables) - `REGISTRY_HOST` - Docker registry hostname (e.g., `registry.monacousa.org`) - `REGISTRY_USERNAME` - Registry username - `IMAGE_NAME` - Docker image name (e.g., `monacousa-portal`) #### Secrets (Repository Settings > Actions > Secrets) - `REGISTRY_TOKEN` - Registry authentication token #### Deployment Secrets (if using deployment stages) - `STAGING_HOST` - Staging server hostname - `STAGING_USER` - SSH username for staging - `STAGING_SSH_KEY` - SSH private key for staging - `STAGING_PORT` - SSH port (optional, defaults to 22) - `PRODUCTION_HOST` - Production server hostname - `PRODUCTION_USER` - SSH username for production - `PRODUCTION_SSH_KEY` - SSH private key for production - `PRODUCTION_PORT` - SSH port (optional, defaults to 22) ### Workflow Features - **Automatic builds** on push to main/develop branches - **Multi-platform support** (linux/amd64) - **Branch-based tagging** (latest for main, branch name for others) - **Health check verification** before and after deployment - **Rollback capability** with image backups - **Clean up** of old Docker images ## 🏗️ Server Setup ### Prerequisites ```bash # Install Docker and Docker Compose curl -fsSL https://get.docker.com -o get-docker.sh sh get-docker.sh # Install Docker Compose sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose # Create deployment user sudo useradd -m -s /bin/bash deploy sudo usermod -aG docker deploy # Setup SSH key for deployment sudo -u deploy mkdir -p /home/deploy/.ssh # Add your public key to /home/deploy/.ssh/authorized_keys ``` ### Directory Structure ```bash # Create application directories sudo mkdir -p /opt/monacousa-portal sudo mkdir -p /opt/monacousa-portal-staging sudo chown -R deploy:deploy /opt/monacousa-portal* # Create data directories sudo -u deploy mkdir -p /opt/monacousa-portal/{data,logs} sudo -u deploy mkdir -p /opt/monacousa-portal-staging/{data,logs} ``` ### Server-Level Nginx Configuration The included `nginx-portal.conf` file is a reference configuration for your server-level nginx setup. Configure nginx on your server to: - **Reverse proxy** to the Docker container on port 6060 - **SSL termination** with your certificates - **Security headers** and optimizations - **Static file serving** if needed Example server nginx configuration: ```nginx server { listen 443 ssl http2; server_name portal.monacousa.org; # SSL configuration ssl_certificate /path/to/your/cert.pem; ssl_certificate_key /path/to/your/key.pem; # Proxy to Docker container location / { proxy_pass http://localhost:6060; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } ``` ## 🔍 Health Checks & Monitoring ### Built-in Health Checks The application includes comprehensive health checks: ```bash # Docker health check docker ps # Shows health status # Manual health check curl http://localhost:3000/api/health # Expected response { "status": "healthy", "timestamp": "2025-01-06T12:00:00.000Z", "services": { "database": "connected", "storage": "connected", "auth": "connected" } } ``` ### Monitoring Commands ```bash # View container logs docker-compose logs -f monacousa-portal # Check container status docker-compose ps # View resource usage docker stats monacousa-portal # Check health endpoint watch -n 5 'curl -s http://localhost:3000/api/health | jq' ``` ## 🔄 Deployment Operations ### Manual Deployment ```bash # Pull latest image docker pull registry.monacousa.org/monacousa/monacousa-portal:latest # Update and restart docker-compose up -d --no-deps monacousa-portal # Verify deployment curl -f https://monacousa.org/api/health ``` ### Rollback Procedure ```bash # List available images docker images registry.monacousa.org/monacousa/monacousa-portal # Rollback to previous version docker tag registry.monacousa.org/monacousa/monacousa-portal:backup-20250106-120000 registry.monacousa.org/monacousa/monacousa-portal:latest docker-compose up -d --no-deps monacousa-portal # Verify rollback curl -f https://monacousa.org/api/health ``` ### Backup Procedures ```bash # Backup environment configuration cp data/.env data/.env.backup.$(date +%Y%m%d-%H%M%S) # Backup logs tar -czf logs-backup-$(date +%Y%m%d-%H%M%S).tar.gz logs/ # Create container backup docker commit monacousa-portal monacousa-portal:backup-$(date +%Y%m%d-%H%M%S) ``` ## 🛠️ Troubleshooting ### Common Issues 1. **Container won't start** ```bash # Check logs docker-compose logs monacousa-portal # Check environment variables docker-compose config ``` 2. **Health check failing** ```bash # Test health endpoint manually docker exec monacousa-portal curl http://localhost:3000/api/health # Check service dependencies # Verify Keycloak, NocoDB, and MinIO connectivity ``` 3. **Build failures** ```bash # Clear build cache docker builder prune # Rebuild without cache docker-compose build --no-cache ``` 4. **Permission issues** ```bash # Fix volume permissions sudo chown -R 1001:1001 data/ sudo chown -R 1001:1001 logs/ ``` ### Debug Commands ```bash # Enter container shell docker exec -it monacousa-portal sh # View environment variables docker exec monacousa-portal env # Check file permissions docker exec monacousa-portal ls -la /app/ # Test network connectivity docker exec monacousa-portal ping auth.monacousa.org ``` ## 📊 Performance Optimization ### Resource Limits The Docker Compose configuration includes resource limits: - **Memory**: 512MB limit, 256MB reservation - **CPU**: Adjust based on your server capacity ### Optimization Tips 1. **Image optimization** - Multi-stage builds reduce image size - Alpine Linux base for smaller footprint - Proper .dockerignore to exclude unnecessary files 2. **Runtime optimization** - Health checks prevent traffic to unhealthy containers - Proper signal handling for graceful shutdowns - Non-root user for security 3. **Deployment optimization** - Zero-downtime deployments - Build caching for faster CI/CD - Image cleanup to save disk space ## 🔐 Security Considerations ### Container Security - **Non-root user**: Application runs as `nuxt` user (UID 1001) - **Read-only filesystem**: Consider adding read-only root filesystem - **Security scanning**: Regularly scan images for vulnerabilities - **Secrets management**: Environment variables for sensitive data ### Network Security - **Reverse proxy**: Use nginx for SSL termination - **Firewall**: Restrict access to necessary ports only - **SSL/TLS**: Always use HTTPS in production - **Security headers**: Configure appropriate security headers ### Deployment Security - **SSH keys**: Use key-based authentication for deployments - **Limited permissions**: Deploy user has minimal required permissions - **Registry security**: Use private registry with authentication - **Environment isolation**: Separate staging and production environments ## 📚 Additional Resources ### Docker Commands Reference ```bash # Build image locally docker build -t monacousa-portal . # Run container with environment file docker run --env-file .env -p 3000:3000 monacousa-portal # View container logs docker logs -f monacousa-portal # Execute commands in container docker exec -it monacousa-portal sh # Clean up unused images docker image prune -f # View image layers docker history monacousa-portal ``` ### Docker Compose Commands ```bash # Start services docker-compose up -d # View logs docker-compose logs -f # Restart specific service docker-compose restart monacousa-portal # Update and restart docker-compose up -d --no-deps monacousa-portal # Stop all services docker-compose down # Remove volumes (careful!) docker-compose down -v ``` ### Gitea Actions Tips 1. **Testing workflows locally** - Use `act` tool to test workflows locally - Validate YAML syntax before pushing 2. **Debugging workflows** - Add debug steps with `echo` commands - Use `actions/upload-artifact` for debugging files 3. **Optimizing build times** - Use build caching - Minimize context size with .dockerignore - Use multi-stage builds effectively ## 🎯 Best Practices ### Development Workflow 1. **Local development** - Use docker-compose for consistent environment - Mount source code for live reloading - Use separate .env.local for development 2. **Testing** - Test Docker builds locally before pushing - Verify health endpoints work correctly - Test with production-like data volumes 3. **Deployment** - Always test in staging first - Monitor health checks after deployment - Keep rollback procedures ready ### Production Checklist - [ ] Environment variables configured - [ ] SSL certificates installed - [ ] Firewall rules configured - [ ] Monitoring and alerting set up - [ ] Backup procedures tested - [ ] Rollback procedures tested - [ ] Health checks working - [ ] Log rotation configured - [ ] Resource limits appropriate - [ ] Security scanning completed This deployment guide provides everything needed to successfully containerize and deploy the MonacoUSA Portal using Docker and Gitea Actions CI/CD pipeline.