Files
michaelschiemer/docs/deployment/env-production-template.md
Michael Schiemer fc3d7e6357 feat(Production): Complete production deployment infrastructure
- Add comprehensive health check system with multiple endpoints
- Add Prometheus metrics endpoint
- Add production logging configurations (5 strategies)
- Add complete deployment documentation suite:
  * QUICKSTART.md - 30-minute deployment guide
  * DEPLOYMENT_CHECKLIST.md - Printable verification checklist
  * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle
  * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference
  * production-logging.md - Logging configuration guide
  * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation
  * README.md - Navigation hub
  * DEPLOYMENT_SUMMARY.md - Executive summary
- Add deployment scripts and automation
- Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment
- Update README with production-ready features

All production infrastructure is now complete and ready for deployment.
2025-10-25 19:18:37 +02:00

12 KiB

Production Environment Configuration Template

Production-optimierte .env Konfiguration für das Custom PHP Framework.

.env.production Template

# ============================================================================
# PRODUCTION ENVIRONMENT CONFIGURATION
# ============================================================================
# SECURITY: Never commit this file to version control!
# SECURITY: Store sensitive values in Vault, reference here only
# ============================================================================

# ============================================================================
# APPLICATION CONFIGURATION
# ============================================================================
COMPOSE_PROJECT_NAME=michaelschiemer-prod
APP_ENV=production
APP_DEBUG=false
APP_URL=https://your-domain.com

# Application Port (behind reverse proxy/load balancer)
APP_PORT=80

# PHP Version
PHP_VERSION=8.4

# ============================================================================
# DATABASE CONFIGURATION (PostgreSQL)
# ============================================================================
# SECURITY: Use strong passwords (minimum 32 characters)
# Generate with: openssl rand -base64 32
DB_DRIVER=pgsql
DB_HOST=db
DB_PORT=5432
DB_DATABASE=michaelschiemer_prod
DB_USERNAME=postgres
DB_PASSWORD=CHANGE_ME_STRONG_PASSWORD_32_CHARS_MIN
DB_CHARSET=utf8
DB_SCHEMA=public

# Connection Pooling (Production Optimized)
DB_POOL_MIN=5
DB_POOL_MAX=20

# ============================================================================
# REDIS CONFIGURATION
# ============================================================================
# SECURITY: Enable Redis password authentication in production
REDIS_SCHEME=tcp
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=CHANGE_ME_STRONG_REDIS_PASSWORD

# ============================================================================
# RATE LIMITING CONFIGURATION
# ============================================================================
# Production values - stricter than development
RATE_LIMIT_DEFAULT=30
RATE_LIMIT_WINDOW=60
RATE_LIMIT_AUTH=5
RATE_LIMIT_AUTH_WINDOW=300
RATE_LIMIT_API=20
RATE_LIMIT_API_WINDOW=60

# ============================================================================
# SECURITY CONFIGURATION
# ============================================================================

# Vault Configuration
# Generate with: php console.php vault:generate-key
# CRITICAL: Store this key securely, losing it means losing all encrypted data
VAULT_ENCRYPTION_KEY=CHANGE_ME_GENERATE_WITH_CONSOLE_COMMAND

# Admin IP Whitelist (comma-separated)
# SECURITY: Restrict admin access to known IPs only
ADMIN_ALLOWED_IPS=203.0.113.42,198.51.100.10

# CSRF Token Configuration
CSRF_TOKEN_LIFETIME=3600

# Session Configuration
SESSION_LIFETIME=3600
SESSION_SECURE_COOKIE=true
SESSION_HTTP_ONLY=true
SESSION_SAME_SITE=strict

# ============================================================================
# SSL/TLS CONFIGURATION
# ============================================================================
# Let's Encrypt / Certbot Configuration
SSL_ENABLED=true
SSL_DOMAIN=your-domain.com
SSL_EMAIL=admin@your-domain.com
SSL_MODE=production
# CERTBOT_STAGING=false  # Set to true for testing
CERTBOT_CONF_DIR=/etc/letsencrypt
CERTBOT_WEBROOT=/var/www/certbot
CERTBOT_LOGS_DIR=/var/log/letsencrypt

# ============================================================================
# MONITORING & LOGGING CONFIGURATION
# ============================================================================

# Logging Level (emergency, alert, critical, error, warning, notice, info, debug)
LOG_LEVEL=warning

# Performance Monitoring
PERFORMANCE_MONITORING_ENABLED=true
PERFORMANCE_THRESHOLD_MS=500

# Error Reporting
ERROR_REPORTING_ENABLED=true
ERROR_AGGREGATION_ENABLED=true

