monacousa-portal/DOCKER_DEPLOYMENT_GUIDE.md

12 KiB

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

# Clone your MonacoUSA Portal repository
git clone <your-repo-url>
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

# 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:

# 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

# 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

# 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,nginx}
sudo -u deploy mkdir -p /opt/monacousa-portal-staging/{data,logs,nginx}

🔍 Health Checks & Monitoring

Built-in Health Checks

The application includes comprehensive health checks:

# 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

# 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

# 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

# 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

# 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

    # Check logs
    docker-compose logs monacousa-portal
    
    # Check environment variables
    docker-compose config
    
  2. Health check failing

    # 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

    # Clear build cache
    docker builder prune
    
    # Rebuild without cache
    docker-compose build --no-cache
    
  4. Permission issues

    # Fix volume permissions
    sudo chown -R 1001:1001 data/
    sudo chown -R 1001:1001 logs/
    

Debug Commands

# 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

# 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

# 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.