- Update Gitea configuration (remove DEFAULT_ACTIONS_URL) - Fix deployment documentation - Update Ansible playbooks - Clean up deprecated files - Add new deployment scripts and templates
817 lines
20 KiB
Markdown
817 lines
20 KiB
Markdown
# Production Deployment Automation
|
|
|
|
⚠️ **WICHTIG:** Diese Dokumentation ist veraltet.
|
|
|
|
**Für aktuelle Deployment-Automation siehe:**
|
|
- **[deployment/ansible/](../../deployment/ansible/)** - Aktuelle Ansible-Playbooks
|
|
- **[deployment/DEPLOYMENT_COMMANDS.md](../../deployment/DEPLOYMENT_COMMANDS.md)** - Command-Referenz
|
|
- **[deployment/CODE_CHANGE_WORKFLOW.md](../../deployment/CODE_CHANGE_WORKFLOW.md)** - Workflow-Dokumentation
|
|
|
|
---
|
|
|
|
**Historische Dokumentation (veraltet):**
|
|
|
|
Comprehensive guide to automated production deployment scripts for the Custom PHP Framework.
|
|
|
|
## Overview
|
|
|
|
The framework includes three main automation scripts for production operations:
|
|
|
|
1. **`production-deploy.sh`** - Full deployment automation (initial, update, rollback)
|
|
2. **`health-check.sh`** - Comprehensive health monitoring
|
|
3. **`backup.sh`** - Automated backup system
|
|
|
|
All scripts are located in `scripts/` directory and designed for Docker-based production deployments.
|
|
|
|
## Production Deployment Script
|
|
|
|
**Location**: `scripts/production-deploy.sh`
|
|
|
|
### Usage
|
|
|
|
```bash
|
|
# Initial deployment (first time)
|
|
./scripts/production-deploy.sh initial
|
|
|
|
# Update deployment (zero-downtime rolling update)
|
|
./scripts/production-deploy.sh update
|
|
|
|
# Rollback to previous version
|
|
./scripts/production-deploy.sh rollback
|
|
```
|
|
|
|
### Initial Deployment
|
|
|
|
First-time production setup with complete environment initialization:
|
|
|
|
```bash
|
|
# Prerequisites:
|
|
# 1. .env.production configured with VAULT_ENCRYPTION_KEY
|
|
# 2. docker-compose.production.yml present
|
|
# 3. Server meets hardware requirements (8GB RAM, 4 CPUs)
|
|
|
|
./scripts/production-deploy.sh initial
|
|
```
|
|
|
|
**What it does**:
|
|
1. ✅ Checks prerequisites (Docker, Compose, configuration files)
|
|
2. ✅ Verifies VAULT_ENCRYPTION_KEY is configured
|
|
3. ✅ Builds Docker images with production optimizations
|
|
4. ✅ Starts all services (web, php, db, redis, queue-worker, certbot)
|
|
5. ✅ Waits for services to be ready (20s)
|
|
6. ✅ Runs database migrations
|
|
7. ✅ Initializes SSL certificates via PHP console command
|
|
8. ✅ Verifies Vault is accessible
|
|
9. ✅ Runs health checks with retries (30 attempts)
|
|
10. ✅ Displays deployment summary
|
|
|
|
**Output Example**:
|
|
```
|
|
[12:34:56] 🚀 Starting initial production deployment...
|
|
[12:34:56] Checking prerequisites...
|
|
✅ Prerequisites check passed
|
|
[12:35:10] Building Docker images...
|
|
✅ Docker images built
|
|
[12:36:00] Starting Docker services...
|
|
[12:36:20] Running database migrations...
|
|
✅ Database migrations completed
|
|
[12:36:30] Initializing SSL certificates...
|
|
✅ SSL certificate initialized
|
|
[12:36:40] Running health checks...
|
|
✅ Health check passed
|
|
|
|
========================================
|
|
Deployment Summary
|
|
========================================
|
|
|
|
📋 Mode: initial
|
|
⏰ Timestamp: 2024-10-25 12:37:00
|
|
📁 Project: /home/michael/dev/michaelschiemer
|
|
💾 Backup: (none - initial deployment)
|
|
|
|
🐳 Docker Services:
|
|
NAME STATUS
|
|
web Up (healthy)
|
|
php Up (healthy)
|
|
db Up (healthy)
|
|
redis Up (healthy)
|
|
queue-worker Up (2 replicas)
|
|
certbot Up
|
|
|
|
🔒 Security Checks:
|
|
[ ] APP_ENV=production in .env.production
|
|
[ ] APP_DEBUG=false in .env.production
|
|
[ ] VAULT_ENCRYPTION_KEY configured
|
|
[ ] ADMIN_ALLOWED_IPS configured
|
|
[ ] SSL certificates valid
|
|
|
|
✅ 🎉 Initial deployment completed successfully!
|
|
```
|
|
|
|
### Update Deployment (Zero-Downtime)
|
|
|
|
Rolling update with automatic backup and health checks:
|
|
|
|
```bash
|
|
./scripts/production-deploy.sh update
|
|
```
|
|
|
|
**What it does**:
|
|
1. ✅ Checks prerequisites
|
|
2. ✅ **Creates full backup** (database, .env, storage)
|
|
3. ✅ Pulls latest images (if using registry)
|
|
4. ✅ Builds new Docker images
|
|
5. ✅ Runs database migrations
|
|
6. ✅ **Rolling restart** with minimal downtime:
|
|
- PHP-FPM first (10s wait)
|
|
- Web server next (5s wait)
|
|
- Queue workers last (graceful shutdown via 60s grace period)
|
|
7. ✅ Runs health checks
|
|
8. ✅ Cleans up old Docker images
|
|
9. ✅ Displays summary
|
|
|
|
**Zero-Downtime Strategy**:
|
|
- **PHP-FPM** restarted first while old web server still serves requests
|
|
- **Web Server** restarted after PHP is ready
|
|
- **Queue Workers** restarted last with 60s graceful shutdown for jobs to complete
|
|
- **Health checks** verify each step before proceeding
|
|
|
|
**Automatic Rollback on Failure**:
|
|
If any step fails, the script automatically rolls back to the backup:
|
|
|
|
```bash
|
|
❌ Health check failed after 30 attempts
|
|
[12:40:00] Cleaning up after error...
|
|
⚠️ Rolling back to previous version...
|
|
[12:40:10] Restoring from backup: /backups/backup_20241025_123456
|
|
✅ Database restored
|
|
✅ .env restored
|
|
✅ Storage restored
|
|
✅ Backup restored successfully
|
|
```
|
|
|
|
### Rollback Deployment
|
|
|
|
Restore from latest backup:
|
|
|
|
```bash
|
|
./scripts/production-deploy.sh rollback
|
|
```
|
|
|
|
**What it does**:
|
|
1. ✅ Finds latest backup
|
|
2. ✅ Prompts for confirmation
|
|
3. ✅ Restores database from backup
|
|
4. ✅ Restores .env configuration
|
|
5. ✅ Restores storage directory
|
|
6. ✅ Restarts all services
|
|
7. ✅ Runs health checks
|
|
|
|
**Interactive Confirmation**:
|
|
```
|
|
⏪ Starting rollback...
|
|
⚠️ Rolling back to: /backups/backup_20241025_123456
|
|
Continue? (yes/no): yes
|
|
[12:45:00] Restoring from backup...
|
|
✅ Database restored
|
|
✅ .env restored
|
|
✅ Storage restored
|
|
✅ Backup restored successfully
|
|
✅ Health check passed
|
|
✅ 🎉 Rollback completed successfully!
|
|
```
|
|
|
|
### Backup Strategy
|
|
|
|
Backups are created automatically during update deployments:
|
|
|
|
**Backup Location**: `../backups/backup_YYYYMMDD_HHMMSS_*`
|
|
|
|
**Backup Contents**:
|
|
- `backup_YYYYMMDD_HHMMSS_database.sql.gz` - PostgreSQL database dump
|
|
- `backup_YYYYMMDD_HHMMSS_env` - .env configuration
|
|
- `backup_YYYYMMDD_HHMMSS_storage.tar.gz` - Storage directory (logs, cache, queue)
|
|
|
|
**Retention Policy**: Last 5 backups are retained, older backups are automatically cleaned up.
|
|
|
|
### Error Handling
|
|
|
|
The script includes comprehensive error handling:
|
|
|
|
```bash
|
|
# Automatic cleanup on error
|
|
trap cleanup_on_error ERR
|
|
|
|
cleanup_on_error() {
|
|
log "Cleaning up after error..."
|
|
|
|
if [[ -d "$BACKUP_PATH" ]]; then
|
|
warning "Rolling back to previous version..."
|
|
restore_backup "$BACKUP_PATH"
|
|
fi
|
|
}
|
|
```
|
|
|
|
**Common Errors**:
|
|
|
|
1. **Missing VAULT_ENCRYPTION_KEY**:
|
|
```
|
|
❌ VAULT_ENCRYPTION_KEY not configured in .env.production
|
|
```
|
|
**Fix**: Generate key with `docker exec php php console.php vault:generate-key`
|
|
|
|
2. **Prerequisites not met**:
|
|
```
|
|
❌ Docker is not installed
|
|
```
|
|
**Fix**: Install Docker and Docker Compose
|
|
|
|
3. **Health check failed**:
|
|
```
|
|
❌ Health check failed after 30 attempts
|
|
```
|
|
**Fix**: Check logs with `docker compose logs -f --tail=100`
|
|
|
|
---
|
|
|
|
## Health Check Script
|
|
|
|
**Location**: `scripts/health-check.sh`
|
|
|
|
### Usage
|
|
|
|
```bash
|
|
# Basic health check
|
|
./scripts/health-check.sh
|
|
|
|
# Verbose output
|
|
./scripts/health-check.sh --verbose
|
|
|
|
# JSON output (for monitoring systems)
|
|
./scripts/health-check.sh --json
|
|
```
|
|
|
|
### Health Check Components
|
|
|
|
The script performs 12 comprehensive health checks:
|
|
|
|
1. **Docker Daemon** - Verifies Docker is running
|
|
2. **Docker Services** - Checks all 5 services (web, php, db, redis, queue-worker)
|
|
3. **Web Response** - HTTP response from Nginx (3 retries)
|
|
4. **Health Endpoint** - `/health` endpoint availability
|
|
5. **Database** - PostgreSQL connectivity via `pg_isready`
|
|
6. **Redis** - Redis ping command
|
|
7. **SSL Certificate** - Certificate validity via PHP console
|
|
8. **Vault** - Vault accessibility check
|
|
9. **Disk Space** - Disk usage monitoring (warn >80%, critical >90%)
|
|
10. **Memory** - System memory usage (warn >80%, critical >90%)
|
|
11. **Queue Workers** - Verify 2 workers running
|
|
12. **Recent Errors** - Log analysis for error frequency
|
|
|
|
### Output Format
|
|
|
|
**Standard Output**:
|
|
```
|
|
[12:50:00] 🔍 Starting production health check...
|
|
|
|
[12:50:01] Checking Docker daemon...
|
|
✅ Docker daemon is running
|
|
[12:50:02] Checking Docker Compose services...
|
|
✅ All Docker services are running
|
|
[12:50:03] Checking web server response...
|
|
✅ Web server is responding
|
|
[12:50:04] Checking /health endpoint...
|
|
✅ Health endpoint is responding
|
|
[12:50:05] Checking database connectivity...
|
|
✅ Database is accepting connections
|
|
[12:50:06] Checking Redis connectivity...
|
|
✅ Redis is responding
|
|
[12:50:07] Checking SSL certificate...
|
|
✅ SSL certificate is valid
|
|
[12:50:08] Checking Vault connectivity...
|
|
✅ Vault is accessible
|
|
[12:50:09] Checking disk space...
|
|
✅ Disk space usage: 45%
|
|
[12:50:10] Checking memory usage...
|
|
✅ Memory usage: 62%
|
|
[12:50:11] Checking queue workers...
|
|
✅ Queue workers: 2 running
|
|
[12:50:12] Checking recent errors in logs...
|
|
✅ Recent errors: 2 (last 1000 lines)
|
|
|
|
========================================
|
|
Production Health Check Summary
|
|
========================================
|
|
|
|
📊 Health Status:
|
|
✅ Healthy: 12
|
|
⚠️ Warnings: 0
|
|
❌ Unhealthy: 0
|
|
|
|
Overall Status: HEALTHY ✅
|
|
|
|
🎉 All critical systems are operational
|
|
|
|
========================================
|
|
```
|
|
|
|
**JSON Output** (for monitoring systems):
|
|
```json
|
|
{
|
|
"timestamp": "2024-10-25T12:50:12+00:00",
|
|
"overall_status": "healthy",
|
|
"checks": {
|
|
"docker": "healthy",
|
|
"service_web": "healthy",
|
|
"service_php": "healthy",
|
|
"service_db": "healthy",
|
|
"service_redis": "healthy",
|
|
"service_queue-worker": "healthy",
|
|
"web_response": "healthy",
|
|
"health_endpoint": "healthy",
|
|
"database": "healthy",
|
|
"redis": "healthy",
|
|
"ssl": "healthy",
|
|
"vault": "healthy",
|
|
"disk_space": "healthy",
|
|
"memory": "healthy",
|
|
"queue_workers": "healthy",
|
|
"recent_errors": "healthy"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Verbose Mode
|
|
|
|
Provides additional details:
|
|
|
|
```bash
|
|
./scripts/health-check.sh --verbose
|
|
```
|
|
|
|
**Additional Information**:
|
|
- Active database connections
|
|
- Redis memory usage
|
|
- Full SSL certificate status
|
|
- Detailed error log excerpt
|
|
|
|
### Exit Codes
|
|
|
|
- **0** - All checks healthy
|
|
- **1** - One or more critical checks failed
|
|
|
|
### Integration with Monitoring
|
|
|
|
**Cron Job** (every 5 minutes):
|
|
```cron
|
|
*/5 * * * * /path/to/scripts/health-check.sh --json > /var/log/health-check.json
|
|
```
|
|
|
|
**Alerting Integration**:
|
|
```bash
|
|
# Send alert if unhealthy
|
|
if ! ./scripts/health-check.sh &>/dev/null; then
|
|
./scripts/send-alert.sh "Production health check failed"
|
|
fi
|
|
```
|
|
|
|
---
|
|
|
|
## Backup Script
|
|
|
|
**Location**: `scripts/backup.sh`
|
|
|
|
### Usage
|
|
|
|
```bash
|
|
# Full backup (database + vault + files)
|
|
./scripts/backup.sh --full
|
|
|
|
# Database only
|
|
./scripts/backup.sh --database-only
|
|
|
|
# Vault only
|
|
./scripts/backup.sh --vault-only
|
|
|
|
# Encrypted backup (GPG)
|
|
./scripts/backup.sh --full --encrypt
|
|
```
|
|
|
|
### Backup Components
|
|
|
|
1. **Database Backup**
|
|
- PostgreSQL dump via `pg_dump`
|
|
- Gzipped for compression
|
|
- Optional GPG encryption
|
|
|
|
2. **Vault Backup**
|
|
- Vault secrets table (`vault_secrets`)
|
|
- Vault audit table (`vault_audit`)
|
|
- **Encryption highly recommended**
|
|
|
|
3. **Environment Configuration**
|
|
- `.env.production` file backup
|
|
- Contains sensitive configuration
|
|
|
|
4. **Storage Directory**
|
|
- Logs, cache, queue, discovery, uploads
|
|
- Tar.gz compression
|
|
|
|
5. **Uploaded Files**
|
|
- `public/uploads/` directory
|
|
- Media and user-uploaded content
|
|
|
|
### Backup Process
|
|
|
|
```bash
|
|
./scripts/backup.sh --full --encrypt
|
|
```
|
|
|
|
**Output**:
|
|
```
|
|
[13:00:00] 🔐 Starting production backup (type: full)...
|
|
|
|
[13:00:01] Preparing backup directory...
|
|
✅ Backup directory created: /backups/20241025_130000
|
|
[13:00:02] Backing up database...
|
|
✅ Database backup created: database.sql.gz (245M)
|
|
[13:00:05] Encrypting /backups/20241025_130000/database.sql.gz...
|
|
✅ File encrypted: database.sql.gz.gpg
|
|
[13:00:10] Backing up Vault secrets...
|
|
✅ Vault backup created: vault_secrets.sql.gz (2.3M)
|
|
⚠️ Vault backup is not encrypted - consider using --encrypt
|
|
[13:00:12] Backing up environment configuration...
|
|
✅ Environment configuration backed up
|
|
[13:00:13] Backing up storage directory...
|
|
✅ Storage backup created: storage.tar.gz (120M)
|
|
[13:00:18] Backing up uploaded files...
|
|
✅ Uploads backup created: uploads.tar.gz (1.5G)
|
|
[13:00:45] Creating backup manifest...
|
|
✅ Backup manifest created
|
|
[13:00:46] Verifying backup integrity...
|
|
✓ database.sql.gz.gpg is valid
|
|
✓ storage.tar.gz is valid
|
|
✓ uploads.tar.gz is valid
|
|
✅ All backup files verified successfully
|
|
[13:00:47] Cleaning up old backups...
|
|
✅ Old backups cleaned up (kept last 7 days)
|
|
|
|
========================================
|
|
Backup Summary
|
|
========================================
|
|
|
|
📋 Backup Type: full
|
|
⏰ Timestamp: 2024-10-25 13:00:47
|
|
📁 Location: /backups/20241025_130000
|
|
🔒 Encrypted: true
|
|
|
|
📦 Backup Contents:
|
|
|
|
1.5G uploads.tar.gz
|
|
245M database.sql.gz.gpg
|
|
120M storage.tar.gz
|
|
2.3M vault_secrets.sql.gz
|
|
|
|
💾 Total Size: 1.9G
|
|
|
|
📝 Restoration Commands:
|
|
|
|
Database:
|
|
gpg -d database.sql.gz.gpg | gunzip | docker compose exec -T db psql -U postgres michaelschiemer_prod
|
|
|
|
Vault:
|
|
gunzip -c vault_secrets.sql.gz | docker compose exec -T db psql -U postgres michaelschiemer_prod
|
|
|
|
Storage:
|
|
tar -xzf storage.tar.gz -C /path/to/project
|
|
|
|
========================================
|
|
✅ 🎉 Backup completed successfully!
|
|
```
|
|
|
|
### Backup Encryption
|
|
|
|
GPG symmetric encryption (AES-256):
|
|
|
|
```bash
|
|
./scripts/backup.sh --full --encrypt
|
|
```
|
|
|
|
**What gets encrypted**:
|
|
- Database dumps
|
|
- Vault backups
|
|
- Environment configuration
|
|
|
|
**Decryption**:
|
|
```bash
|
|
# Decrypt file
|
|
gpg -d database.sql.gz.gpg > database.sql.gz
|
|
|
|
# Restore database
|
|
gunzip -c database.sql.gz | docker compose exec -T db psql -U postgres michaelschiemer_prod
|
|
```
|
|
|
|
**Encryption Password**:
|
|
- Prompted during backup
|
|
- **Store securely** in password manager
|
|
- Required for restoration
|
|
|
|
### Backup Retention
|
|
|
|
**Automatic Cleanup**:
|
|
- Backups older than 7 days are automatically deleted
|
|
- Keeps last 7 days of backups
|
|
- Configurable in script
|
|
|
|
**Manual Cleanup**:
|
|
```bash
|
|
# Remove specific backup
|
|
rm -rf /backups/20241025_130000
|
|
|
|
# Remove all backups older than 30 days
|
|
find /backups -type d -name "20*" -mtime +30 -exec rm -rf {} \;
|
|
```
|
|
|
|
### Backup Verification
|
|
|
|
All backups are automatically verified:
|
|
|
|
**Verification Checks**:
|
|
- Gzip integrity (`gzip -t`)
|
|
- Tar.gz integrity (`tar -tzf`)
|
|
- File completeness
|
|
|
|
**Failed Verification**:
|
|
```
|
|
✗ database.sql.gz is corrupted
|
|
❌ Some backup files are corrupted
|
|
```
|
|
|
|
### Restoration Procedures
|
|
|
|
**Full System Restoration**:
|
|
|
|
1. **Restore Database**:
|
|
```bash
|
|
cd /backups/20241025_130000
|
|
|
|
# If encrypted
|
|
gpg -d database.sql.gz.gpg | gunzip | docker compose exec -T db psql -U postgres michaelschiemer_prod
|
|
|
|
# If not encrypted
|
|
gunzip -c database.sql.gz | docker compose exec -T db psql -U postgres michaelschiemer_prod
|
|
```
|
|
|
|
2. **Restore Vault**:
|
|
```bash
|
|
gunzip -c vault_secrets.sql.gz | docker compose exec -T db psql -U postgres michaelschiemer_prod
|
|
```
|
|
|
|
3. **Restore Environment**:
|
|
```bash
|
|
cp env.production /path/to/project/.env.production
|
|
```
|
|
|
|
4. **Restore Storage**:
|
|
```bash
|
|
tar -xzf storage.tar.gz -C /path/to/project
|
|
```
|
|
|
|
5. **Restore Uploads**:
|
|
```bash
|
|
tar -xzf uploads.tar.gz -C /path/to/project/public
|
|
```
|
|
|
|
6. **Restart Services**:
|
|
```bash
|
|
docker compose -f docker-compose.yml -f docker-compose.production.yml --env-file .env.production restart
|
|
```
|
|
|
|
### Automated Backup Schedule
|
|
|
|
**Recommended Cron Jobs**:
|
|
|
|
```cron
|
|
# Daily full backup at 2 AM (encrypted)
|
|
0 2 * * * /path/to/scripts/backup.sh --full --encrypt >> /var/log/backup.log 2>&1
|
|
|
|
# Hourly database backup
|
|
0 * * * * /path/to/scripts/backup.sh --database-only >> /var/log/backup.log 2>&1
|
|
|
|
# Weekly Vault backup (encrypted)
|
|
0 3 * * 0 /path/to/scripts/backup.sh --vault-only --encrypt >> /var/log/backup.log 2>&1
|
|
```
|
|
|
|
**Backup Monitoring**:
|
|
```bash
|
|
# Check if backup succeeded
|
|
if ! tail -1 /var/log/backup.log | grep -q "completed successfully"; then
|
|
./scripts/send-alert.sh "Backup failed"
|
|
fi
|
|
```
|
|
|
|
---
|
|
|
|
## Integration with Production Workflow
|
|
|
|
### Complete Production Deployment Workflow
|
|
|
|
**Step 1: Initial Setup**
|
|
```bash
|
|
# Prerequisites
|
|
1. Configure .env.production with all required values
|
|
2. Generate VAULT_ENCRYPTION_KEY: docker exec php php console.php vault:generate-key
|
|
3. Update ADMIN_ALLOWED_IPS for IP-based access control
|
|
4. Configure SSL_DOMAIN and SSL_EMAIL for Let's Encrypt
|
|
|
|
# Deploy
|
|
./scripts/production-deploy.sh initial
|
|
```
|
|
|
|
**Step 2: Verify Deployment**
|
|
```bash
|
|
# Run health check
|
|
./scripts/health-check.sh --verbose
|
|
|
|
# Check logs
|
|
docker compose logs -f --tail=100
|
|
|
|
# Test application
|
|
curl -H "User-Agent: Mozilla/5.0" https://your-domain.com/health
|
|
```
|
|
|
|
**Step 3: Create Initial Backup**
|
|
```bash
|
|
# Full encrypted backup
|
|
./scripts/backup.sh --full --encrypt
|
|
```
|
|
|
|
**Step 4: Regular Updates**
|
|
```bash
|
|
# Zero-downtime update
|
|
./scripts/production-deploy.sh update
|
|
|
|
# Verify health
|
|
./scripts/health-check.sh
|
|
```
|
|
|
|
### Automated Operations
|
|
|
|
**Daily Operations Cron**:
|
|
```cron
|
|
# Health check every 5 minutes
|
|
*/5 * * * * /path/to/scripts/health-check.sh --json > /var/log/health-check.json
|
|
|
|
# Full backup daily at 2 AM
|
|
0 2 * * * /path/to/scripts/backup.sh --full --encrypt >> /var/log/backup.log 2>&1
|
|
|
|
# Cleanup old logs at 3 AM
|
|
0 3 * * * find /path/to/project/storage/logs -name "*.log" -mtime +30 -delete
|
|
```
|
|
|
|
### Monitoring Integration
|
|
|
|
**Prometheus Metrics** (from health-check.sh JSON output):
|
|
|
|
```yaml
|
|
# prometheus.yml
|
|
scrape_configs:
|
|
- job_name: 'health-check'
|
|
static_configs:
|
|
- targets: ['localhost:9090']
|
|
metrics_path: '/metrics'
|
|
file_sd_configs:
|
|
- files:
|
|
- '/var/log/health-check.json'
|
|
```
|
|
|
|
**Grafana Dashboard**:
|
|
- Service status panels
|
|
- Resource usage graphs
|
|
- Error rate trends
|
|
- SSL certificate expiry countdown
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Deployment Script Issues
|
|
|
|
**Problem**: Prerequisites check fails
|
|
```
|
|
❌ .env.production not found
|
|
```
|
|
**Solution**: Copy `.env.example` to `.env.production` and configure all values
|
|
|
|
**Problem**: Health check fails
|
|
```
|
|
❌ Health check failed after 30 attempts
|
|
```
|
|
**Solutions**:
|
|
1. Check Docker logs: `docker compose logs -f php`
|
|
2. Verify all services are up: `docker compose ps`
|
|
3. Check firewall: `sudo ufw status`
|
|
4. Verify DNS: `dig your-domain.com`
|
|
|
|
**Problem**: SSL initialization fails
|
|
```
|
|
❌ SSL initialization failed
|
|
```
|
|
**Solutions**:
|
|
1. Verify DNS A record points to server
|
|
2. Check ports 80/443 are open
|
|
3. Verify SSL_DOMAIN in .env.production
|
|
4. Check Certbot logs: `docker compose logs certbot`
|
|
|
|
### Health Check Script Issues
|
|
|
|
**Problem**: Web response check fails
|
|
```
|
|
❌ Web server is not responding
|
|
```
|
|
**Solutions**:
|
|
1. Check Nginx status: `docker compose ps web`
|
|
2. Check Nginx logs: `docker compose logs web`
|
|
3. Verify SSL certificates: `docker compose exec php php console.php ssl:status`
|
|
|
|
**Problem**: Database check fails
|
|
```
|
|
❌ Database is not accepting connections
|
|
```
|
|
**Solutions**:
|
|
1. Check PostgreSQL status: `docker compose ps db`
|
|
2. Check PostgreSQL logs: `docker compose logs db`
|
|
3. Verify database credentials in .env.production
|
|
|
|
### Backup Script Issues
|
|
|
|
**Problem**: Database backup fails
|
|
```
|
|
❌ Database backup failed
|
|
```
|
|
**Solutions**:
|
|
1. Check database container: `docker compose ps db`
|
|
2. Verify database credentials
|
|
3. Check disk space: `df -h`
|
|
|
|
**Problem**: GPG encryption fails
|
|
```
|
|
⚠️ GPG not installed - skipping encryption
|
|
```
|
|
**Solution**: Install GPG: `sudo apt install gnupg`
|
|
|
|
**Problem**: Backup verification fails
|
|
```
|
|
✗ database.sql.gz is corrupted
|
|
```
|
|
**Solutions**:
|
|
1. Run backup again
|
|
2. Check disk space
|
|
3. Verify database health
|
|
|
|
---
|
|
|
|
## Best Practices
|
|
|
|
### Deployment Best Practices
|
|
|
|
1. **Always test in staging first**
|
|
2. **Run health check before deployment**
|
|
3. **Create backup before updates**
|
|
4. **Monitor logs during deployment**
|
|
5. **Verify health after deployment**
|
|
6. **Have rollback plan ready**
|
|
7. **Document all configuration changes**
|
|
|
|
### Backup Best Practices
|
|
|
|
1. **Encrypt Vault backups** (always)
|
|
2. **Store backups off-site** (AWS S3, external server)
|
|
3. **Test restoration regularly** (monthly)
|
|
4. **Verify backup integrity** (automated)
|
|
5. **Monitor backup size growth**
|
|
6. **Rotate encryption passwords** (quarterly)
|
|
7. **Keep multiple backup copies** (3-2-1 rule: 3 copies, 2 media types, 1 off-site)
|
|
|
|
### Monitoring Best Practices
|
|
|
|
1. **Run health checks every 5 minutes**
|
|
2. **Alert on critical failures** (email, Slack, PagerDuty)
|
|
3. **Monitor resource usage trends**
|
|
4. **Track deployment success rate**
|
|
5. **Review logs daily**
|
|
6. **Set up uptime monitoring** (UptimeRobot, Pingdom)
|
|
7. **Document incident responses**
|
|
|
|
---
|
|
|
|
## See Also
|
|
|
|
- **Prerequisites**: `docs/deployment/production-prerequisites.md`
|
|
- **Environment Configuration**: `docs/deployment/env-production-template.md`
|
|
- **Docker Compose Production**: `docs/deployment/docker-compose-production.md`
|
|
- **Database Migrations**: `docs/deployment/database-migration-strategy.md`
|
|
- **SSL Setup**: `docs/deployment/ssl-setup.md`
|
|
- **Secrets Management**: `docs/deployment/secrets-management.md`
|
|
- **Logging Configuration**: `docs/deployment/logging-configuration.md`
|