# N+1 Detection (Disable ML in production for performance)
NPLUSONE_ML_ENABLED=false
NPLUSONE_ML_TIMEOUT_MS=5000
NPLUSONE_ML_CONFIDENCE_THRESHOLD=70.0

# Health Check Endpoint
HEALTH_CHECK_ENABLED=true
HEALTH_CHECK_PATH=/health

# ============================================================================
# EXTERNAL API CONFIGURATION
# ============================================================================

# RapidMail API
# SECURITY: Store credentials in Vault, reference here
RAPIDMAIL_USERNAME=CHANGE_ME_YOUR_RAPIDMAIL_USERNAME
RAPIDMAIL_PASSWORD=CHANGE_ME_YOUR_RAPIDMAIL_PASSWORD
RAPIDMAIL_DEFAULT_LIST_ID=CHANGE_ME_YOUR_LIST_ID

# Shopify API
# SECURITY: Store access token in Vault
SHOPIFY_SHOP_DOMAIN=yourstore.myshopify.com
SHOPIFY_ACCESS_TOKEN=CHANGE_ME_SHOPIFY_ACCESS_TOKEN
SHOPIFY_API_VERSION=2024-04

# ============================================================================
# OAUTH PROVIDER CONFIGURATION
# ============================================================================

# Spotify OAuth
SPOTIFY_CLIENT_ID=CHANGE_ME_SPOTIFY_CLIENT_ID
SPOTIFY_CLIENT_SECRET=CHANGE_ME_SPOTIFY_CLIENT_SECRET
SPOTIFY_REDIRECT_URI=https://your-domain.com/oauth/spotify/callback

# Apple Music OAuth
APPLE_MUSIC_CLIENT_ID=CHANGE_ME_APPLE_MUSIC_CLIENT_ID
APPLE_MUSIC_TEAM_ID=CHANGE_ME_APPLE_MUSIC_TEAM_ID
APPLE_MUSIC_KEY_ID=CHANGE_ME_APPLE_MUSIC_KEY_ID
APPLE_MUSIC_PRIVATE_KEY=/path/to/apple_music_private_key.p8
APPLE_MUSIC_REDIRECT_URI=https://your-domain.com/oauth/apple-music/callback

# Tidal OAuth
TIDAL_CLIENT_ID=CHANGE_ME_TIDAL_CLIENT_ID
TIDAL_CLIENT_SECRET=CHANGE_ME_TIDAL_CLIENT_SECRET
TIDAL_REDIRECT_URI=https://your-domain.com/oauth/tidal/callback

# ============================================================================
# FILESYSTEM & CACHING CONFIGURATION
# ============================================================================

# Filesystem Performance (leave caching enabled in production)
FILESYSTEM_DISABLE_CACHE=false

# OPcache Configuration (handled via php.production.ini)
# See: docker/php/php.production.ini

# ============================================================================
# BACKUP CONFIGURATION
# ============================================================================

# Database Backup Configuration
BACKUP_ENABLED=true
BACKUP_SCHEDULE=0 2 * * *  # Daily at 2 AM
BACKUP_RETENTION_DAYS=30
BACKUP_ENCRYPTION_ENABLED=true
BACKUP_STORAGE_PATH=/backups

# ============================================================================
# DEPLOYMENT CONFIGURATION
# ============================================================================

# Zero-Downtime Deployment
DEPLOYMENT_MODE=rolling
DEPLOYMENT_HEALTH_CHECK_TIMEOUT=60
DEPLOYMENT_MAX_RETRIES=3

# Container Resource Limits (set in docker-compose.production.yml)
# PHP_MEMORY_LIMIT=512M
# PHP_MAX_EXECUTION_TIME=30
# NGINX_WORKER_PROCESSES=auto
# NGINX_WORKER_CONNECTIONS=2048

# ============================================================================
# OPTIONAL FEATURES
# ============================================================================

# Feature Flags
FEATURE_GRAPHQL_ENABLED=true
FEATURE_ASYNC_PROCESSING_ENABLED=true
FEATURE_LIVE_COMPONENTS_ENABLED=true

# Queue Configuration
QUEUE_DRIVER=redis
QUEUE_CONNECTION=default
QUEUE_RETRY_AFTER=90

# Scheduler Configuration
SCHEDULER_ENABLED=true
SCHEDULER_TIMEZONE=Europe/Berlin

# ============================================================================
# ENVIRONMENT-SPECIFIC OVERRIDES
# ============================================================================

# Staging Environment (if needed)
# Copy this file to .env.staging and adjust values:
# - APP_ENV=staging
# - APP_DEBUG=false
# - SSL_MODE=staging (Let's Encrypt staging)
# - Less restrictive rate limits
# - Test database/Redis instances

