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
Dockerfile- Multi-stage build configurationdocker-compose.yml- Local development and deploymentdocker-entrypoint.sh- Runtime configuration script.dockerignore- Build context optimization.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
nuxtuser for security - Health checks: Built-in health monitoring using
/api/healthendpoint - 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
-
Keycloak Authentication
- Issuer URL
- Client ID and secret
- Callback URL
-
NocoDB Database
- API URL and token
- Base ID
-
MinIO File Storage
- Endpoint and credentials
- Bucket name
-
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:
.envfile 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:
-
Test Stage
- Dependency installation
- Linting and type checking
- Build verification
- Health endpoint testing
-
Build Stage
- Docker build and push to registry
- Uses Gitea variables for registry configuration
- Tags with branch name and latest
-
Deploy Stages
- Staging: Automatic deployment on
developbranch - Production: Automatic deployment on
mainbranch - Zero-downtime deployments
- Health check verification
- Staging: Automatic deployment on
-
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 usernameIMAGE_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 hostnameSTAGING_USER- SSH username for stagingSTAGING_SSH_KEY- SSH private key for stagingSTAGING_PORT- SSH port (optional, defaults to 22)PRODUCTION_HOST- Production server hostnamePRODUCTION_USER- SSH username for productionPRODUCTION_SSH_KEY- SSH private key for productionPRODUCTION_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
-
Container won't start
# Check logs docker-compose logs monacousa-portal # Check environment variables docker-compose config -
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 -
Build failures
# Clear build cache docker builder prune # Rebuild without cache docker-compose build --no-cache -
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
-
Image optimization
- Multi-stage builds reduce image size
- Alpine Linux base for smaller footprint
- Proper .dockerignore to exclude unnecessary files
-
Runtime optimization
- Health checks prevent traffic to unhealthy containers
- Proper signal handling for graceful shutdowns
- Non-root user for security
-
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
nuxtuser (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
-
Testing workflows locally
- Use
acttool to test workflows locally - Validate YAML syntax before pushing
- Use
-
Debugging workflows
- Add debug steps with
echocommands - Use
actions/upload-artifactfor debugging files
- Add debug steps with
-
Optimizing build times
- Use build caching
- Minimize context size with .dockerignore
- Use multi-stage builds effectively
🎯 Best Practices
Development Workflow
-
Local development
- Use docker-compose for consistent environment
- Mount source code for live reloading
- Use separate .env.local for development
-
Testing
- Test Docker builds locally before pushing
- Verify health endpoints work correctly
- Test with production-like data volumes
-
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.