Security Checklist

Before Deployment

  • Replace ALL CHANGE_ME_* placeholders with actual values
  • Generate VAULT_ENCRYPTION_KEY: php console.php vault:generate-key
  • Generate strong database password (32+ characters)
  • Generate strong Redis password
  • Configure ADMIN_ALLOWED_IPS with production IPs
  • Verify SSL_DOMAIN matches DNS configuration
  • Verify SSL_EMAIL is valid for Let's Encrypt notifications
  • Store sensitive credentials in Vault (not in .env file)
  • Set APP_DEBUG=false (CRITICAL: Never enable debug in production)
  • Set SESSION_SECURE_COOKIE=true
  • Verify all OAuth redirect URIs match production domain

After Deployment

  • Verify .env.production is not committed to version control
  • Set file permissions: chmod 600 .env.production
  • Verify environment variables loaded: php console.php env:check
  • Test Vault encryption: php console.php vault:test
  • Initialize SSL certificates: php console.php ssl:init
  • Verify SSL certificate status: php console.php ssl:status
  • Test health check endpoint: curl https://your-domain.com/health
  • Monitor logs for errors: docker-compose logs -f --tail=100

Secrets Management Strategy

CRITICAL: Do NOT store sensitive values in .env.production directly.

  1. Use Vault for Sensitive Data:
# Store sensitive values in Vault
php console.php vault:store rapidmail_password "actual_password_here"
php console.php vault:store shopify_access_token "actual_token_here"

# Reference in application code
$password = $vault->get('rapidmail_password');
  1. Environment-Specific Vaults:
  • Production Vault (encrypted with VAULT_ENCRYPTION_KEY)
  • Staging Vault (different encryption key)
  • Development Vault (different encryption key)
  1. Key Rotation Schedule:
  • Vault encryption key: Rotate quarterly
  • Database passwords: Rotate semi-annually
  • API tokens: Rotate when provider recommends
  • SSL certificates: Auto-renewed by Certbot

Configuration Validation

# Validate production configuration
php console.php config:validate --env=production

# Check for missing required values
php console.php config:check --strict

# Test database connection
php console.php db:test-connection

# Test Redis connection
php console.php redis:test-connection

# Verify SSL configuration
php console.php ssl:test

Environment File Hierarchy

.env.example          # Template with placeholders
.env                  # Development (local, debug enabled)
.env.staging          # Staging (production-like, staging SSL)
.env.production       # Production (this template)

Load Priority: .env.production > .env > Environment Variables > Defaults

Docker Compose Integration

Production environment is loaded via docker-compose:

# Load production environment
docker-compose -f docker-compose.yml -f docker-compose.production.yml --env-file .env.production up -d

# Verify environment loaded correctly
docker-compose -f docker-compose.yml -f docker-compose.production.yml --env-file .env.production config

Troubleshooting

Problem: Environment variables not loaded

# Check if .env.production exists
ls -la .env.production

# Verify file permissions
chmod 600 .env.production

# Check Docker Compose loads it
docker-compose --env-file .env.production config | grep APP_ENV

Problem: Vault encryption key lost

WARNING: If VAULT_ENCRYPTION_KEY is lost, all encrypted data is UNRECOVERABLE.

Prevention:

  • Store key in secure password manager
  • Backup key to encrypted offline storage
  • Document key rotation procedure

Recovery:

  • Restore from encrypted backup (if available)
  • Regenerate key and re-encrypt all data
  • Update all services with new key

Problem: SSL certificate initialization fails

# Test configuration
php console.php ssl:test

# Check DNS configuration
dig +short your-domain.com

# Verify ports 80/443 open
netstat -tuln | grep -E ':(80|443)'

# Check Certbot logs
docker-compose logs certbot
tail -f /var/log/letsencrypt/letsencrypt.log

Production Deployment Command

# Complete production deployment
./scripts/deploy-production.sh

# Or manual deployment
docker-compose -f docker-compose.yml \
               -f docker-compose.production.yml \
               --env-file .env.production \
               up -d --build

# Wait for health checks
./scripts/wait-for-health.sh

# Run database migrations
docker exec php php console.php db:migrate --env=production

# Verify deployment
curl -f https://your-domain.com/health || exit 1

See Also

  • Prerequisites: docs/deployment/production-prerequisites.md
  • SSL Setup: docs/deployment/ssl-setup.md
  • Database Migrations: docs/deployment/database-migrations.md (TODO)
  • Monitoring: docs/deployment/monitoring.md (TODO)
  • Rollback Guide: docs/deployment/rollback-guide.md (TODO)