chore: Update deployment configuration and documentation

- Update Gitea configuration (remove DEFAULT_ACTIONS_URL)
- Fix deployment documentation
- Update Ansible playbooks
- Clean up deprecated files
- Add new deployment scripts and templates
This commit is contained in:
2025-10-31 21:11:11 +01:00
parent cf4748f8db
commit 16d586ecdf
92 changed files with 4601 additions and 10524 deletions

View File

@@ -1,5 +1,15 @@
# Ansible-Based Deployment
⚠️ **WICHTIG:** Diese Dokumentation ist veraltet.
**Für aktuelle Ansible-Deployment-Dokumentation siehe:**
- **[deployment/ansible/README.md](../../deployment/ansible/README.md)** - Aktuelle Ansible-Dokumentation
- **[deployment/DEPLOYMENT_COMMANDS.md](../../deployment/DEPLOYMENT_COMMANDS.md)** - Command-Referenz
---
**Historische Dokumentation (veraltet):**
Fortgeschrittenes Deployment mit Ansible für Multi-Server Orchestrierung und Infrastructure as Code.
## Übersicht

View File

@@ -1,73 +0,0 @@
# 🚀 Production Deployment Guide
## Schneller Deployment-Workflow
### 1. Environment Setup (KRITISCH)
```bash
# Kopiere .env Template
cp .env.production .env
# Setze ALLE CHANGE_ME Werte:
nano .env
```
**WICHTIG:** Folgende Werte MÜSSEN gesetzt werden:
- `DB_PASSWORD` - Starkes Datenbankpasswort
- `SHOPIFY_WEBHOOK_SECRET` - Nur wenn Shopify verwendet wird
- `RAPIDMAIL_USERNAME/PASSWORD` - Nur wenn RapidMail verwendet wird
### 2. Database Setup
```bash
# 1. Datenbank erstellen
mysql -u root -p
CREATE DATABASE production_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'production_user'@'localhost' IDENTIFIED BY 'DEIN_PASSWORT';
GRANT ALL PRIVILEGES ON production_db.* TO 'production_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
# 2. Migration ausführen
mysql -u production_user -p production_db < migrations/2024_01_01_create_meta_entries_table.sql
```
### 3. Assets Build (falls Frontend verwendet)
```bash
npm install
npm run build
```
### 4. Basic Health Check
```bash
# Server starten und testen
php -S localhost:8000 -t public/
curl http://localhost:8000/
```
## Sicherheits-Checklist ✅
- [x] Keine hardcoded Secrets im Code
- [x] Starke Datenbankpasswörter
- [x] Production .env Template erstellt
- [x] Environment-basierte Konfiguration
## Next Steps (Optional)
1. **SSL Setup** - Let's Encrypt oder eigene Zertifikate
2. **Webserver Config** - nginx/Apache Konfiguration
3. **Process Manager** - PM2, systemd oder supervisor
4. **Monitoring** - Log-Aggregation und Error-Tracking
5. **Backup Strategy** - Automatische DB-Backups
## Rollback Strategy
Bei Problemen:
```bash
# 1. Alte Version aktivieren
git checkout previous-version
# 2. Assets neu bauen (falls nötig)
npm run build
# 3. Cache leeren
# (abhängig von Setup)
```

View File

@@ -1,374 +0,0 @@
# Production Deployment Checklist
**Print this and check off items as you complete them.**
---
## Pre-Deployment Checklist
### Infrastructure
- [ ] Server meets requirements (Ubuntu 22.04+, 4GB RAM, 40GB disk)
- [ ] Domain name configured and pointing to server IP
- [ ] DNS propagation verified (nslookup yourdomain.com)
- [ ] Firewall rules configured (ports 22, 80, 443 open)
- [ ] SSH access to server confirmed
- [ ] Root or sudo access verified
### Security
- [ ] SSH key pair generated
- [ ] SSH key added to server
- [ ] Vault encryption key generated
- [ ] Vault key stored in password manager
- [ ] Database passwords generated (32+ characters)
- [ ] JWT secrets generated (64+ characters)
- [ ] Admin allowed IPs list prepared
- [ ] SSL certificate email address ready
### Code
- [ ] Application repository accessible
- [ ] Production branch exists and tested
- [ ] All tests passing locally
- [ ] Database migrations reviewed
- [ ] .env.example up to date
- [ ] Dependencies reviewed (composer.json, package.json)
---
## Deployment Steps Checklist
### Step 1: Server Setup
- [ ] SSH into server
- [ ] System updated (apt update && upgrade)
- [ ] Docker installed
- [ ] Docker Compose installed
- [ ] Certbot installed
- [ ] Application user created
- [ ] Application user added to docker group
- [ ] Directory structure created (/var/www/app, /var/log/app, /opt/vault)
### Step 2: SSL Certificate
- [ ] Webroot directory created (/var/www/certbot)
- [ ] Certbot certificate obtained
- [ ] Certificate files verified (fullchain.pem, privkey.pem)
- [ ] Certificate expiration date checked (>30 days)
- [ ] Auto-renewal tested (certbot renew --dry-run)
### Step 3: Application Code
- [ ] Repository cloned to /home/appuser/app
- [ ] Production branch checked out
- [ ] Git configured (user.name, user.email)
- [ ] File permissions set correctly (chown -R appuser:appuser)
### Step 4: Environment Configuration
- [ ] .env.production created from .env.example
- [ ] APP_ENV set to "production"
- [ ] APP_DEBUG set to "false"
- [ ] APP_URL configured with domain
- [ ] Database credentials configured
- [ ] VAULT_ENCRYPTION_KEY added
- [ ] LOG_PATH configured
- [ ] ADMIN_ALLOWED_IPS configured
- [ ] All required environment variables set
- [ ] Sensitive values NOT committed to git
### Step 5: Docker Containers
- [ ] docker-compose.production.yml reviewed
- [ ] Containers built (docker compose build)
- [ ] Containers started (docker compose up -d)
- [ ] All containers running (docker compose ps)
- [ ] Container logs checked for errors
- [ ] Container networking verified
### Step 6: Database
- [ ] Database container healthy
- [ ] Database migrations applied (php console.php db:migrate)
- [ ] Migration status verified (php console.php db:status)
- [ ] Database backup created
- [ ] Database connection tested
### Step 7: Health Checks
- [ ] Health endpoint accessible (curl http://localhost/health/summary)
- [ ] All health checks passing (overall_healthy: true)
- [ ] Database health check: healthy
- [ ] Cache health check: healthy
- [ ] Queue health check: healthy
- [ ] Filesystem health check: healthy
- [ ] SSL health check: healthy
- [ ] Detailed health endpoint tested
### Step 8: Nginx Configuration
- [ ] Nginx installed
- [ ] Site configuration created (/etc/nginx/sites-available/app)
- [ ] SSL certificates paths correct in config
- [ ] Proxy settings configured
- [ ] Site enabled (symlink in sites-enabled)
- [ ] Nginx configuration tested (nginx -t)
- [ ] Nginx restarted
- [ ] HTTPS redirect working (http → https)
### Step 9: Application Verification
- [ ] HTTPS endpoint accessible (https://yourdomain.com)
- [ ] SSL certificate valid (no browser warnings)
- [ ] Homepage loads correctly
- [ ] API endpoints responding
- [ ] Authentication working
- [ ] Admin panel accessible (from allowed IPs)
- [ ] File uploads working
- [ ] Background jobs processing
- [ ] Email sending configured
### Step 10: Monitoring
- [ ] Metrics endpoint accessible (/metrics)
- [ ] Prometheus metrics valid format
- [ ] Health checks integrated with monitoring
- [ ] Log files being created (/var/log/app/)
- [ ] Log rotation configured
- [ ] Disk space monitored
- [ ] Memory usage monitored
- [ ] CPU usage monitored
---
## Post-Deployment Checklist
### Security Hardening
- [ ] UFW firewall enabled
- [ ] Only required ports open (22, 80, 443)
- [ ] SSH password authentication disabled
- [ ] Root login disabled via SSH
- [ ] Fail2Ban installed and configured
- [ ] Security headers verified (X-Frame-Options, CSP, etc.)
- [ ] OWASP security scan performed
- [ ] SSL Labs test passed (A+ rating)
### Backups
- [ ] Database backup script created
- [ ] Vault backup script created
- [ ] Backup directory created (/opt/backups)
- [ ] Backup cron job configured
- [ ] Backup restoration tested
- [ ] Backup retention policy configured (7 days)
- [ ] Off-site backup configured (optional but recommended)
### Monitoring & Alerts
- [ ] Grafana installed (optional)
- [ ] Prometheus configured (optional)
- [ ] Alert rules configured
- [ ] Email notifications configured
- [ ] Disk space alerts set (>90% usage)
- [ ] Memory alerts set (>90% usage)
- [ ] Health check alerts set
- [ ] SSL expiration alerts set (30 days)
### Documentation
- [ ] Deployment procedure documented
- [ ] Server credentials documented (in secure location)
- [ ] Vault encryption key documented (in secure location)
- [ ] Database backup location documented
- [ ] Rollback procedure documented
- [ ] Team access granted and documented
- [ ] On-call rotation documented
### Performance
- [ ] Performance baseline established
- [ ] Slow query log enabled
- [ ] Cache hit rate monitored
- [ ] Response time benchmarked
- [ ] Load testing performed
- [ ] Database indexes optimized
- [ ] Asset compression enabled (gzip)
- [ ] CDN configured (optional)
### Compliance & Legal
- [ ] Privacy policy deployed
- [ ] Terms of service deployed
- [ ] Cookie consent implemented (if EU traffic)
- [ ] GDPR compliance verified (if EU traffic)
- [ ] Data retention policies documented
- [ ] Incident response plan documented
---
## Rollback Checklist
**Use this if deployment fails and you need to rollback:**
### Immediate Rollback
- [ ] Stop new containers: `docker compose down`
- [ ] Start old containers: `docker compose -f docker-compose.old.yml up -d`
- [ ] Verify health: `curl http://localhost/health/summary`
- [ ] Rollback database migrations: `php console.php db:rollback`
- [ ] Clear cache: `php console.php cache:clear`
- [ ] Verify application functionality
- [ ] Notify team of rollback
### Post-Rollback
- [ ] Document rollback reason
- [ ] Identify root cause
- [ ] Create fix for issue
- [ ] Test fix in staging
- [ ] Plan next deployment attempt
- [ ] Update deployment procedure if needed
---
## Weekly Maintenance Checklist
**Perform these checks weekly:**
- [ ] Review application logs for errors
- [ ] Check disk space (should be <80%)
- [ ] Review health check status
- [ ] Verify backups running successfully
- [ ] Check SSL certificate expiration (>30 days remaining)
- [ ] Review security logs (fail2ban)
- [ ] Check for system updates
- [ ] Review performance metrics
- [ ] Test backup restoration (monthly)
---
## Monthly Maintenance Checklist
**Perform these checks monthly:**
- [ ] Apply system security updates
- [ ] Review and update dependencies (composer update, npm update)
- [ ] Rotate secrets (API keys, tokens) if required
- [ ] Review and archive old logs
- [ ] Perform security audit
- [ ] Review and update documentation
- [ ] Test disaster recovery procedure
- [ ] Review and optimize database performance
- [ ] Review monitoring alerts effectiveness
- [ ] Update deployment runbook with lessons learned
---
## Quarterly Maintenance Checklist
**Perform these checks quarterly:**
- [ ] Rotate Vault encryption key
- [ ] Rotate database passwords
- [ ] Review and update security policies
- [ ] Conduct penetration testing
- [ ] Review and optimize infrastructure costs
- [ ] Update disaster recovery plan
- [ ] Review team access and permissions
- [ ] Conduct deployment drill with team
- [ ] Review compliance requirements
- [ ] Update technical documentation
---
## Emergency Contacts
**Fill this in and keep it secure:**
```
Server Provider: _______________________
Support Phone: _________________________
Support Email: _________________________
Domain Registrar: ______________________
Support Phone: _________________________
Support Email: _________________________
SSL Provider: __________________________
Support Phone: _________________________
Support Email: _________________________
Database Backup Location: ______________
Vault Key Location: ____________________
SSH Key Location: ______________________
Team Lead: _____________________________
On-Call Phone: _________________________
DevOps Lead: ___________________________
On-Call Phone: _________________________
Security Contact: ______________________
Emergency Phone: _______________________
```
---
## Deployment Sign-Off
**Deployment Details:**
```
Date: _____________________
Deployed By: ______________
Version/Commit: ___________
Environment: Production
Deployment Method: [ ] Manual [ ] Script [ ] Ansible
Health Check Status: [ ] All Passing
SSL Certificate: [ ] Valid
Database Migrations: [ ] Applied
Backups: [ ] Verified
Issues During Deployment:
_____________________________________________
_____________________________________________
Post-Deployment Notes:
_____________________________________________
_____________________________________________
Signed: ___________________ Date: __________
```
---
## Continuous Improvement
After each deployment, answer these questions:
1. **What went well?**
- _______________________________________________
- _______________________________________________
2. **What could be improved?**
- _______________________________________________
- _______________________________________________
3. **What was unexpected?**
- _______________________________________________
- _______________________________________________
4. **Action items for next deployment:**
- _______________________________________________
- _______________________________________________
5. **Documentation updates needed:**
- _______________________________________________
- _______________________________________________
---
**Remember**: This checklist should be updated after each deployment to reflect lessons learned and process improvements.

View File

@@ -1,96 +0,0 @@
# Deployment System Restructuring Complete
## Summary
The deployment system has been successfully restructured from multiple scattered configurations into a modern, organized hybrid deployment system.
## What Was Done
### 1. Backup Creation
Created `.deployment-backup/` directory containing all old deployment files:
- `ansible/` - Multiple Ansible configurations (netcup-simple-deploy, nginx-cdn-germany, wireguard-server)
- `x_ansible/` - Alternative Ansible setup
- `ssl/` - SSL certificates for local development
- `bin/` - Deployment utility scripts
- `BACKUP_SUMMARY.md` - Detailed backup documentation
### 2. New Structure Creation
Created modern `deployment/` directory with four main components:
**Infrastructure** (`deployment/infrastructure/`)
- Ansible playbooks for server setup and management
- Environment-specific inventories
- Reusable roles for common tasks
- Configuration management via group_vars
**Applications** (`deployment/applications/`)
- Docker Compose configurations per environment
- Production, staging, and development setups
- Service orchestration and health monitoring
- Environment-specific optimizations
**Scripts** (`deployment/scripts/`)
- Automated deployment orchestration
- Setup, rollback, and utility scripts
- Health checking and monitoring tools
- Integration with infrastructure and applications
**Configs** (`deployment/configs/`)
- Configuration templates for all services
- Nginx, PHP, MySQL, and SSL configurations
- Environment-specific template variables
- Monitoring and logging configurations
## Key Improvements
**Separation of Concerns**: Clear distinction between infrastructure and application deployment
**Environment Management**: Dedicated configurations for production, staging, development
**Docker Integration**: Full containerization with Docker Compose
**Automation**: Streamlined deployment workflows
**Configuration Management**: Centralized template system
**Documentation**: Comprehensive README files for each component
## Next Steps
1. **Infrastructure Setup** (`deployment/infrastructure/`)
- Create Ansible inventories for environments
- Develop server setup playbooks
- Configure security and Docker roles
2. **Application Configuration** (`deployment/applications/`)
- Create environment-specific Docker Compose files
- Configure service networking and volumes
- Set up health checks and monitoring
3. **Script Development** (`deployment/scripts/`)
- Implement main deployment orchestration script
- Create setup and rollback automation
- Develop health monitoring tools
4. **Configuration Templates** (`deployment/configs/`)
- Create Nginx configuration templates
- Set up SSL certificate management
- Configure environment file templates
## Migration Benefits
- **Maintainability**: Organized, documented structure
- **Scalability**: Easy to add new environments or services
- **Reliability**: Automated testing and rollback capabilities
- **Security**: Modern security practices and SSL management
- **Consistency**: Standardized deployment across environments
## Rollback Option
If needed, the old system can be quickly restored by moving files back from `.deployment-backup/` to their original locations. See `BACKUP_SUMMARY.md` for detailed instructions.
## Framework Integration
The new deployment system is specifically designed for the Custom PHP Framework with:
- HTTPS-first configuration (framework requirement)
- Docker-based architecture (current setup)
- Production server targeting (94.16.110.151 with deploy user)
- SSL certificate automation for framework's HTTPS requirement
- Health check integration with framework's built-in endpoints
This modern deployment system provides a solid foundation for reliable, automated deployment of the Custom PHP Framework across all environments.

View File

@@ -1,568 +0,0 @@
# Production Deployment Infrastructure - Summary
**Project**: Custom PHP Framework
**Status**: ✅ Complete
**Date**: January 2025
---
## Overview
Complete production deployment infrastructure has been implemented for the Custom PHP Framework, providing multiple deployment paths from quick manual setup to fully automated infrastructure as code.
---
## Completed Components
### 1. Health Check & Monitoring System ✅
**Location**: `src/Application/Health/`, `src/Application/Metrics/`
**Features**:
- Multiple health check endpoints for different use cases
- Automatic health check discovery via attributes
- Prometheus-compatible metrics endpoint
- Real-time performance monitoring
- Health check categories (Database, Cache, Security, Infrastructure)
**Endpoints**:
```
GET /health/summary - Quick health overview
GET /health/detailed - Comprehensive health report
GET /health/checks - List all registered checks
GET /health/category/{cat} - Category-specific checks
GET /metrics - Prometheus metrics
GET /metrics/json - JSON metrics
```
**Health Checks Implemented**:
- ✅ Database connectivity and performance
- ✅ Cache system health (Redis/File)
- ✅ Queue system monitoring
- ✅ SSL certificate validity (30-day warning, 7-day critical)
- ✅ Disk space monitoring
- ✅ Memory usage monitoring
- ✅ Vault availability
---
### 2. Production Logging Configuration ✅
**Location**: `src/Framework/Logging/ProductionLogConfig.php`
**Available Configurations**:
| Configuration | Use Case | Performance | Volume Reduction |
|---------------|----------|-------------|------------------|
| **production()** | Standard production | 10K+ logs/sec | Baseline |
| **highPerformance()** | High traffic (>100 req/s) | 50K+ logs/sec | 80-90% |
| **productionWithAggregation()** | Repetitive patterns | 20K+ logs/sec | 70-90% |
| **debug()** | Temporary troubleshooting | 2-3ms latency | N/A (verbose) |
| **staging()** | Pre-production testing | Standard | N/A |
**Features**:
- Resilient logging with automatic fallback
- Buffered writes for performance (100 entries, 5s flush)
- 14-day rotating log files
- Structured JSON logs with request/trace context
- Intelligent sampling and aggregation
- Integration with Prometheus metrics
**Documentation**: [production-logging.md](production-logging.md)
---
### 3. Deployment Documentation Suite ✅
Six comprehensive guides covering all deployment scenarios:
#### 3.1. Quick Start Guide
**File**: [QUICKSTART.md](QUICKSTART.md)
**Purpose**: Get to production in 30 minutes
**Target**: First-time deployment, quick setup
**Contents**:
- 10-step deployment process
- Minimal configuration required
- SSL certificate automation
- Vault key generation
- Database initialization
- Health verification
- Basic troubleshooting
#### 3.2. Deployment Checklist
**File**: [DEPLOYMENT_CHECKLIST.md](DEPLOYMENT_CHECKLIST.md)
**Purpose**: Ensure nothing is missed
**Target**: Compliance verification, team coordination
**Contents**:
- Pre-deployment checklist (Infrastructure, Security, Code)
- Step-by-step deployment verification
- Post-deployment security hardening
- Maintenance schedules (weekly, monthly, quarterly)
- Emergency contacts template
- Deployment sign-off form
- Continuous improvement framework
#### 3.3. Complete Deployment Workflow
**File**: [DEPLOYMENT_WORKFLOW.md](DEPLOYMENT_WORKFLOW.md)
**Purpose**: Detailed deployment lifecycle
**Target**: Understanding complete process
**Contents**:
- **Phase 1**: Initial Server Setup (one-time)
- Server preparation
- SSL certificate with Let's Encrypt
- Vault key generation
- Environment configuration
- **Phase 2**: Initial Deployment
- Docker container setup
- Database migrations
- Health check verification
- Nginx reverse proxy
- **Phase 3**: Ongoing Deployment
- Automated deployment scripts
- Zero-downtime deployment
- Manual deployment steps
- **Phase 4**: Monitoring Setup
- Prometheus and Grafana
- Alerting configuration
#### 3.4. Production Deployment Guide
**File**: [PRODUCTION_DEPLOYMENT.md](PRODUCTION_DEPLOYMENT.md)
**Purpose**: Comprehensive infrastructure reference
**Target**: Deep technical details
**Contents**:
- Complete infrastructure setup
- SSL/TLS configuration
- Secrets management with Vault
- Docker deployment
- Database migration strategy
- All monitoring endpoints documented
- Logging configuration
- Security best practices
- Comprehensive troubleshooting
- Rollback procedures
- Maintenance tasks
#### 3.5. Production Logging Guide
**File**: [production-logging.md](production-logging.md)
**Purpose**: Logging configuration and optimization
**Target**: Production logging setup
**Contents**:
- All ProductionLogConfig options explained
- Environment-based configuration
- Log rotation and retention policies
- Structured JSON format
- Metrics integration
- Performance tuning guidelines
- Troubleshooting common issues
- Best practices
#### 3.6. Ansible Deployment Guide
**File**: [ANSIBLE_DEPLOYMENT.md](ANSIBLE_DEPLOYMENT.md)
**Purpose**: Infrastructure as Code automation
**Target**: Multi-server, enterprise deployments
**Contents**:
- Complete Ansible project structure
- Ansible roles (common, docker, ssl, application)
- Playbooks (site.yml, deploy.yml, rollback.yml, provision.yml)
- Ansible Vault for secrets
- CI/CD integration (GitHub Actions)
- Comparison: Script-Based vs Ansible
- Hybrid approach recommendation
#### 3.7. Deployment README
**File**: [README.md](README.md)
**Purpose**: Navigation and quick reference
**Target**: All deployment scenarios
**Contents**:
- Document overview and navigation
- Which guide for which scenario
- Deployment methods comparison
- Common tasks quick reference
- Troubleshooting quick reference
- Support resources
---
## Deployment Options
### Option 1: Quick Start (Recommended for First Deployment)
**Time**: 30 minutes
**Best For**: Single server, getting started
**Guide**: [QUICKSTART.md](QUICKSTART.md)
**Process**:
1. Server setup (10 min)
2. SSL certificate (5 min)
3. Clone application (2 min)
4. Generate secrets (3 min)
5. Create environment file (5 min)
6. Build and start containers (3 min)
7. Initialize database (2 min)
### Option 2: Script-Based Deployment
**Time**: 2 hours initial, 10 minutes ongoing
**Best For**: Single server, repeatable deployments
**Guide**: [DEPLOYMENT_WORKFLOW.md](DEPLOYMENT_WORKFLOW.md)
**Features**:
- Automated deployment scripts
- Zero-downtime blue-green deployment
- Rollback support
- Health check integration
**Scripts**:
- `scripts/deployment/deploy-production.sh` - Standard deployment
- `scripts/deployment/blue-green-deploy.sh` - Zero-downtime deployment
- `scripts/deployment/blue-green-rollback.sh` - Safe rollback
### Option 3: Ansible Automation
**Time**: 4 hours initial, 5 minutes ongoing
**Best For**: Multiple servers, enterprise deployments
**Guide**: [ANSIBLE_DEPLOYMENT.md](ANSIBLE_DEPLOYMENT.md)
**Features**:
- Infrastructure as Code
- Multi-server orchestration
- Idempotent operations
- Automated rollback
- CI/CD integration
**Roles**:
- **common**: System packages, firewall, directories
- **docker**: Docker installation and configuration
- **ssl**: Certificate management with auto-renewal
- **application**: Git, composer, migrations, health checks
---
## Infrastructure Components
### SSL/TLS Management
- ✅ Let's Encrypt integration
- ✅ Automatic certificate renewal
- ✅ 30-day expiration warning
- ✅ 7-day critical alert
- ✅ Health check integration
### Secrets Management
- ✅ Vault encryption key generation
- ✅ Encrypted secrets storage
- ✅ Environment-based configuration
- ✅ Key rotation procedures
### Docker Infrastructure
- ✅ Production-ready docker-compose configuration
- ✅ Container health checks
- ✅ Resource limits and constraints
- ✅ Logging configuration
- ✅ Network isolation
### Database Management
- ✅ Migration system with safe rollback architecture
- ✅ Forward-only migrations by default
- ✅ Optional SafelyReversible interface
- ✅ Fix-forward strategy for unsafe changes
- ✅ Automated migration execution
### Reverse Proxy
- ✅ Nginx configuration
- ✅ SSL/TLS termination
- ✅ Proxy headers
- ✅ Health check routing
- ✅ Static asset serving
---
## Security Features
### Web Application Firewall (WAF)
- ✅ SQL injection detection
- ✅ XSS protection
- ✅ Path traversal prevention
- ✅ Command injection detection
- ✅ Rate limiting
- ✅ Suspicious user agent blocking
### Security Headers
- ✅ X-Frame-Options: SAMEORIGIN
- ✅ X-Content-Type-Options: nosniff
- ✅ X-XSS-Protection: 1; mode=block
- ✅ Strict-Transport-Security (HSTS)
- ✅ Content-Security-Policy (CSP)
- ✅ Referrer-Policy
- ✅ Permissions-Policy
### Authentication & Authorization
- ✅ IP-based authentication for admin routes
- ✅ Session-based authentication
- ✅ Token-based authentication
- ✅ CSRF protection
- ✅ Rate limiting
### Hardening
- ✅ UFW firewall configuration
- ✅ SSH key-only authentication
- ✅ Fail2Ban integration
- ✅ Regular security updates
- ✅ OWASP security event logging
---
## Monitoring & Observability
### Health Checks
- ✅ Multiple endpoints for different use cases
- ✅ Category-based filtering
- ✅ Automatic service discovery
- ✅ Response time tracking
- ✅ Detailed error reporting
### Metrics
- ✅ Prometheus-compatible metrics
- ✅ Health check metrics
- ✅ Performance metrics
- ✅ Resource utilization metrics
- ✅ Custom business metrics
### Logging
- ✅ Structured JSON logs
- ✅ Request ID tracing
- ✅ Distributed tracing support
- ✅ Performance metrics
- ✅ Error aggregation
### Alerting
- ✅ Prometheus alert rules
- ✅ Health check failure alerts
- ✅ Disk space alerts
- ✅ SSL expiration alerts
- ✅ Custom alert rules
---
## Performance Characteristics
### Health Check Performance
- **Response Time**: <100ms for summary endpoint
- **Detailed Check**: <500ms with all checks
- **Throughput**: 1000+ requests/second
- **Timeout Protection**: Configurable per-check timeouts
### Logging Performance
- **Standard Production**: 10,000+ logs/second
- **High Performance**: 50,000+ logs/second (with sampling)
- **Write Latency**: <1ms (buffered)
- **Disk I/O**: Minimized via buffering and rotation
### Deployment Performance
- **Manual Deployment**: ~15 minutes
- **Automated Deployment**: ~5-10 minutes
- **Zero-Downtime Deployment**: ~10-15 minutes
- **Rollback**: ~5 minutes
---
## Testing & Validation
### Pre-Deployment Testing
- ✅ Unit tests passing
- ✅ Integration tests passing
- ✅ Migration tests
- ✅ Health check tests
- ✅ Security tests
### Deployment Verification
- ✅ Container health checks
- ✅ Application health endpoints
- ✅ SSL certificate validation
- ✅ Database migration verification
- ✅ Performance baseline
### Post-Deployment Monitoring
- ✅ Health check monitoring
- ✅ Metrics collection
- ✅ Log aggregation
- ✅ Alert verification
- ✅ User acceptance testing
---
## Maintenance Procedures
### Weekly Maintenance
- Review application logs
- Check disk space (<80%)
- Verify health check status
- Verify backups
- Check SSL certificate (>30 days)
- Review security logs
### Monthly Maintenance
- Apply system security updates
- Update dependencies
- Rotate secrets if required
- Review and archive logs
- Security audit
- Database optimization
### Quarterly Maintenance
- Rotate Vault encryption key
- Rotate database passwords
- Penetration testing
- Infrastructure cost review
- Disaster recovery drill
- Team training
---
## Rollback & Disaster Recovery
### Rollback Procedures
- ✅ Blue-green deployment rollback
- ✅ Database migration rollback (safe migrations)
- ✅ Fix-forward strategy (unsafe migrations)
- ✅ Container version rollback
- ✅ Configuration rollback
### Disaster Recovery
- ✅ Automated database backups (daily)
- ✅ Vault backup procedures
- ✅ Configuration backups
- ✅ Off-site backup storage
- ✅ Recovery testing procedures
---
## Documentation Highlights
### Comprehensive Coverage
- 6 deployment guides totaling 140+ pages
- Step-by-step instructions for all scenarios
- Troubleshooting guides for common issues
- Best practices and recommendations
- Security considerations
- Performance tuning guidelines
### Accessibility
- Quick start for fast deployment (30 min)
- Detailed guides for deep understanding
- Printable checklists for verification
- Navigation guide for finding information
- Cross-references between documents
### Maintainability
- Continuous improvement framework
- Post-deployment feedback template
- Lessons learned documentation
- Version history tracking
- Regular update procedures
---
## Team Readiness
### Documentation
- ✅ Complete deployment documentation
- ✅ Troubleshooting guides
- ✅ Runbooks for common operations
- ✅ Emergency procedures
- ✅ Contact information templates
### Training Materials
- ✅ Quick start guide for new team members
- ✅ Detailed workflow documentation
- ✅ Video walkthrough opportunities
- ✅ FAQ sections
- ✅ Best practices documentation
### Support
- ✅ Internal documentation references
- ✅ External resource links
- ✅ Community support channels
- ✅ Escalation procedures
- ✅ On-call rotation guidelines
---
## Next Steps
### Recommended Actions
1. **First Deployment**: Follow [QUICKSTART.md](QUICKSTART.md)
2. **Team Review**: Distribute [DEPLOYMENT_README.md](README.md) to team
3. **Production Deploy**: Schedule deployment using deployment checklist
4. **Monitoring Setup**: Configure Prometheus/Grafana (Phase 4 in workflow)
5. **Security Hardening**: Complete post-deployment security checklist
6. **Team Training**: Conduct deployment drill with team
7. **Documentation Review**: Schedule quarterly documentation updates
### Future Enhancements
**Potential additions** (not required for production):
- Kubernetes deployment option (for larger scale)
- Multi-region deployment strategies
- Advanced monitoring dashboards
- Automated security scanning integration
- Performance testing automation
- Chaos engineering practices
---
## Success Metrics
### Deployment Success
- ✅ All health checks passing
- ✅ SSL certificate valid
- ✅ Zero errors in logs
- ✅ Metrics collecting correctly
- ✅ Backups running successfully
### Operational Success
- ⏱️ Deployment time: <30 minutes (target)
- 🎯 Uptime: 99.9% (target)
- ⚡ Response time: <200ms (target)
- 🔒 Security: Zero critical vulnerabilities
- 📊 Monitoring: 100% coverage
---
## Conclusion
The Custom PHP Framework now has **production-ready deployment infrastructure** with:
**Multiple deployment paths** (Quick, Script-Based, Ansible)
**Comprehensive monitoring** (Health checks, Metrics, Logging)
**Security hardening** (WAF, SSL, Vault, Headers)
**Zero-downtime deployments** (Blue-green strategy)
**Safe rollback procedures** (Migration architecture)
**Complete documentation** (6 comprehensive guides)
**Team readiness** (Checklists, runbooks, procedures)
**The infrastructure is ready for production deployment.**
---
## Quick Reference
| Need | Document | Time |
|------|----------|------|
| Deploy now | [QUICKSTART.md](QUICKSTART.md) | 30 min |
| Understand process | [DEPLOYMENT_WORKFLOW.md](DEPLOYMENT_WORKFLOW.md) | 2 hours |
| Deep technical details | [PRODUCTION_DEPLOYMENT.md](PRODUCTION_DEPLOYMENT.md) | Reference |
| Logging setup | [production-logging.md](production-logging.md) | 30 min |
| Automation | [ANSIBLE_DEPLOYMENT.md](ANSIBLE_DEPLOYMENT.md) | 4 hours |
| Verification | [DEPLOYMENT_CHECKLIST.md](DEPLOYMENT_CHECKLIST.md) | Ongoing |
| Navigation | [README.md](README.md) | Reference |
---
**For questions or support, see [README.md](README.md) → Support and Resources**
**Ready to deploy? → [QUICKSTART.md](QUICKSTART.md)**

View File

@@ -1,720 +0,0 @@
# Concrete Deployment Workflow
Schritt-für-Schritt Anleitung für das Production Deployment mit und ohne Ansible.
## Deployment-Optionen
Das Framework bietet **zwei Deployment-Strategien**:
1. **Manual/Script-Based** (einfach, für Single-Server)
2. **Ansible-Based** (automatisiert, für Multi-Server)
Beide Strategien nutzen Docker Compose als Container-Orchestrierung.
---
## Option 1: Manual/Script-Based Deployment (Empfohlen für Start)
### Voraussetzungen
- Server mit Ubuntu 22.04 LTS
- SSH-Zugriff mit sudo-Rechten
- Domain mit DNS konfiguriert
- Git Repository Access
### Phase 1: Initiales Server Setup (Einmalig)
#### 1.1 Server vorbereiten
```bash
# SSH-Verbindung zum Server
ssh user@your-server.com
# System aktualisieren
sudo apt update && sudo apt upgrade -y
# Docker installieren
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
# Docker Compose installieren
sudo apt install -y docker-compose-plugin
# Neuanmeldung für Docker-Gruppe
exit
ssh user@your-server.com
# Verify
docker --version
docker compose version
```
#### 1.2 Projektverzeichnisse erstellen
```bash
# Verzeichnisstruktur anlegen
sudo mkdir -p /var/www/app
sudo mkdir -p /var/log/app
sudo mkdir -p /opt/vault
sudo mkdir -p /etc/ssl/app
sudo mkdir -p /backups/database
sudo mkdir -p /backups/volumes
# Berechtigungen setzen
sudo chown -R $USER:$USER /var/www/app
sudo chown -R www-data:www-data /var/log/app
sudo chown -R www-data:www-data /opt/vault
sudo chmod 755 /var/www/app
sudo chmod 755 /var/log/app
sudo chmod 700 /opt/vault
```
#### 1.3 Repository klonen
```bash
cd /var/www
git clone git@github.com:yourusername/app.git
cd app
# Production branch
git checkout production
# Scripts ausführbar machen
chmod +x scripts/deployment/*.sh
```
#### 1.4 SSL-Zertifikat einrichten
```bash
# Nginx für Certbot installieren
sudo apt install -y nginx certbot python3-certbot-nginx
# Temporäre Nginx-Config für Certbot
sudo tee /etc/nginx/sites-available/temp-certbot > /dev/null <<'EOF'
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
}
EOF
sudo ln -s /etc/nginx/sites-available/temp-certbot /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
# Zertifikat holen
sudo certbot certonly --webroot \
-w /var/www/certbot \
-d yourdomain.com \
-d www.yourdomain.com \
--email your-email@example.com \
--agree-tos \
--no-eff-email
# Zertifikate für Container verfügbar machen
sudo cp /etc/letsencrypt/live/yourdomain.com/fullchain.pem /etc/ssl/app/cert.pem
sudo cp /etc/letsencrypt/live/yourdomain.com/privkey.pem /etc/ssl/app/key.pem
sudo chmod 644 /etc/ssl/app/cert.pem
sudo chmod 600 /etc/ssl/app/key.pem
# Auto-Renewal einrichten
echo "0 3 * * * root certbot renew --quiet && cp /etc/letsencrypt/live/yourdomain.com/fullchain.pem /etc/ssl/app/cert.pem && cp /etc/letsencrypt/live/yourdomain.com/privkey.pem /etc/ssl/app/key.pem && docker compose -f /var/www/app/docker-compose.production.yml restart nginx" | sudo tee -a /etc/crontab
```
#### 1.5 Vault Encryption Key generieren
```bash
cd /var/www/app
# Key generieren
php scripts/deployment/generate-vault-key.php
# Output kopieren (sicher speichern!):
# VAULT_ENCRYPTION_KEY=base64encodedkey...
# In 1Password, Bitwarden, oder AWS Secrets Manager speichern
```
#### 1.6 Environment File erstellen
```bash
cd /var/www/app
# Template kopieren
cp .env.example .env.production
# Mit echten Production-Werten füllen
nano .env.production
```
**Minimal erforderliche Werte**:
```env
# Application
APP_ENV=production
APP_DEBUG=false
APP_URL=https://yourdomain.com
# Database
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=app_production
DB_USERNAME=app_user
DB_PASSWORD=<strong-database-password>
# Cache & Queue
CACHE_DRIVER=redis
QUEUE_DRIVER=redis
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=<strong-redis-password>
# Vault
VAULT_ENCRYPTION_KEY=<from-generate-vault-key>
# Admin Access
ADMIN_ALLOWED_IPS=your.ip.address.here
# Logging
LOG_PATH=/var/log/app
LOG_LEVEL=info
```
#### 1.7 Secrets in Vault speichern
```bash
# Secrets-Setup Script ausführen
php scripts/deployment/setup-production-secrets.php
# Manuelle Secrets hinzufügen
docker compose -f docker-compose.production.yml run --rm php php -r "
require 'vendor/autoload.php';
\$vault = new App\Framework\Vault\EncryptedVault(
\$_ENV['VAULT_ENCRYPTION_KEY'],
'/opt/vault/production.vault'
);
// API Keys
\$vault->set(
App\Framework\Vault\SecretKey::from('stripe_secret_key'),
App\Framework\Vault\SecretValue::from('sk_live_...')
);
// Mail Password
\$vault->set(
App\Framework\Vault\SecretKey::from('mail_password'),
App\Framework\Vault\SecretValue::from('your-mail-password')
);
echo 'Secrets stored successfully\n';
"
```
### Phase 2: Initiales Deployment
#### 2.1 Dependencies installieren
```bash
cd /var/www/app
# Composer Dependencies
docker compose -f docker-compose.production.yml run --rm php composer install --no-dev --optimize-autoloader
# NPM Dependencies und Build
docker compose -f docker-compose.production.yml run --rm nodejs npm ci
docker compose -f docker-compose.production.yml run --rm nodejs npm run build
```
#### 2.2 Container starten
```bash
# Docker Images bauen
docker compose -f docker-compose.production.yml build
# Container starten
docker compose -f docker-compose.production.yml up -d
# Logs verfolgen
docker compose -f docker-compose.production.yml logs -f
```
#### 2.3 Datenbank initialisieren
```bash
# Warten bis MySQL ready ist
sleep 30
# Migrations ausführen
docker compose -f docker-compose.production.yml exec php php console.php db:migrate
# Verify
docker compose -f docker-compose.production.yml exec php php console.php db:status
```
#### 2.4 Health Checks verifizieren
```bash
# Health Check (sollte 200 zurückgeben)
curl -f http://localhost/health || echo "Health check failed"
# Detailed Health Report
curl -s http://localhost/health/detailed | jq
# Alle Checks sollten "healthy" sein
curl -s http://localhost/health/summary | jq '.summary'
```
#### 2.5 Nginx Reverse Proxy konfigurieren
```bash
# System Nginx als Reverse Proxy
sudo tee /etc/nginx/sites-available/app > /dev/null <<'EOF'
upstream app_backend {
server localhost:8080;
}
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
# Redirect HTTP to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.com www.yourdomain.com;
ssl_certificate /etc/ssl/app/cert.pem;
ssl_certificate_key /etc/ssl/app/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Security Headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# Proxy to Docker container
location / {
proxy_pass http://app_backend;
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;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# Increase timeouts for long-running requests
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
EOF
# Enable site
sudo ln -sf /etc/nginx/sites-available/app /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
sudo rm -f /etc/nginx/sites-enabled/temp-certbot
# Test config
sudo nginx -t
# Reload
sudo systemctl reload nginx
```
#### 2.6 Finaler Test
```bash
# HTTPS Health Check
curl -f https://yourdomain.com/health || echo "HTTPS health check failed"
# SSL Test
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com < /dev/null
# Metrics
curl https://yourdomain.com/metrics | head -20
# Homepage
curl -I https://yourdomain.com
```
### Phase 3: Laufendes Deployment (Updates)
#### 3.1 Automatisches Deployment Script nutzen
```bash
cd /var/www/app
# Standard Deployment
./scripts/deployment/deploy-production.sh
# Mit spezifischem Branch
./scripts/deployment/deploy-production.sh --branch production-v2.1.0
# Dry-Run (keine Änderungen)
./scripts/deployment/deploy-production.sh --dry-run
```
Das Script führt automatisch aus:
1. ✅ Pre-deployment Checks
2. ✅ Backup Erstellung
3. ✅ Git Pull
4. ✅ Composer/NPM Install
5. ✅ Docker Image Build
6. ✅ Database Migrations
7. ✅ Container Restart
8. ✅ Health Checks
9. ✅ Smoke Tests
#### 3.2 Zero-Downtime Deployment (Blue-Green)
```bash
# Blue-Green Deployment für Zero-Downtime
./scripts/deployment/blue-green-deploy.sh
# Bei Problemen: Rollback
./scripts/deployment/blue-green-rollback.sh
```
#### 3.3 Manuelles Deployment (wenn Scripts nicht verfügbar)
```bash
cd /var/www/app
# 1. Pre-Deployment Backup
docker compose -f docker-compose.production.yml exec db \
mysqldump -u app_user -p<password> app_production \
> /backups/database/backup_$(date +%Y%m%d_%H%M%S).sql
# 2. Git Pull
git fetch origin production
git checkout production
git pull origin production
# 3. Dependencies aktualisieren
docker compose -f docker-compose.production.yml run --rm php \
composer install --no-dev --optimize-autoloader
# 4. Frontend Build (falls geändert)
docker compose -f docker-compose.production.yml run --rm nodejs npm ci
docker compose -f docker-compose.production.yml run --rm nodejs npm run build
# 5. Images neu bauen
docker compose -f docker-compose.production.yml build
# 6. Migrations ausführen
docker compose -f docker-compose.production.yml exec php php console.php db:migrate
# 7. Container neu starten
docker compose -f docker-compose.production.yml up -d --no-deps --build php nginx
# 8. Health Check
curl -f https://yourdomain.com/health/summary
# 9. Logs prüfen
docker compose -f docker-compose.production.yml logs -f --tail=100 php
```
### Phase 4: Monitoring Setup
#### 4.1 Prometheus (Optional)
```yaml
# docker-compose.monitoring.yml erstellen
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
restart: unless-stopped
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
volumes:
- grafana-data:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=<strong-password>
restart: unless-stopped
volumes:
prometheus-data:
grafana-data:
```
```yaml
# prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'app'
static_configs:
- targets: ['app-nginx:80']
metrics_path: '/metrics'
```
```bash
# Monitoring starten
docker compose -f docker-compose.monitoring.yml up -d
# Grafana öffnen: http://your-server:3000
# Login: admin / <strong-password>
# Dashboard importieren: docs/deployment/grafana-dashboard.json
```
#### 4.2 Alerting (Optional)
```bash
# Simple Alert Script für kritische Health Checks
tee /opt/health-check-alert.sh > /dev/null <<'EOF'
#!/bin/bash
HEALTH=$(curl -s http://localhost/health/summary | jq -r '.overall_healthy')
if [ "$HEALTH" != "true" ]; then
# Alert senden (Email, Slack, PagerDuty, etc.)
curl -X POST https://hooks.slack.com/services/YOUR/WEBHOOK/URL \
-H 'Content-Type: application/json' \
-d '{"text":"🚨 Production Health Check FAILED!"}'
fi
EOF
chmod +x /opt/health-check-alert.sh
# Crontab: Jede 5 Minuten prüfen
echo "*/5 * * * * /opt/health-check-alert.sh" | crontab -
```
---
## Option 2: Ansible-Based Deployment (Multi-Server)
### Wann Ansible verwenden?
**Verwende Ansible wenn**:
- Mehrere Production Server (Load Balancing)
- Staging + Production Environments
- Infrastructure as Code gewünscht
- Wiederholbare, idempotente Deployments
- Team-basierte Deployments
**Ansible NICHT notwendig wenn**:
- Einzelner Production Server
- Einfache Infrastruktur
- Kleine Team-Größe
- Docker Compose Scripts ausreichend
### Ansible Setup
Siehe separate Dokumentation: [ANSIBLE_DEPLOYMENT.md](ANSIBLE_DEPLOYMENT.md)
**Kurzübersicht**:
```bash
# Ansible installieren
pip install ansible
# Playbooks ausführen
cd ansible
ansible-playbook -i inventory/production site.yml
# Spezifische Playbooks
ansible-playbook -i inventory/production playbooks/deploy.yml
ansible-playbook -i inventory/production playbooks/rollback.yml
```
---
## Deployment-Checkliste
### Pre-Deployment
- [ ] Server vorbereitet und zugänglich
- [ ] Domain DNS konfiguriert
- [ ] SSL-Zertifikat vorhanden
- [ ] Vault Encryption Key generiert und sicher gespeichert
- [ ] Environment File `.env.production` erstellt
- [ ] Secrets in Vault gespeichert
- [ ] Docker und Docker Compose installiert
- [ ] Nginx Reverse Proxy konfiguriert
### Initial Deployment
- [ ] Repository geklont
- [ ] Dependencies installiert
- [ ] Docker Images gebaut
- [ ] Container gestartet
- [ ] Datenbank migriert
- [ ] Health Checks grün
- [ ] HTTPS funktioniert
- [ ] Monitoring konfiguriert (optional)
### Laufendes Deployment
- [ ] Backup erstellt
- [ ] Git Pull erfolgreich
- [ ] Dependencies aktualisiert
- [ ] Frontend gebaut (falls nötig)
- [ ] Images neu gebaut
- [ ] Migrations ausgeführt
- [ ] Container neu gestartet
- [ ] Health Checks grün
- [ ] Smoke Tests erfolgreich
- [ ] Logs geprüft
### Post-Deployment
- [ ] Application erreichbar
- [ ] Alle Features funktional
- [ ] Performance akzeptabel
- [ ] Monitoring aktiv
- [ ] Logs rotieren
- [ ] Backups funktionieren
- [ ] Rollback-Plan getestet
---
## Rollback-Prozedur
### Quick Rollback
```bash
cd /var/www/app
# 1. Zu vorherigem Commit
git log --oneline -10 # Vorherigen Commit finden
git checkout <previous-commit>
# 2. Dependencies (falls nötig)
docker compose -f docker-compose.production.yml run --rm php \
composer install --no-dev --optimize-autoloader
# 3. Migrations rückgängig
docker compose -f docker-compose.production.yml exec php \
php console.php db:rollback 3
# 4. Container neu starten
docker compose -f docker-compose.production.yml up -d --build
# 5. Health Check
curl -f https://yourdomain.com/health/summary
```
### Database Rollback
```bash
# Datenbank aus Backup wiederherstellen
docker compose -f docker-compose.production.yml exec -T db \
mysql -u app_user -p<password> app_production \
< /backups/database/backup_20250115_120000.sql
# Verify
docker compose -f docker-compose.production.yml exec php \
php console.php db:status
```
---
## Troubleshooting Deployment
### Container starten nicht
```bash
# Logs prüfen
docker compose -f docker-compose.production.yml logs
# Port-Konflikte prüfen
sudo netstat -tulpn | grep -E ':(80|443|3306|6379)'
# Container Status
docker compose -f docker-compose.production.yml ps
# Neustart
docker compose -f docker-compose.production.yml down
docker compose -f docker-compose.production.yml up -d
```
### Health Checks schlagen fehl
```bash
# Detailed Health Report
curl http://localhost/health/detailed | jq
# Spezifische Checks
curl http://localhost/health/category/database | jq
curl http://localhost/health/category/security | jq
# Container-Logs
docker compose -f docker-compose.production.yml logs php
docker compose -f docker-compose.production.yml logs nginx
```
### Migrations schlagen fehl
```bash
# Migration Status
docker compose -f docker-compose.production.yml exec php \
php console.php db:status
# Migrations rollback
docker compose -f docker-compose.production.yml exec php \
php console.php db:rollback 1
# Database Connection testen
docker compose -f docker-compose.production.yml exec php \
php -r "new PDO('mysql:host=db;dbname=app_production', 'app_user', '<password>');"
```
---
## Empfohlener Workflow für dein Projekt
### Für Initial Setup und kleine Deployments:
**Verwende Script-Based Deployment**:
1. Server Setup (einmalig): Siehe Phase 1
2. Initial Deployment: Siehe Phase 2
3. Updates: `./scripts/deployment/deploy-production.sh`
4. Zero-Downtime: `./scripts/deployment/blue-green-deploy.sh`
### Für Skalierung und Multiple Environments:
**Ergänze mit Ansible**:
1. Server Provisioning automatisieren
2. Multi-Server Deployments orchestrieren
3. Konsistente Configuration Management
4. Infrastructure as Code
Siehe nächstes Dokument: [ANSIBLE_DEPLOYMENT.md](ANSIBLE_DEPLOYMENT.md)
---
## Nächste Schritte
1. ✅ Server vorbereiten (Phase 1)
2. ✅ Initial Deployment durchführen (Phase 2)
3. ✅ Monitoring einrichten (Phase 4)
4. 📝 Deployment dokumentieren
5. 🔄 Ansible evaluieren (optional, wenn Multi-Server)
Für detaillierte Ansible-Integration siehe nächstes Dokument!

File diff suppressed because it is too large Load Diff

View File

@@ -1,599 +0,0 @@
# Production Deployment - Quick Start Guide
**Goal**: Get the application running in production in under 30 minutes.
This is a simplified, essential-steps-only guide. For comprehensive documentation, see:
- [Complete Deployment Workflow](DEPLOYMENT_WORKFLOW.md)
- [Production Deployment Guide](PRODUCTION_DEPLOYMENT.md)
- [Ansible Deployment](ANSIBLE_DEPLOYMENT.md)
---
## Prerequisites
- Ubuntu 22.04+ server with root access
- Domain name pointing to server IP
- Port 80 and 443 open in firewall
---
## Step 1: Initial Server Setup (10 minutes)
```bash
# SSH into server
ssh root@your-server.com
# Update system
apt update && apt upgrade -y
# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
# Install Docker Compose
apt install docker-compose-plugin -y
# Install certbot for SSL
apt install certbot -y
# Create application user
useradd -m -s /bin/bash appuser
usermod -aG docker appuser
```
---
## Step 2: SSL Certificate (5 minutes)
```bash
# Create webroot directory
mkdir -p /var/www/certbot
# Get SSL certificate
certbot certonly --webroot \
-w /var/www/certbot \
-d yourdomain.com \
--email your-email@example.com \
--agree-tos \
--non-interactive
# Verify certificates
ls -la /etc/letsencrypt/live/yourdomain.com/
```
**Expected output**: `fullchain.pem` and `privkey.pem` files
---
## Step 3: Clone Application (2 minutes)
```bash
# Switch to app user
su - appuser
# Clone repository
git clone https://github.com/your-org/your-app.git /home/appuser/app
cd /home/appuser/app
# Checkout production branch
git checkout main
```
---
## Step 4: Generate Secrets (3 minutes)
```bash
# Generate Vault encryption key
php scripts/deployment/generate-vault-key.php
# Save output - YOU MUST STORE THIS SECURELY!
# Example output: vault_key_abc123def456...
```
**⚠️ CRITICAL**: Store this key in your password manager. You cannot recover it if lost.
---
## Step 5: Create Environment File (5 minutes)
```bash
# Copy example
cp .env.example .env.production
# Edit configuration
nano .env.production
```
**Minimal required configuration**:
```env
# Application
APP_ENV=production
APP_DEBUG=false
APP_URL=https://yourdomain.com
# Database
DB_HOST=database
DB_PORT=3306
DB_NAME=app_production
DB_USER=app_user
DB_PASS=GENERATE_STRONG_PASSWORD_HERE
# Vault
VAULT_ENCRYPTION_KEY=YOUR_GENERATED_KEY_FROM_STEP_4
# Logging
LOG_PATH=/var/log/app
LOG_LEVEL=INFO
# Admin Access
ADMIN_ALLOWED_IPS=YOUR.SERVER.IP,127.0.0.1
```
**Generate strong passwords**:
```bash
# Generate DB password
openssl rand -base64 32
# Generate JWT secret
openssl rand -base64 64
```
---
## Step 6: Build and Start (3 minutes)
```bash
# Build containers
docker compose -f docker-compose.production.yml build
# Start containers
docker compose -f docker-compose.production.yml up -d
# Check status
docker compose -f docker-compose.production.yml ps
```
**Expected output**: All containers should be "Up"
---
## Step 7: Initialize Database (2 minutes)
```bash
# Run migrations
docker compose -f docker-compose.production.yml exec php php console.php db:migrate
# Verify migration status
docker compose -f docker-compose.production.yml exec php php console.php db:status
```
---
## Step 8: Verify Health (1 minute)
```bash
# Check health endpoint
curl http://localhost/health/summary
# Expected output (healthy):
{
"timestamp": "2025-01-15T10:00:00+00:00",
"overall_status": "healthy",
"overall_healthy": true,
"summary": {
"total_checks": 8,
"healthy": 8,
"warning": 0,
"unhealthy": 0
}
}
```
If unhealthy, check logs:
```bash
docker compose -f docker-compose.production.yml logs php
```
---
## Step 9: Configure Nginx Reverse Proxy
```bash
# Exit to root user
exit
# Create Nginx config
nano /etc/nginx/sites-available/app
```
**Nginx configuration**:
```nginx
server {
listen 80;
server_name yourdomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
location / {
proxy_pass http://localhost:8080;
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;
}
location /health {
proxy_pass http://localhost:8080/health;
access_log off;
}
}
```
**Enable and restart**:
```bash
# Enable site
ln -s /etc/nginx/sites-available/app /etc/nginx/sites-enabled/
# Test configuration
nginx -t
# Restart Nginx
systemctl restart nginx
```
---
## Step 10: Final Verification
```bash
# Test HTTPS endpoint
curl -f https://yourdomain.com/health/summary
# Test detailed health
curl -f https://yourdomain.com/health/detailed
# Test metrics (should be accessible)
curl -f https://yourdomain.com/metrics
```
**✅ Success criteria**:
- All curl commands return 200 OK
- No SSL certificate warnings
- Health endpoint shows all checks healthy
---
## Post-Deployment Tasks
### Setup Automatic Certificate Renewal
```bash
# Test renewal
certbot renew --dry-run
# Certbot automatically creates cron job, verify:
systemctl status certbot.timer
```
### Setup Log Rotation
```bash
# Create logrotate config
nano /etc/logrotate.d/app
```
```
/var/log/app/*.log {
daily
rotate 14
compress
delaycompress
notifempty
missingok
create 0644 appuser appuser
sharedscripts
postrotate
docker compose -f /home/appuser/app/docker-compose.production.yml exec php php console.php cache:clear > /dev/null 2>&1 || true
endscript
}
```
### Setup Monitoring (Optional but Recommended)
```bash
# Install monitoring stack
cd /home/appuser/app
docker compose -f docker-compose.monitoring.yml up -d
# Access Grafana
# URL: http://your-server:3000
# Default credentials: admin/admin
```
### Setup Backups
```bash
# Create backup script
nano /home/appuser/backup-production.sh
```
```bash
#!/bin/bash
set -e
BACKUP_DIR="/opt/backups"
DATE=$(date +%Y%m%d_%H%M%S)
# Backup database
docker compose -f /home/appuser/app/docker-compose.production.yml \
exec -T database mysqldump -u app_user -p${DB_PASS} app_production | \
gzip > ${BACKUP_DIR}/db_${DATE}.sql.gz
# Backup Vault
tar -czf ${BACKUP_DIR}/vault_${DATE}.tar.gz /opt/vault
# Keep only last 7 days
find ${BACKUP_DIR} -name "*.gz" -mtime +7 -delete
echo "Backup completed: ${DATE}"
```
```bash
# Make executable
chmod +x /home/appuser/backup-production.sh
# Add to crontab (daily at 2 AM)
crontab -e
```
Add line:
```
0 2 * * * /home/appuser/backup-production.sh >> /var/log/backup.log 2>&1
```
---
## Troubleshooting
### Container won't start
```bash
# Check logs
docker compose -f docker-compose.production.yml logs php
# Common issues:
# - Wrong database credentials → Check .env.production
# - Port already in use → Check: netstat -tulpn | grep 8080
# - Permission issues → Run: chown -R appuser:appuser /home/appuser/app
```
### Health checks failing
```bash
# Check specific health check
curl http://localhost/health/category/database
# Common issues:
# - Database not migrated → Run: php console.php db:migrate
# - Cache not writable → Check: ls -la /var/cache/app
# - Queue not running → Check: docker compose ps
```
### SSL certificate issues
```bash
# Check certificate validity
openssl x509 -in /etc/letsencrypt/live/yourdomain.com/fullchain.pem -noout -dates
# Renew certificate
certbot renew --force-renewal
# Restart Nginx
systemctl restart nginx
```
### Application errors
```bash
# Check application logs
docker compose -f docker-compose.production.yml logs -f php
# Check Nginx logs
tail -f /var/log/nginx/error.log
# Check system logs
journalctl -u nginx -f
```
---
## Security Hardening (Do This After Deployment)
### 1. Firewall Configuration
```bash
# Install UFW
apt install ufw -y
# Allow SSH
ufw allow 22/tcp
# Allow HTTP/HTTPS
ufw allow 80/tcp
ufw allow 443/tcp
# Enable firewall
ufw enable
```
### 2. SSH Key-Only Authentication
```bash
# Generate SSH key on local machine
ssh-keygen -t ed25519 -C "your-email@example.com"
# Copy to server
ssh-copy-id root@your-server.com
# Disable password authentication
nano /etc/ssh/sshd_config
```
Set:
```
PasswordAuthentication no
PermitRootLogin prohibit-password
```
Restart SSH:
```bash
systemctl restart sshd
```
### 3. Fail2Ban
```bash
# Install fail2ban
apt install fail2ban -y
# Create jail for Nginx
nano /etc/fail2ban/jail.d/nginx-limit.conf
```
```ini
[nginx-limit-req]
enabled = true
filter = nginx-limit-req
logpath = /var/log/nginx/error.log
maxretry = 10
findtime = 60
bantime = 3600
```
```bash
# Restart fail2ban
systemctl restart fail2ban
```
---
## Deployment Updates (Ongoing)
For deploying updates after initial setup:
```bash
# SSH to server
ssh appuser@your-server.com
# Navigate to app
cd /home/appuser/app
# Pull latest code
git pull origin main
# Rebuild containers
docker compose -f docker-compose.production.yml build
# Run migrations (if any)
docker compose -f docker-compose.production.yml exec php php console.php db:migrate
# Restart containers
docker compose -f docker-compose.production.yml up -d
# Verify health
curl -f http://localhost/health/summary
```
**For zero-downtime deployments**, use the automated script:
```bash
./scripts/deployment/blue-green-deploy.sh
```
---
## Getting Help
If you encounter issues not covered in this quick start:
1. **Check detailed documentation**:
- [Complete Deployment Workflow](DEPLOYMENT_WORKFLOW.md)
- [Production Deployment Guide](PRODUCTION_DEPLOYMENT.md)
- [Troubleshooting Guide](PRODUCTION_DEPLOYMENT.md#troubleshooting)
2. **Check application logs**:
```bash
docker compose -f docker-compose.production.yml logs -f
```
3. **Check health endpoints**:
```bash
curl http://localhost/health/detailed | jq
```
4. **Check metrics**:
```bash
curl http://localhost/metrics
```
---
## Success Checklist
✅ Before considering deployment complete:
- [ ] SSL certificate installed and valid
- [ ] Application accessible via HTTPS
- [ ] All health checks passing (green)
- [ ] Database migrations applied successfully
- [ ] Logs being written to `/var/log/app`
- [ ] Automatic certificate renewal configured
- [ ] Backup script running daily
- [ ] Firewall configured (ports 22, 80, 443 only)
- [ ] SSH key-only authentication enabled
- [ ] Fail2Ban installed and monitoring
- [ ] Monitoring stack running (optional)
- [ ] Team has access to Vault encryption key
- [ ] Database backup verified and restorable
---
## Next Steps
After successful deployment:
1. **Setup Monitoring Alerts**: Configure Prometheus alerting rules
2. **Performance Tuning**: Review metrics and optimize based on actual traffic
3. **Security Audit**: Run security scan with tools like OWASP ZAP
4. **Documentation**: Document any custom configuration changes
5. **Team Training**: Ensure team knows deployment and rollback procedures
6. **Disaster Recovery**: Test backup restoration procedure
---
## Estimated Timeline
- **Initial deployment (following this guide)**: 30 minutes
- **Security hardening**: 15 minutes
- **Monitoring setup**: 20 minutes
- **Total time to production**: ~1 hour
---
**You're ready for production! 🚀**
For questions or issues, refer to the comprehensive guides linked throughout this document.

View File

@@ -1,477 +1,66 @@
# Production Deployment Documentation
# Deployment Documentation
Complete documentation for deploying the Custom PHP Framework to production.
**Hinweis:** Die Haupt-Deployment-Dokumentation befindet sich jetzt im `deployment/` Ordner.
---
## Quick Navigation
## 📖 Haupt-Dokumentation
**New to deployment? Start here:**
1. [Quick Start Guide](QUICKSTART.md) - Get running in 30 minutes
2. [Deployment Checklist](DEPLOYMENT_CHECKLIST.md) - Printable checklist
**Für aktuelle Deployment-Informationen siehe:**
**Need detailed information?**
- [Complete Deployment Workflow](DEPLOYMENT_WORKFLOW.md) - Step-by-step deployment process
- [Production Deployment Guide](PRODUCTION_DEPLOYMENT.md) - Comprehensive infrastructure guide
- [Production Logging](production-logging.md) - Logging configuration and best practices
**Want automation?**
- [Ansible Deployment](ANSIBLE_DEPLOYMENT.md) - Infrastructure as Code with Ansible
**Need secure access?**
- [WireGuard VPN Setup](WIREGUARD-SETUP.md) - Secure VPN access to production services
- **[deployment/README.md](../../deployment/README.md)** - Haupt-Deployment-Dokumentation
- **[deployment/QUICK_START.md](../../deployment/QUICK_START.md)** - Schnellstart-Guide
- **[deployment/DEPLOYMENT_COMMANDS.md](../../deployment/DEPLOYMENT_COMMANDS.md)** - Command-Referenz
- **[deployment/CODE_CHANGE_WORKFLOW.md](../../deployment/CODE_CHANGE_WORKFLOW.md)** - Code-Deployment-Workflow
---
## Documentation Structure
## 📚 Spezifische Themen-Dokumentation
### 1. [QUICKSTART.md](QUICKSTART.md)
**Best for**: First-time deployment, getting started quickly
Die folgenden Dokumente behandeln spezifische Deployment-Themen:
**Content**:
- 10-step deployment process (~30 minutes)
- Minimal configuration required
- Immediate verification steps
- Basic troubleshooting
### VPN & Security
- **[WIREGUARD-SETUP.md](WIREGUARD-SETUP.md)** - WireGuard VPN Setup (komplett)
- **[WIREGUARD-FUTURE-SECURITY.md](WIREGUARD-FUTURE-SECURITY.md)** - Zukünftige Security-Überlegungen
- **[PRODUCTION-SECURITY-UPDATES.md](PRODUCTION-SECURITY-UPDATES.md)** - Security-Updates
**Use when**: You want to get the application running in production as fast as possible.
### Configuration & Setup
- **[database-migration-strategy.md](database-migration-strategy.md)** - Database Migration Strategy
- **[logging-configuration.md](logging-configuration.md)** - Logging Configuration
- **[production-logging.md](production-logging.md)** - Production Logging Best Practices
- **[secrets-management.md](secrets-management.md)** - Secrets Management mit Vault
- **[ssl-setup.md](ssl-setup.md)** - SSL/TLS Setup mit Let's Encrypt
- **[SSL-PRODUCTION-SETUP.md](SSL-PRODUCTION-SETUP.md)** - Production SSL Setup
- **[env-production-template.md](env-production-template.md)** - Environment Template
- **[production-prerequisites.md](production-prerequisites.md)** - Production Prerequisites
### Automation (Veraltet - siehe deployment/ansible)
- **[ANSIBLE_DEPLOYMENT.md](ANSIBLE_DEPLOYMENT.md)** - ⚠️ Veraltet, siehe `deployment/ansible/README.md`
- **[deployment-automation.md](deployment-automation.md)** - ⚠️ Veraltet, siehe `deployment/ansible/`
---
### 2. [DEPLOYMENT_CHECKLIST.md](DEPLOYMENT_CHECKLIST.md)
**Best for**: Ensuring nothing is missed, compliance verification
## 🚀 Schnellstart
**Content**:
- Pre-deployment checklist
- Step-by-step deployment verification
- Post-deployment security hardening
- Maintenance schedules (weekly, monthly, quarterly)
- Emergency contacts template
- Deployment sign-off form
**Für aktuelle Deployment-Informationen:**
**Use when**: You want a printable, check-off-items-as-you-go guide.
---
### 3. [DEPLOYMENT_WORKFLOW.md](DEPLOYMENT_WORKFLOW.md)
**Best for**: Understanding the complete deployment lifecycle
**Content**:
- Phase 1: Initial Server Setup (one-time)
- Phase 2: Initial Deployment
- Phase 3: Ongoing Deployment (updates)
- Phase 4: Monitoring Setup
- Two deployment options: Manual/Script-Based and Ansible-Based
- Automated deployment scripts
- Zero-downtime deployment
- Rollback procedures
**Use when**: You need detailed explanations of each deployment phase or want to understand deployment options.
---
### 4. [PRODUCTION_DEPLOYMENT.md](PRODUCTION_DEPLOYMENT.md)
**Best for**: Comprehensive infrastructure reference
**Content**:
- Complete infrastructure setup
- SSL/TLS configuration with Let's Encrypt
- Secrets management with Vault
- Environment configuration
- Docker deployment
- Database migrations
- Monitoring and health checks (all endpoints documented)
- Logging configuration
- Security considerations
- Troubleshooting guide
- Maintenance procedures
**Use when**: You need deep technical details about any production infrastructure component.
---
### 5. [production-logging.md](production-logging.md)
**Best for**: Production logging configuration and optimization
**Content**:
- ProductionLogConfig options (production, highPerformance, withAggregation, debug, staging)
- Environment-based configuration
- Log rotation and retention policies
- Structured JSON log format
- Metrics and monitoring integration
- Performance tuning (buffer sizes, sampling rates, aggregation)
- Troubleshooting guides
- Best practices
**Use when**: You need to configure or troubleshoot production logging.
---
### 6. [ANSIBLE_DEPLOYMENT.md](ANSIBLE_DEPLOYMENT.md)
**Best for**: Automated, multi-server deployments
**Content**:
- Complete Ansible project structure
- Ansible roles (common, docker, ssl, application)
- Playbooks (site.yml, deploy.yml, rollback.yml, provision.yml)
- Ansible Vault for secrets
- CI/CD integration (GitHub Actions)
- Comparison: Script-Based vs Ansible
- Hybrid approach recommendation
**Use when**: You're scaling to multiple servers or want infrastructure as code.
---
### 7. [WIREGUARD-SETUP.md](WIREGUARD-SETUP.md)
**Best for**: Secure VPN access to production services
**Content**:
- Complete WireGuard VPN setup guide
- Server installation via Ansible
- Client configuration and management
- Connection testing and troubleshooting
- Security best practices
- Monitoring and maintenance
**Use when**: You need secure access to internal services (Prometheus, Grafana, Portainer) or want to restrict access via VPN.
---
## Which Guide Should I Use?
### Scenario 1: First-Time Deployment
**Path**: QUICKSTART.md → DEPLOYMENT_CHECKLIST.md
1. Follow [QUICKSTART.md](QUICKSTART.md) for initial deployment
2. Use [DEPLOYMENT_CHECKLIST.md](DEPLOYMENT_CHECKLIST.md) to verify everything
3. Keep [PRODUCTION_DEPLOYMENT.md](PRODUCTION_DEPLOYMENT.md) handy for troubleshooting
**Time Required**: ~1 hour
---
### Scenario 2: Enterprise Deployment
**Path**: PRODUCTION_DEPLOYMENT.md → ANSIBLE_DEPLOYMENT.md → DEPLOYMENT_CHECKLIST.md
1. Review [PRODUCTION_DEPLOYMENT.md](PRODUCTION_DEPLOYMENT.md) for infrastructure understanding
2. Implement with [ANSIBLE_DEPLOYMENT.md](ANSIBLE_DEPLOYMENT.md) for automation
3. Verify with [DEPLOYMENT_CHECKLIST.md](DEPLOYMENT_CHECKLIST.md)
**Time Required**: ~4 hours (initial setup), ~30 minutes (ongoing deployments)
---
### Scenario 3: Single Server, Team Collaboration
**Path**: DEPLOYMENT_WORKFLOW.md → DEPLOYMENT_CHECKLIST.md
1. Follow [DEPLOYMENT_WORKFLOW.md](DEPLOYMENT_WORKFLOW.md) for comprehensive process
2. Use automated scripts (deploy-production.sh)
3. Verify with [DEPLOYMENT_CHECKLIST.md](DEPLOYMENT_CHECKLIST.md)
**Time Required**: ~2 hours
---
### Scenario 4: Logging Issues
**Path**: production-logging.md
1. Consult [production-logging.md](production-logging.md) for logging configuration
2. Check troubleshooting section
3. Adjust ProductionLogConfig based on needs
**Time Required**: ~30 minutes
---
### Scenario 5: Adding Monitoring
**Path**: PRODUCTION_DEPLOYMENT.md (Monitoring section)
1. Jump to Monitoring section in [PRODUCTION_DEPLOYMENT.md](PRODUCTION_DEPLOYMENT.md)
2. Follow Prometheus/Grafana setup
3. Configure alerts
**Time Required**: ~1 hour
---
## Deployment Methods Comparison
| Feature | Quick Start | Script-Based | Ansible |
|---------|-------------|--------------|---------|
| **Setup Time** | 30 min | 2 hours | 4 hours |
| **Ongoing Deployment** | 15 min | 10 min | 5 min |
| **Multi-Server** | Manual | Manual | Automated |
| **Rollback** | Manual | Script | Automated |
| **Team Collaboration** | Docs | Scripts + Docs | Playbooks |
| **Infrastructure as Code** | No | Partial | Yes |
| **Idempotency** | No | Partial | Yes |
| **Best For** | Single server, quick start | Single server, repeatable | Multiple servers, scaling |
---
## Prerequisites Summary
All deployment methods require:
### Server Requirements
- Ubuntu 22.04+ (or Debian 11+)
- 4GB RAM minimum (8GB recommended)
- 40GB disk space minimum
- Root or sudo access
### Network Requirements
- Domain name configured
- DNS pointing to server IP
- Ports 22, 80, 443 accessible
- Static IP address recommended
### Tools Required
- SSH client
- Git
- Text editor (nano, vim, or VS Code with Remote SSH)
### Knowledge Requirements
- Basic Linux command line
- SSH and file permissions
- Docker basics
- DNS and domain configuration
- (Optional) Ansible for automation
---
## Common Tasks
### Initial Deployment
```bash
# Follow Quick Start Guide
cat docs/deployment/QUICKSTART.md
# Haupt-Dokumentation
cat deployment/README.md
# Verify with checklist
cat docs/deployment/DEPLOYMENT_CHECKLIST.md
# Schnellstart
cat deployment/QUICK_START.md
# Commands
cat deployment/DEPLOYMENT_COMMANDS.md
```
### Deploy Update
```bash
# Manual method
cd /home/appuser/app
git pull origin main
docker compose -f docker-compose.production.yml build
docker compose -f docker-compose.production.yml up -d
php console.php db:migrate
# Automated script method
./scripts/deployment/deploy-production.sh
# Zero-downtime method
./scripts/deployment/blue-green-deploy.sh
```
### Rollback
```bash
# Manual rollback (see DEPLOYMENT_WORKFLOW.md)
docker compose -f docker-compose.old.yml up -d
php console.php db:rollback 1
# Automated rollback
./scripts/deployment/blue-green-rollback.sh
```
### Health Check
```bash
# Quick health check
curl -f https://yourdomain.com/health/summary
# Detailed health check
curl -f https://yourdomain.com/health/detailed | jq
# Specific category
curl -f https://yourdomain.com/health/category/database
```
### View Logs
```bash
# Application logs
docker compose -f docker-compose.production.yml logs -f php
# System logs
tail -f /var/log/app/app.log
# Nginx logs
tail -f /var/log/nginx/error.log
```
### Database Backup
```bash
# Manual backup
docker compose exec database mysqldump -u app_user -p app_production > backup.sql
# Automated backup (configured in QUICKSTART.md)
/home/appuser/backup-production.sh
```
### SSL Certificate Renewal
```bash
# Test renewal
certbot renew --dry-run
# Force renewal
certbot renew --force-renewal
# Automatic renewal is configured via cron/systemd timer
```
**Für spezifische Themen:**
- VPN Setup: `docs/deployment/WIREGUARD-SETUP.md`
- Database Migrations: `docs/deployment/database-migration-strategy.md`
- Logging: `docs/deployment/production-logging.md`
- SSL Setup: `docs/deployment/ssl-setup.md`
---
## Troubleshooting Quick Reference
### Issue: Containers won't start
**Solution**: Check logs
```bash
docker compose -f docker-compose.production.yml logs php
```
**Common causes**: Database credentials, port conflicts, permissions
**Full guide**: [PRODUCTION_DEPLOYMENT.md - Troubleshooting](PRODUCTION_DEPLOYMENT.md#troubleshooting)
---
### Issue: Health checks failing
**Solution**: Check specific health check
```bash
curl http://localhost/health/category/database
```
**Common causes**: Database not migrated, cache not writable, queue not running
**Full guide**: [DEPLOYMENT_WORKFLOW.md - Troubleshooting](DEPLOYMENT_WORKFLOW.md#troubleshooting)
---
### Issue: SSL certificate problems
**Solution**: Verify certificate
```bash
openssl x509 -in /etc/letsencrypt/live/yourdomain.com/fullchain.pem -noout -dates
```
**Common causes**: DNS not propagated, port 80 blocked, wrong domain
**Full guide**: [PRODUCTION_DEPLOYMENT.md - SSL/TLS](PRODUCTION_DEPLOYMENT.md#ssltls-configuration)
---
### Issue: Application errors
**Solution**: Check application logs
```bash
docker compose -f docker-compose.production.yml logs -f php
tail -f /var/log/app/app.log
```
**Common causes**: Environment configuration, missing migrations, permission issues
**Full guide**: [production-logging.md - Troubleshooting](production-logging.md#troubleshooting)
---
## Security Considerations
All deployment methods include security best practices:
- ✅ HTTPS enforced (SSL/TLS)
- ✅ Firewall configured (UFW)
- ✅ SSH key-only authentication
- ✅ Fail2Ban for intrusion prevention
- ✅ Security headers (CSP, HSTS, X-Frame-Options)
- ✅ CSRF protection
- ✅ Rate limiting
- ✅ WAF (Web Application Firewall)
- ✅ Vault for secrets management
- ✅ Regular security updates
**Detailed security guide**: [PRODUCTION_DEPLOYMENT.md - Security](PRODUCTION_DEPLOYMENT.md#security-considerations)
---
## Monitoring and Health Checks
### Available Endpoints
```
GET /health/summary - Quick health summary
GET /health/detailed - Full health report with all checks
GET /health/checks - List registered health checks
GET /health/category/{cat} - Health checks by category
GET /metrics - Prometheus metrics
GET /metrics/json - JSON metrics
```
### Health Check Categories
- `DATABASE` - Database connectivity and performance
- `CACHE` - Cache system health (Redis/File)
- `SECURITY` - SSL certificates, rate limiting, CSRF
- `INFRASTRUCTURE` - Disk space, memory, queue status
- `EXTERNAL` - External service connectivity
**Full monitoring guide**: [PRODUCTION_DEPLOYMENT.md - Monitoring](PRODUCTION_DEPLOYMENT.md#monitoring-and-health-checks)
---
## Support and Resources
### Internal Documentation
- [Framework Guidelines](../claude/guidelines.md)
- [Security Patterns](../claude/security-patterns.md)
- [Database Patterns](../claude/database-patterns.md)
- [Error Handling](../claude/error-handling.md)
### External Resources
- [Docker Documentation](https://docs.docker.com/)
- [Let's Encrypt Documentation](https://letsencrypt.org/docs/)
- [Nginx Documentation](https://nginx.org/en/docs/)
- [Ansible Documentation](https://docs.ansible.com/) (for automation)
### Getting Help
1. **Check documentation** (this directory)
2. **Review application logs** (`docker compose logs`)
3. **Check health endpoints** (`/health/detailed`)
4. **Review metrics** (`/metrics`)
5. **Consult troubleshooting guides** (in each document)
---
## Contribution
This documentation should be updated after each deployment to reflect:
- Lessons learned
- Process improvements
- Common issues encountered
- New best practices discovered
**Deployment feedback template**: See [DEPLOYMENT_CHECKLIST.md - Continuous Improvement](DEPLOYMENT_CHECKLIST.md#continuous-improvement)
---
## Version History
| Version | Date | Changes | Author |
|---------|------|---------|--------|
| 1.0 | 2025-01-15 | Initial comprehensive deployment documentation | System |
| | | Complete with Quick Start, Workflow, Ansible, Checklists | |
---
**Quick Links**:
- [Quick Start](QUICKSTART.md) - Fastest path to production
- [Checklist](DEPLOYMENT_CHECKLIST.md) - Ensure nothing is missed
- [Complete Workflow](DEPLOYMENT_WORKFLOW.md) - Detailed deployment process
- [Production Guide](PRODUCTION_DEPLOYMENT.md) - Comprehensive reference
- [Logging Guide](production-logging.md) - Production logging configuration
- [Ansible Guide](ANSIBLE_DEPLOYMENT.md) - Infrastructure automation
- [WireGuard VPN](WIREGUARD-SETUP.md) - Secure VPN access to production
---
**Ready to deploy? Start with [QUICKSTART.md](QUICKSTART.md) →**
**Haupt-Deployment-Dokumentation:** Siehe [deployment/](../../deployment/) Ordner

View File

@@ -1,5 +1,16 @@
# 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

View File

@@ -1,711 +0,0 @@
# Production Docker Compose Configuration
Production Docker Compose configuration mit Sicherheits-Härtung, Performance-Optimierung und Monitoring für das Custom PHP Framework.
## Übersicht
Das Projekt verwendet Docker Compose Overlay-Pattern:
- **Base**: `docker-compose.yml` - Entwicklungsumgebung
- **Production**: `docker-compose.production.yml` - Production-spezifische Overrides
## Usage
```bash
# Production-Stack starten
docker-compose -f docker-compose.yml \
-f docker-compose.production.yml \
--env-file .env.production \
up -d
# Mit Build (bei Änderungen)
docker-compose -f docker-compose.yml \
-f docker-compose.production.yml \
--env-file .env.production \
up -d --build
# Stack stoppen
docker-compose -f docker-compose.yml \
-f docker-compose.production.yml \
down
# Logs anzeigen
docker-compose -f docker-compose.yml \
-f docker-compose.production.yml \
logs -f [service]
# Service Health Check
docker-compose -f docker-compose.yml \
-f docker-compose.production.yml \
ps
```
## Production Overrides
### 1. Web (Nginx) Service
**Restart Policy**:
```yaml
restart: always # Automatischer Neustart bei Fehlern
```
**SSL/TLS Configuration**:
```yaml
volumes:
- certbot-conf:/etc/letsencrypt:ro
- certbot-www:/var/www/certbot:ro
```
- Let's Encrypt Zertifikate via Certbot
- Read-only Mounts für Sicherheit
**Health Checks**:
```yaml
healthcheck:
test: ["CMD", "curl", "-f", "https://localhost/health"]
interval: 15s
timeout: 5s
retries: 5
start_period: 30s
```
- HTTPS Health Check auf `/health` Endpoint
- 15 Sekunden Intervall für schnelle Fehler-Erkennung
- 5 Retries vor Service-Nestart
**Resource Limits**:
```yaml
deploy:
resources:
limits:
memory: 512M
cpus: '1.0'
reservations:
memory: 256M
cpus: '0.5'
```
- Nginx ist lightweight, moderate Limits
**Logging**:
```yaml
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
compress: "true"
labels: "service,environment"
```
- JSON-Format für Log-Aggregation (ELK Stack kompatibel)
- 10MB pro Datei, 5 Dateien = 50MB total
- Komprimierte Rotation
### 2. PHP Service
**Restart Policy**:
```yaml
restart: always
```
**Build Configuration**:
```yaml
build:
args:
- ENV=production
- COMPOSER_INSTALL_FLAGS=--no-dev --optimize-autoloader --classmap-authoritative
```
- `--no-dev`: Keine Development-Dependencies
- `--optimize-autoloader`: PSR-4 Optimization
- `--classmap-authoritative`: Keine Filesystem-Lookups (Performance)
**Environment**:
```yaml
environment:
- APP_ENV=production
- APP_DEBUG=false # DEBUG AUS in Production!
- PHP_MEMORY_LIMIT=512M
- PHP_MAX_EXECUTION_TIME=30
- XDEBUG_MODE=off # Xdebug aus für Performance
```
**Health Checks**:
```yaml
healthcheck:
test: ["CMD", "php-fpm-healthcheck"]
interval: 15s
timeout: 5s
retries: 5
start_period: 30s
```
- PHP-FPM Health Check via Custom Script
- Schnelles Failure-Detection
**Resource Limits**:
```yaml
deploy:
resources:
limits:
memory: 1G
cpus: '2.0'
reservations:
memory: 512M
cpus: '1.0'
```
- PHP benötigt mehr Memory als Nginx
- 2 CPUs für parallele Request-Verarbeitung
**Volumes**:
```yaml
volumes:
- storage-logs:/var/www/html/storage/logs:rw
- storage-cache:/var/www/html/storage/cache:rw
- storage-queue:/var/www/html/storage/queue:rw
- storage-discovery:/var/www/html/storage/discovery:rw
- storage-uploads:/var/www/html/storage/uploads:rw
```
- Nur notwendige Docker Volumes
- **KEINE Host-Mounts** für Sicherheit
- Application Code im Image (nicht gemountet)
### 3. Database (PostgreSQL 16) Service
**Restart Policy**:
```yaml
restart: always
```
**Production Configuration**:
```yaml
volumes:
- db_data:/var/lib/postgresql/data
- ./docker/postgres/postgresql.production.conf:/etc/postgresql/postgresql.conf:ro
- ./docker/postgres/init:/docker-entrypoint-initdb.d:ro
```
- Production-optimierte `postgresql.production.conf`
- Init-Scripts für Schema-Setup
**Resource Limits**:
```yaml
deploy:
resources:
limits:
memory: 2G
cpus: '2.0'
reservations:
memory: 1G
cpus: '1.0'
```
- PostgreSQL benötigt Memory für `shared_buffers` (2GB in Config)
- 2 CPUs für parallele Query-Verarbeitung
**Health Checks**:
```yaml
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME:-postgres} -d ${DB_DATABASE:-michaelschiemer}"]
interval: 10s
timeout: 3s
retries: 5
start_period: 30s
```
- `pg_isready` für schnelle Connection-Prüfung
- 10 Sekunden Intervall (häufiger als andere Services)
**Logging**:
```yaml
logging:
driver: json-file
options:
max-size: "20m" # Größere Log-Dateien für PostgreSQL
max-file: "10"
compress: "true"
```
- PostgreSQL loggt mehr (Slow Queries, Checkpoints, etc.)
- 20MB pro Datei, 10 Dateien = 200MB total
### 4. Redis Service
**Restart Policy**:
```yaml
restart: always
```
**Resource Limits**:
```yaml
deploy:
resources:
limits:
memory: 512M
cpus: '1.0'
reservations:
memory: 256M
cpus: '0.5'
```
- Redis ist Memory-basiert, moderate Limits
**Health Checks**:
```yaml
healthcheck:
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
interval: 10s
timeout: 3s
retries: 5
start_period: 10s
```
- `redis-cli ping` für Connection-Check
- Schneller Start (10s start_period)
### 5. Queue Worker Service
**Restart Policy**:
```yaml
restart: always
```
**Environment**:
```yaml
environment:
- APP_ENV=production
- WORKER_DEBUG=false
- WORKER_SLEEP_TIME=100000
- WORKER_MAX_JOBS=10000
```
- Production-Modus ohne Debug
- 10,000 Jobs pro Worker-Lifecycle
**Resource Limits**:
```yaml
deploy:
resources:
limits:
memory: 2G
cpus: '2.0'
reservations:
memory: 1G
cpus: '1.0'
replicas: 2 # 2 Worker-Instanzen
```
- Worker benötigen Memory für Job-Processing
- **2 Replicas** für Parallelität
**Graceful Shutdown**:
```yaml
stop_grace_period: 60s
```
- 60 Sekunden für Job-Completion vor Shutdown
- Verhindert Job-Abbrüche
**Logging**:
```yaml
logging:
driver: json-file
options:
max-size: "20m"
max-file: "10"
compress: "true"
```
- Worker loggen ausführlich (Job-Start, Completion, Errors)
- 200MB total Log-Storage
### 6. Certbot Service
**Restart Policy**:
```yaml
restart: always
```
**Auto-Renewal**:
```yaml
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew --webroot -w /var/www/certbot --quiet; sleep 12h & wait $${!}; done;'"
```
- Automatische Erneuerung alle 12 Stunden
- Webroot-Challenge über Nginx
**Volumes**:
```yaml
volumes:
- certbot-conf:/etc/letsencrypt
- certbot-www:/var/www/certbot
- certbot-logs:/var/log/letsencrypt
```
- Zertifikate werden mit Nginx geteilt
## Network Configuration
**Security Isolation**:
```yaml
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # Backend network is internal (no internet access)
cache:
driver: bridge
internal: true # Cache network is internal
```
**Network-Segmentierung**:
- **Frontend**: Nginx, Certbot (Internet-Zugriff)
- **Backend**: PHP, PostgreSQL, Queue Worker (KEIN Internet-Zugriff)
- **Cache**: Redis (KEIN Internet-Zugriff)
**Security Benefits**:
- Backend Services können nicht nach außen kommunizieren
- Verhindert Data Exfiltration bei Compromise
- Zero-Trust Network Architecture
## Volumes Configuration
**SSL/TLS Volumes**:
```yaml
certbot-conf:
driver: local
certbot-www:
driver: local
certbot-logs:
driver: local
```
**Application Storage Volumes**:
```yaml
storage-logs:
driver: local
storage-cache:
driver: local
storage-queue:
driver: local
storage-discovery:
driver: local
storage-uploads:
driver: local
```
**Database Volume**:
```yaml
db_data:
driver: local
# Optional: External volume for backups
# driver_opts:
# type: none
# o: bind
# device: /mnt/db-backups/michaelschiemer-prod
```
**Volume Best Practices**:
- Alle Volumes sind `driver: local` (nicht Host-Mounts)
- Für Backups: Optional External Volume für Database
- Keine Development-Host-Mounts in Production
## Logging Strategy
**JSON Logging** für alle Services:
```yaml
logging:
driver: json-file
options:
max-size: "10m" # Service-abhängig
max-file: "5" # Service-abhängig
compress: "true"
labels: "service,environment"
```
**Log Rotation**:
| Service | Max Size | Max Files | Total Storage |
|---------|----------|-----------|---------------|
| Nginx | 10MB | 5 | 50MB |
| PHP | 10MB | 10 | 100MB |
| PostgreSQL | 20MB | 10 | 200MB |
| Redis | 10MB | 5 | 50MB |
| Queue Worker | 20MB | 10 | 200MB |
| Certbot | 5MB | 3 | 15MB |
| **TOTAL** | | | **615MB** |
**Log Aggregation**:
- JSON-Format für ELK Stack (Elasticsearch, Logstash, Kibana)
- Labels für Service-Identifikation
- Komprimierte Log-Files für Storage-Effizienz
## Resource Allocation
**Total Resource Requirements**:
| Service | Memory Limit | Memory Reservation | CPU Limit | CPU Reservation |
|---------|--------------|-------------------|-----------|-----------------|
| Nginx | 512M | 256M | 1.0 | 0.5 |
| PHP | 1G | 512M | 2.0 | 1.0 |
| PostgreSQL | 2G | 1G | 2.0 | 1.0 |
| Redis | 512M | 256M | 1.0 | 0.5 |
| Queue Worker (x2) | 4G | 2G | 4.0 | 2.0 |
| **TOTAL** | **8GB** | **4GB** | **10 CPUs** | **5 CPUs** |
**Server Sizing Recommendations**:
- **Minimum**: 8GB RAM, 4 CPUs (Resource Limits)
- **Recommended**: 16GB RAM, 8 CPUs (Headroom für OS und Spikes)
- **Optimal**: 32GB RAM, 16 CPUs (Production mit Monitoring)
## Health Checks
**Health Check Strategy**:
| Service | Endpoint | Interval | Timeout | Retries | Start Period |
|---------|----------|----------|---------|---------|--------------|
| Nginx | HTTPS /health | 15s | 5s | 5 | 30s |
| PHP | php-fpm-healthcheck | 15s | 5s | 5 | 30s |
| PostgreSQL | pg_isready | 10s | 3s | 5 | 30s |
| Redis | redis-cli ping | 10s | 3s | 5 | 10s |
**Health Check Benefits**:
- Automatische Service-Recovery bei Failures
- Docker orchestriert Neustart nur bei unhealthy Services
- Health-Status via `docker-compose ps`
## Deployment Workflow
### Initial Deployment
```bash
# 1. Server vorbereiten (siehe production-prerequisites.md)
# 2. .env.production konfigurieren (siehe env-production-template.md)
# 3. Build und Deploy
docker-compose -f docker-compose.yml \
-f docker-compose.production.yml \
--env-file .env.production \
up -d --build
# 4. SSL Zertifikate initialisieren
docker exec php php console.php ssl:init
# 5. Database Migrationen
docker exec php php console.php db:migrate
# 6. Health Checks verifizieren
docker-compose -f docker-compose.yml \
-f docker-compose.production.yml \
ps
```
### Rolling Update (Zero-Downtime)
```bash
# 1. Neue Version pullen
git pull origin main
# 2. Build neue Images
docker-compose -f docker-compose.yml \
-f docker-compose.production.yml \
--env-file .env.production \
build --no-cache
# 3. Rolling Update (Service für Service)
# Nginx
docker-compose -f docker-compose.yml \
-f docker-compose.production.yml \
up -d --no-deps web
# PHP (nach Nginx)
docker-compose -f docker-compose.yml \
-f docker-compose.production.yml \
up -d --no-deps php
# Queue Worker (nach PHP)
docker-compose -f docker-compose.yml \
-f docker-compose.production.yml \
up -d --no-deps --scale queue-worker=2 queue-worker
# 4. Health Checks verifizieren
docker-compose -f docker-compose.yml \
-f docker-compose.production.yml \
ps
```
### Rollback Strategy
```bash
# 1. Previous Git Commit
git log --oneline -5
git checkout <previous-commit>
# 2. Rebuild und Deploy
docker-compose -f docker-compose.yml \
-f docker-compose.production.yml \
--env-file .env.production \
up -d --build
# 3. Database Rollback (wenn nötig)
docker exec php php console.php db:rollback 1
```
## Monitoring
### Container Status
```bash
# Status aller Services
docker-compose -f docker-compose.yml \
-f docker-compose.production.yml \
ps
# Detaillierte Informationen
docker inspect <container-name>
```
### Resource Usage
```bash
# CPU/Memory Usage
docker stats
# Service-spezifisch
docker stats php db redis
```
### Logs
```bash
# Alle Logs (Follow)
docker-compose -f docker-compose.yml \
-f docker-compose.production.yml \
logs -f
# Service-spezifisch
docker-compose -f docker-compose.yml \
-f docker-compose.production.yml \
logs -f php
# Letzte N Zeilen
docker-compose -f docker-compose.yml \
-f docker-compose.production.yml \
logs --tail=100 php
```
### Health Check Status
```bash
# Health Check Logs
docker inspect --format='{{json .State.Health}}' php | jq
# Health History
docker inspect --format='{{range .State.Health.Log}}{{.Start}} {{.ExitCode}} {{.Output}}{{end}}' php
```
## Backup Strategy
### Database Backup
```bash
# Manual Backup
docker exec db pg_dump -U postgres michaelschiemer_prod > backup_$(date +%Y%m%d_%H%M%S).sql
# Automated Backup (Cron)
# /etc/cron.daily/postgres-backup
#!/bin/bash
docker exec db pg_dump -U postgres michaelschiemer_prod | gzip > /mnt/backups/michaelschiemer_$(date +%Y%m%d).sql.gz
```
### Volume Backup
```bash
# Backup all volumes
docker run --rm \
-v michaelschiemer_db_data:/data:ro \
-v $(pwd)/backups:/backup \
alpine tar czf /backup/db_data_$(date +%Y%m%d).tar.gz -C /data .
```
## Troubleshooting
### Service Won't Start
```bash
# Check logs
docker-compose -f docker-compose.yml \
-f docker-compose.production.yml \
logs <service>
# Check configuration
docker-compose -f docker-compose.yml \
-f docker-compose.production.yml \
config
```
### Health Check Failing
```bash
# Manual health check
docker exec php php-fpm-healthcheck
docker exec db pg_isready -U postgres
docker exec redis redis-cli ping
# Check health logs
docker inspect --format='{{json .State.Health}}' <container> | jq
```
### Memory Issues
```bash
# Check memory usage
docker stats
# Increase limits in docker-compose.production.yml
# Then restart service
docker-compose -f docker-compose.yml \
-f docker-compose.production.yml \
up -d --no-deps <service>
```
### Network Issues
```bash
# Check networks
docker network ls
docker network inspect michaelschiemer-prod_backend
# Test connectivity
docker exec php ping db
docker exec php nc -zv db 5432
```
## Security Considerations
### 1. Network Isolation
- ✅ Backend network is internal (no internet access)
- ✅ Cache network is internal
- ✅ Only frontend services expose ports
### 2. Volume Security
- ✅ No host mounts (application code in image)
- ✅ Read-only mounts where possible (SSL certificates)
- ✅ Named Docker volumes (managed by Docker)
### 3. Secrets Management
- ✅ Use `.env.production` (not committed to git)
- ✅ Use Vault for sensitive data
- ✅ No secrets in docker-compose files
### 4. Resource Limits
- ✅ All services have memory limits (prevent OOM)
- ✅ CPU limits prevent resource starvation
- ✅ Restart policies for automatic recovery
### 5. Logging
- ✅ JSON logging for security monitoring
- ✅ Log rotation prevents disk exhaustion
- ✅ Compressed logs for storage efficiency
## Best Practices
1. **Always use `.env.production`** - Never commit production secrets
2. **Test updates in staging first** - Use same docker-compose setup
3. **Monitor resource usage** - Adjust limits based on metrics
4. **Regular backups** - Automate database and volume backups
5. **Health checks** - Ensure all services have working health checks
6. **Log aggregation** - Send logs to centralized logging system (ELK)
7. **SSL renewal** - Monitor Certbot logs for renewal issues
8. **Security updates** - Regularly update Docker images
## See Also
- **Prerequisites**: `docs/deployment/production-prerequisites.md`
- **Environment Configuration**: `docs/deployment/env-production-template.md`
- **SSL Setup**: `docs/deployment/ssl-setup.md`
- **Database Migrations**: `docs/deployment/database-migration-strategy.md`
- **Logging Configuration**: `docs/deployment/logging-configuration.md`

View File

@@ -1,381 +0,0 @@
# Docker Swarm + Traefik Deployment Guide
Production deployment guide for the Custom PHP Framework using Docker Swarm orchestration with Traefik load balancer.
## Architecture Overview
```
Internet → Traefik (SSL Termination, Load Balancing)
[Web Service - 3 Replicas]
↓ ↓
Database Redis Queue Workers
(PostgreSQL) (Cache/Sessions) (2 Replicas)
```
**Key Components**:
- **Traefik v2.10**: Reverse proxy, SSL termination, automatic service discovery
- **Web Service**: 3 replicas of PHP-FPM + Nginx (HTTP only, Traefik handles HTTPS)
- **PostgreSQL 16**: Single instance database (manager node)
- **Redis 7**: Sessions and cache (manager node)
- **Queue Workers**: 2 replicas for background job processing
- **Docker Swarm**: Native container orchestration with rolling updates and health checks
## Prerequisites
1. **Docker Engine 28.0+** with Swarm mode enabled
2. **Production Server** with SSH access
3. **SSL Certificates** in `./ssl/` directory (cert.pem, key.pem)
4. **Environment Variables** in `.env` file on production server
5. **Docker Image** built and available
## Initial Setup
### 1. Initialize Docker Swarm
On production server:
```bash
docker swarm init
```
Verify:
```bash
docker node ls
# Should show 1 node as Leader
```
### 2. Create Docker Secrets
Create secrets from .env file values:
```bash
cd /home/deploy/framework
# Create secrets (one-time setup)
echo "$DB_PASSWORD" | docker secret create db_password -
echo "$APP_KEY" | docker secret create app_key -
echo "$VAULT_ENCRYPTION_KEY" | docker secret create vault_encryption_key -
echo "$SHOPIFY_WEBHOOK_SECRET" | docker secret create shopify_webhook_secret -
echo "$RAPIDMAIL_PASSWORD" | docker secret create rapidmail_password -
```
Or use the automated script:
```bash
./scripts/setup-production-secrets.sh
```
Verify secrets:
```bash
docker secret ls
```
### 3. Build and Transfer Docker Image
On local machine:
**Option A: Via Private Registry** (if available):
```bash
# Build image
docker build -f Dockerfile.production -t 94.16.110.151:5000/framework:latest .
# Push to registry
docker push 94.16.110.151:5000/framework:latest
```
**Option B: Direct Transfer via SSH** (recommended for now):
```bash
# Build image
docker build -f Dockerfile.production -t 94.16.110.151:5000/framework:latest .
# Save and transfer to production
docker save 94.16.110.151:5000/framework:latest | \
ssh -i ~/.ssh/production deploy@94.16.110.151 'docker load'
```
### 4. Deploy Stack
On production server:
```bash
cd /home/deploy/framework
# Deploy the stack
docker stack deploy -c docker-compose.prod.yml framework
# Monitor deployment
watch docker stack ps framework
# Check service status
docker stack services framework
```
## Health Monitoring
### Check Service Status
```bash
# List all services
docker stack services framework
# Check specific service
docker service ps framework_web
# View service logs
docker service logs framework_web -f
docker service logs framework_traefik -f
docker service logs framework_db -f
```
### Health Check Endpoints
- **Main Health**: http://localhost/health (via Traefik)
- **Traefik Dashboard**: http://traefik.localhost:8080 (manager node only)
### Expected Service Replicas
| Service | Replicas | Purpose |
|---------|----------|---------|
| traefik | 1 | Reverse proxy + SSL |
| web | 3 | Application servers |
| db | 1 | PostgreSQL database |
| redis | 1 | Cache + sessions |
| queue-worker | 2 | Background jobs |
## Rolling Updates
### Update Application
1. Build new image with updated code:
```bash
docker build -f Dockerfile.production -t 94.16.110.151:5000/framework:latest .
```
2. Transfer to production (if no registry):
```bash
docker save 94.16.110.151:5000/framework:latest | \
ssh -i ~/.ssh/production deploy@94.16.110.151 'docker load'
```
3. Update the service:
```bash
# On production server
docker service update --image 94.16.110.151:5000/framework:latest framework_web
```
The update will:
- Roll out to 1 container at a time (`parallelism: 1`)
- Wait 10 seconds between updates (`delay: 10s`)
- Start new container before stopping old one (`order: start-first`)
- Automatically rollback on failure (`failure_action: rollback`)
### Monitor Update Progress
```bash
# Watch update status
watch docker service ps framework_web
# View update logs
docker service logs framework_web -f --tail 50
```
### Manual Rollback
If needed, rollback to previous version:
```bash
docker service rollback framework_web
```
## Troubleshooting
### Service Won't Start
Check service logs:
```bash
docker service logs framework_web --tail 100
```
Check task failures:
```bash
docker service ps framework_web --no-trunc
```
### Container Crashing
Inspect individual container:
```bash
# Get container ID
docker ps -a | grep framework_web
# View logs
docker logs <container_id>
# Exec into running container
docker exec -it <container_id> bash
```
### SSL/TLS Issues
Traefik handles SSL termination. Check Traefik logs:
```bash
docker service logs framework_traefik -f
```
Verify SSL certificates are mounted in docker-compose.prod.yml:
```yaml
volumes:
- ./ssl:/ssl:ro
```
### Database Connection Issues
Check PostgreSQL health:
```bash
docker service logs framework_db --tail 50
# Exec into db container
docker exec -it $(docker ps -q -f name=framework_db) psql -U postgres -d framework_prod
```
### Redis Connection Issues
Check Redis availability:
```bash
docker service logs framework_redis --tail 50
# Test Redis connection
docker exec -it $(docker ps -q -f name=framework_redis) redis-cli ping
```
### Performance Issues
Check resource usage:
```bash
# Service resource limits
docker service inspect framework_web --format='{{json .Spec.TaskTemplate.Resources}}' | jq
# Container stats
docker stats
```
## Scaling
### Scale Web Service
```bash
# Scale up to 5 replicas
docker service scale framework_web=5
# Scale down to 2 replicas
docker service scale framework_web=2
```
### Scale Queue Workers
```bash
# Scale workers based on queue backlog
docker service scale framework_queue-worker=4
```
## Cleanup
### Remove Stack
```bash
# Remove entire stack
docker stack rm framework
# Verify removal
docker stack ls
```
### Remove Secrets
```bash
# List secrets
docker secret ls
# Remove specific secret
docker secret rm db_password
# Remove all framework secrets
docker secret ls | grep -E "db_password|app_key|vault_encryption_key" | awk '{print $2}' | xargs docker secret rm
```
### Leave Swarm
```bash
# Force leave Swarm (removes all services and secrets)
docker swarm leave --force
```
## Network Architecture
### Overlay Networks
- **traefik-public**: External network for Traefik ↔ Web communication
- **backend**: Internal network for Web ↔ Database/Redis communication
### Port Mappings
| Port | Service | Purpose |
|------|---------|---------|
| 80 | Traefik | HTTP (redirects to 443) |
| 443 | Traefik | HTTPS (production traffic) |
| 8080 | Traefik | Dashboard (manager node only) |
## Volume Management
### Named Volumes
| Volume | Purpose | Mounted In |
|--------|---------|------------|
| traefik-logs | Traefik access logs | traefik |
| storage-logs | Application logs | web, queue-worker |
| storage-uploads | User uploads | web |
| storage-queue | Queue data | queue-worker |
| db-data | PostgreSQL data | db |
| redis-data | Redis persistence | redis |
### Backup Volumes
```bash
# Backup database
docker exec $(docker ps -q -f name=framework_db) pg_dump -U postgres framework_prod > backup.sql
# Backup Redis (if persistence enabled)
docker exec $(docker ps -q -f name=framework_redis) redis-cli --rdb /data/dump.rdb
```
## Security Best Practices
1. **Secrets Management**: Never commit secrets to version control, use Docker Secrets
2. **Network Isolation**: Backend network is internal-only, no external access
3. **SSL/TLS**: Traefik enforces HTTPS, redirects HTTP → HTTPS
4. **Health Checks**: All services have health checks with automatic restart
5. **Resource Limits**: Production services have memory/CPU limits
6. **Least Privilege**: Containers run as www-data (not root) where possible
## Phase 2 - Monitoring (Coming Soon)
- Prometheus for metrics collection
- Grafana dashboards
- Automated PostgreSQL backups
- Email/Slack alerting
## Phase 3 - CI/CD (Coming Soon)
- Gitea Actions workflow
- Loki + Promtail for log aggregation
- Performance tuning
## Phase 4 - High Availability (Future)
- Multi-node Swarm cluster
- Varnish CDN cache layer
- PostgreSQL Primary/Replica with pgpool
- MinIO object storage
## References
- [Docker Swarm Documentation](https://docs.docker.com/engine/swarm/)
- [Traefik v2 Documentation](https://doc.traefik.io/traefik/)
- [Docker Secrets Management](https://docs.docker.com/engine/swarm/secrets/)

View File

@@ -0,0 +1,297 @@
# Gitea Secrets Setup - Vollständige Anleitung
## Problem: "Secrets" fehlt in Repository Settings
Wenn du unter **Repository → Settings** keine "Secrets" Option siehst, kann das verschiedene Gründe haben. Diese Anleitung zeigt alle Möglichkeiten, wie Secrets in Gitea konfiguriert werden können.
## 📍 Wo finde ich Secrets in Gitea?
### Option 1: Repository Secrets (Standard)
**Pfad:** `Repository → Settings → Secrets`
⚠️ **Falls diese Option fehlt:**
- Gitea Actions muss für das Repository aktiviert sein
- Benötigt Berechtigung: Repository Owner oder Admin
- Manche Gitea-Versionen haben Secrets an anderen Orten
### Option 2: Über Actions/Tabs
Manche Gitea-Versionen haben Secrets unter:
- **Repository → Settings → Actions → Secrets**
- **Repository → Actions → Secrets**
### Option 3: Organization/Admin Level
Falls Repository-Secrets nicht verfügbar sind, können Secrets auf Organisations-Level gesetzt werden:
1. **Als Admin:** `Site Administration → Actions → Secrets`
2. **Als Org-Owner:** `Organization Settings → Actions → Secrets`
### Option 4: Via Gitea API (Programmatisch)
Falls die UI-Option fehlt, können Secrets via API gesetzt werden:
```bash
# Siehe: scripts/setup-gitea-secrets.sh
```
## 🔍 Diagnose: Warum sehe ich keine Secrets-Option?
### Checkliste:
1. **Ist Gitea Actions aktiviert?**
- Gehe zu: **Site Administration → Actions → Settings**
- Stelle sicher, dass Actions aktiviert ist
2. **Hast du die richtigen Berechtigungen?**
- Du musst Repository Owner oder Admin sein
- Prüfe: **Repository → Settings → Collaborators**
3. **Welche Gitea-Version wird verwendet?**
- Neuere Versionen haben Secrets unter Repository → Settings → Secrets
- Ältere Versionen könnten andere Pfade haben
4. **Sind Actions für das Repository aktiviert?**
- Prüfe ob Workflows unter **Repository → Actions** sichtbar sind
- Falls nicht, müssen Actions für das Repository aktiviert werden
## 🛠️ Lösung: Secrets manuell setzen
### Methode 1: Via Gitea API (Empfohlen)
Wenn die UI-Option fehlt, verwende das Setup-Script:
```bash
# Script vorbereiten
cd /home/michael/dev/michaelschiemer
# Setze deine Gitea-Credentials
export GITEA_URL="https://git.michaelschiemer.de"
export GITEA_TOKEN="dein-gitea-token" # Siehe unten wie man einen Token erstellt
export REPO_OWNER="dein-username" # Oder Organization-Name
export REPO_NAME="michaelschiemer"
# Setze die Secrets
./scripts/setup-gitea-secrets.sh
```
**Gitea Token erstellen:**
1. Gehe zu: `https://git.michaelschiemer.de/user/settings/applications`
2. Scrolle zu "Generate New Token"
3. Name: z.B. "CI/CD Secrets Setup"
4. Scopes: `write:repository` (mindestens)
5. Klicke "Generate Token"
6. Kopiere den Token (wird nur einmal angezeigt!)
### Methode 2: Environment-Variablen im Runner (Alternative)
Falls Repository Secrets wirklich nicht verfügbar sind, können Secrets auch als Environment-Variablen im Runner konfiguriert werden:
**In `deployment/gitea-runner/docker-compose.yml`:**
```yaml
services:
gitea-runner:
environment:
- REGISTRY_USER=admin
- REGISTRY_PASSWORD=registry-secure-password-2025
# Weitere Secrets...
```
⚠️ **Nicht empfohlen:** Weniger sicher, da Secrets im docker-compose.yml gespeichert werden.
### Methode 3: Secrets im Workflow hardcoden (NICHT EMPFOHLEN!)
**⚠️ NIEMALS PASSWÖRTER IM CODE SPEICHERN!**
Diese Methode sollte nur für Tests verwendet werden und ist für Produktion unsicher.
## 📝 Schritt-für-Schritt: Secrets via API setzen
### Schritt 1: Gitea Token erstellen
1. Gehe zu: `https://git.michaelschiemer.de/user/settings/applications`
2. Scrolle zu "Generate New Token"
3. **Name:** `CI/CD Secrets Management`
4. **Scopes:** Wähle:
-`read:repository`
-`write:repository`
-`read:organization` (falls Org-Repo)
5. Klicke **"Generate Token"**
6. **Kopiere den Token sofort** (wird nur einmal angezeigt!)
### Schritt 2: Repository-Informationen finden
**Repository Owner:**
- Gehe zu deinem Repository: `https://git.michaelschiemer.de/[username]/michaelschiemer`
- Der erste Teil nach `/` ist der Owner (Username oder Org-Name)
**Repository Name:**
- Der zweite Teil ist der Repository-Name (meist `michaelschiemer`)
### Schritt 3: Setup-Script ausführen
```bash
cd /home/michael/dev/michaelschiemer
# Konfiguriere die Variablen
export GITEA_URL="https://git.michaelschiemer.de"
export GITEA_TOKEN="dein-token-hier"
export REPO_OWNER="dein-username"
export REPO_NAME="michaelschiemer"
export REGISTRY_PASSWORD="registry-secure-password-2025"
# Führe das Script aus
bash scripts/setup-gitea-secrets.sh
```
Das Script setzt automatisch:
- `REGISTRY_USER` = `admin`
- `REGISTRY_PASSWORD` = Wert von `$REGISTRY_PASSWORD`
- `SSH_PRIVATE_KEY` = aus `~/.ssh/production`
### Schritt 4: Verifizierung
Nach dem Ausführen des Scripts:
1. **Prüfe ob Secrets gesetzt wurden:**
```bash
# Teste mit einem Workflow
# Gehe zu: Repository → Actions → Test Registry Credentials → Run workflow
```
2. **Oder prüfe via API:**
```bash
curl -H "Authorization: token ${GITEA_TOKEN}" \
"${GITEA_URL}/api/v1/repos/${REPO_OWNER}/${REPO_NAME}/actions/secrets"
```
## 🔐 Alternative: Secrets in Runner Environment
Falls Repository Secrets gar nicht funktionieren, können Secrets auch als Environment-Variablen im Runner konfiguriert werden:
### Schritt 1: .env Datei erstellen
```bash
cd deployment/gitea-runner
cp .env.example .env
```
### Schritt 2: Secrets zur .env hinzufügen
```bash
nano .env
```
Füge hinzu:
```bash
REGISTRY_USER=admin
REGISTRY_PASSWORD=registry-secure-password-2025
# SSH_PRIVATE_KEY würde hier nicht gesetzt werden (zu lang)
```
### Schritt 3: docker-compose.yml anpassen
```yaml
services:
gitea-runner:
environment:
- REGISTRY_USER=${REGISTRY_USER:-admin}
- REGISTRY_PASSWORD=${REGISTRY_PASSWORD}
# ... rest of config
```
### Schritt 4: Workflow anpassen
Im Workflow müssen Secrets dann anders geladen werden:
```yaml
- name: Login to Registry
env:
REGISTRY_USER: ${REGISTRY_USER}
REGISTRY_PASSWORD: ${REGISTRY_PASSWORD}
run: |
# Secrets werden jetzt aus Runner Environment geladen
```
⚠️ **Nachteil:** Secrets sind dann im Runner-Environment und nicht repository-spezifisch.
## 🧪 Test ob Secrets funktionieren
### Test 1: Workflow ausführen
```bash
# Gehe zu: Repository → Actions → Test Registry Credentials → Run workflow
```
### Test 2: Debug-Output im Workflow
Füge temporär Debug-Output hinzu:
```yaml
- name: Debug Secrets
run: |
echo "REGISTRY_USER length: ${#REGISTRY_USER}"
echo "REGISTRY_PASSWORD length: ${#REGISTRY_PASSWORD}"
# Zeigt die Länge, nicht den Inhalt (für Sicherheit)
```
Wenn beide > 0 sind, funktionieren die Secrets.
### Test 3: Lokales Test-Script
```bash
export REGISTRY_USER="admin"
export REGISTRY_PASSWORD="registry-secure-password-2025"
./scripts/test-registry-credentials.sh
```
## 📚 Nützliche Links
- **Gitea Actions Docs:** https://docs.gitea.io/en-us/actions/
- **Secrets API:** https://docs.gitea.io/en-us/api-usage/#repository-secrets
- **Setup Script:** `scripts/setup-gitea-secrets.sh`
## ❓ Häufige Fragen
### Q: Warum sehe ich keine "Secrets" Option?
**A:** Mögliche Gründe:
1. Gitea Actions ist nicht aktiviert
2. Du hast nicht die nötigen Berechtigungen (Repository Owner/Admin)
3. Deine Gitea-Version hat Secrets an einem anderen Ort
4. Secrets müssen via API gesetzt werden
### Q: Kann ich Secrets für mehrere Repositories setzen?
**A:** Ja, über:
- **Organization Secrets:** Für alle Repos in der Organisation
- **API:** Script mehrmals ausführen mit verschiedenen `REPO_NAME`
### Q: Sind Secrets verschlüsselt?
**A:** Ja, Gitea verschlüsselt Secrets vor der Speicherung.
### Q: Wie ändere ich ein Secret?
**A:**
- Via UI: Bearbeiten (falls verfügbar)
- Via API: Script erneut ausführen (überschreibt das Secret)
- Via Script: `setup-gitea-secrets.sh` erneut ausführen
## 🚀 Quick Start
**Schnellste Methode (wenn API verfügbar):**
```bash
export GITEA_URL="https://git.michaelschiemer.de"
export GITEA_TOKEN="dein-token"
export REPO_OWNER="dein-username"
export REPO_NAME="michaelschiemer"
export REGISTRY_PASSWORD="registry-secure-password-2025"
bash scripts/setup-gitea-secrets.sh
```
Das war's! Secrets sollten jetzt funktionieren.

View File

@@ -1,800 +0,0 @@
# Production Deployment Guide
Umfassende Anleitung für das Deployment der Custom PHP Framework Anwendung auf dem Production Server.
## Inhaltsverzeichnis
1. [Architektur-Übersicht](#architektur-übersicht)
2. [Voraussetzungen](#voraussetzungen)
3. [Sicherheits-Setup](#sicherheits-setup)
4. [Docker Registry Setup](#docker-registry-setup)
5. [Production Image Build](#production-image-build)
6. [Deployment Prozess](#deployment-prozess)
7. [Troubleshooting](#troubleshooting)
8. [Monitoring](#monitoring)
---
## Architektur-Übersicht
### Development vs Production
**Development** (docker-compose.yml):
- Separate Container: Nginx + PHP-FPM
- Source Code via Volume Mounts
- Hot-Reload für Development
- Xdebug aktiviert
**Production** (docker-compose.prod.yml):
- Single Container: Supervisor → Nginx + PHP-FPM
- Code im Image eingebacken
- Minimale Volume Mounts (nur logs/uploads)
- Optimiert für Performance
### Production Stack
```
┌─────────────────────────────────────────────────┐
│ Production Server (94.16.110.151) │
│ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐│
│ │ Web │ │ PHP │ │ Redis ││
│ │ (Supervisor│ │ │ │ Cache ││
│ │ Nginx + │ │ │ │ ││
│ │ PHP-FPM) │ │ │ │ ││
│ └────────────┘ └────────────┘ └────────────┘│
│ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐│
│ │ PostgreSQL │ │ Queue │ │ Watchtower ││
│ │ Database │ │ Worker │ │ Auto-Update││
│ └────────────┘ └────────────┘ └────────────┘│
│ │
│ Monitoring (VPN-only): │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐│
│ │ Prometheus │ │ Grafana │ │ Portainer ││
│ │ :9090 │ │ :3000 │ │ :9443 ││
│ └────────────┘ └────────────┘ └────────────┘│
└─────────────────────────────────────────────────┘
│ WireGuard VPN (10.8.0.0/24)
┌───┴────┐
│ Client │
└────────┘
```
---
## Voraussetzungen
### Server Requirements
- **OS**: Ubuntu 22.04 LTS (oder neuer)
- **RAM**: Minimum 4GB (empfohlen: 8GB+)
- **CPU**: 2+ Cores
- **Disk**: 50GB+ freier Speicherplatz
- **Network**: Statische IP oder DNS
### Installierte Software
```bash
# Docker & Docker Compose
docker --version # 24.0+
docker-compose --version # 2.20+
# WireGuard (für sicheren Zugriff)
wg --version
# SSL Tools
openssl version
```
### Ports
**Public (Firewall offen)**:
- `8888`: HTTP (optional, für HTTP→HTTPS Redirect)
- `8443`: HTTPS (Hauptzugang)
- `51820`: WireGuard VPN (UDP)
**VPN-only (über 10.8.0.1)**:
- `9090`: Prometheus
- `3000`: Grafana
- `9443`: Portainer
**Internal (nicht extern erreichbar)**:
- `5432`: PostgreSQL
- `6379`: Redis
- `9000`: PHP-FPM
---
## Sicherheits-Setup
### 1. WireGuard VPN
WireGuard bietet verschlüsselten Zugang zum Production Server für Administration und Monitoring.
**Server Installation**:
```bash
# Als root auf Production Server
apt update
apt install -y wireguard
# Schlüssel generieren
cd /etc/wireguard
umask 077
wg genkey | tee server_private.key | wg pubkey > server_public.key
# Server Config
cat > /etc/wireguard/wg0.conf <<'EOF'
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = <server_private_key>
# Client (Development Machine)
[Peer]
PublicKey = <client_public_key>
AllowedIPs = 10.8.0.2/32
EOF
# Service starten
systemctl enable wg-quick@wg0
systemctl start wg-quick@wg0
systemctl status wg-quick@wg0
```
**Client Configuration** (`/etc/wireguard/wg0-production.conf`):
```ini
[Interface]
Address = 10.8.0.2/32
PrivateKey = <client_private_key>
DNS = 1.1.1.1
[Peer]
PublicKey = <server_public_key>
Endpoint = 94.16.110.151:51820
AllowedIPs = 10.8.0.0/24, 94.16.110.151/32
PersistentKeepalive = 25
```
**Client Start**:
```bash
sudo wg-quick up wg0-production
sudo wg show # Verify connection
ping 10.8.0.1 # Test connectivity
```
### 2. Firewall Configuration
**UFW Rules** (auf Production Server):
```bash
# Default policies
ufw default deny incoming
ufw default allow outgoing
# SSH (nur von spezifischen IPs)
ufw allow from <deine_ip> to any port 22
# WireGuard
ufw allow 51820/udp
# HTTP/HTTPS
ufw allow 8888/tcp # HTTP (optional)
ufw allow 8443/tcp # HTTPS
# Enable firewall
ufw enable
ufw status verbose
```
### 3. SSL/TLS Zertifikate
**Development/Testing** (Self-Signed):
```bash
# Bereits vorhanden in ./ssl/
# - cert.pem
# - key.pem
```
**Production** (Let's Encrypt empfohlen):
```bash
# Mit certbot
certbot certonly --standalone -d yourdomain.com
# Zertifikate nach ./ssl/ kopieren
```
---
## Docker Registry Setup
### Local Registry on Production Server
Für sichere, private Image-Verwaltung läuft eine lokale Docker Registry auf dem Production Server.
**Registry starten**:
```bash
docker run -d \
--restart=always \
--name registry \
-p 127.0.0.1:5000:5000 \
registry:2
```
**Verify**:
```bash
curl http://localhost:5000/v2/_catalog
```
**Registry in Docker konfigurieren**:
`/etc/docker/daemon.json`:
```json
{
"insecure-registries": ["94.16.110.151:5000"]
}
```
```bash
sudo systemctl restart docker
```
---
## Production Image Build
### Build-Prozess
Das Production Image wird lokal gebaut und dann zur Registry gepusht.
**1. Production Dockerfile** (`Dockerfile.production`):
```dockerfile
# Multi-stage build für optimale Image-Größe
FROM php:8.3-fpm-alpine AS base
# System dependencies
RUN apk add --no-cache \
nginx \
supervisor \
postgresql-dev \
libpq \
&& docker-php-ext-install pdo pdo_pgsql
# PHP Configuration
COPY docker/php/php.production.ini /usr/local/etc/php/conf.d/production.ini
COPY docker/php/opcache.ini /usr/local/etc/php/conf.d/opcache.ini
COPY docker/php/zz-docker.production.conf /usr/local/etc/php-fpm.d/zz-docker.conf
# Nginx Configuration
COPY docker/nginx/nginx.production.conf /etc/nginx/nginx.conf
COPY docker/nginx/default.production.conf /etc/nginx/http.d/default.conf
# Supervisor Configuration
COPY docker/supervisor/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# Application Code
WORKDIR /var/www/html
COPY --chown=www-data:www-data . .
# Composer dependencies (Production only)
RUN composer install --no-dev --optimize-autoloader --no-interaction
# NPM build
RUN npm ci && npm run build
# Permissions
RUN chown -R www-data:www-data /var/www/html/storage \
&& chmod -R 775 /var/www/html/storage
# Start Supervisor (manages nginx + php-fpm)
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
```
**2. Build Command**:
```bash
# Im Projekt-Root
docker build \
-f Dockerfile.production \
-t 94.16.110.151:5000/framework:latest \
.
```
**3. Push to Registry**:
```bash
docker push 94.16.110.151:5000/framework:latest
```
**4. Verify Push**:
```bash
curl http://94.16.110.151:5000/v2/framework/tags/list
```
### Wichtige Konfigurationsdateien
#### Supervisor Configuration (`docker/supervisor/supervisord.conf`)
```ini
[supervisord]
nodaemon=true
silent=false
logfile=/dev/null
logfile_maxbytes=0
pidfile=/var/run/supervisord.pid
loglevel=info
[program:php-fpm]
command=php-fpm -F
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
autorestart=true
startretries=3
[program:nginx]
command=nginx -g 'daemon off;'
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
autorestart=true
startretries=3
depends_on=php-fpm
```
**Wichtige Änderungen**:
- `silent=false` + `logfile=/dev/null`: Supervisor loggt nach stdout/stderr statt Datei
- Grund: Python's logging kann `/dev/stdout` oder `/proc/self/fd/1` nicht im append-mode öffnen
#### PHP-FPM Production Config (`docker/php/zz-docker.production.conf`)
```ini
[www]
user = www-data
group = www-data
listen = 9000
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500
```
**Wichtig**: User/Group explizit auf `www-data` setzen, da Container als root läuft.
---
## Deployment Prozess
### Docker Compose Setup
**Base Configuration** (`docker-compose.yml`):
- Definiert alle Services für Development
- Wird **nicht** auf Production Server deployed
**Production Overrides** (`docker-compose.prod.yml`):
- Merged mit base config
- Production-spezifische Einstellungen
### Production Override Highlights
**Web Service**:
```yaml
web:
image: 94.16.110.151:5000/framework:latest
pull_policy: always # Immer von Registry pullen, nie bauen
entrypoint: [] # Entrypoint von Base-Image clearen
command: ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
user: root # Container läuft als root, PHP-FPM workers als www-data
volumes:
- ./storage/logs:/var/www/html/storage/logs:rw
- ./storage/uploads:/var/www/html/storage/uploads:rw
- ./ssl:/var/www/ssl:ro
environment:
- APP_ENV=production
labels:
com.centurylinklabs.watchtower.enable: "true"
```
**Wichtige Overrides**:
1. `pull_policy: always`: Verhindert lokales Build, zwingt Registry-Pull
2. `entrypoint: []`: Clearen des inherited entrypoint vom Base PHP-Image
3. `command: [...]`: Expliziter Start-Command für Supervisor
4. `user: root`: Nötig für Supervisor, PHP-FPM läuft intern als www-data
### Deployment Steps
**1. Files auf Server kopieren**:
```bash
# Lokale Entwicklungsmaschine (via WireGuard)
scp docker-compose.prod.yml deploy@94.16.110.151:/home/deploy/framework/
scp .env.production deploy@94.16.110.151:/home/deploy/framework/.env
```
**2. Auf Server: Pull und Deploy**:
```bash
# SSH auf Production Server
ssh deploy@94.16.110.151
# In Projekt-Verzeichnis
cd /home/deploy/framework
# Pull latest image
docker pull 94.16.110.151:5000/framework:latest
# Deploy Stack
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
# Check Status
docker-compose -f docker-compose.yml -f docker-compose.prod.yml ps
```
**3. Logs überwachen**:
```bash
# Alle Container
docker-compose -f docker-compose.yml -f docker-compose.prod.yml logs -f
# Spezifischer Container
docker logs -f web
docker logs -f php
```
### Deployment Verification
**Container Health Checks**:
```bash
# Alle Container sollten "healthy" sein
docker-compose ps
# Output sollte zeigen:
# web Up (healthy)
# php Up (healthy)
# db Up (healthy)
# redis Up (healthy)
```
**Supervisor Status (im web container)**:
```bash
docker exec web supervisorctl status
# Output:
# nginx RUNNING pid 7, uptime 0:05:23
# php-fpm RUNNING pid 8, uptime 0:05:23
```
**Nginx & PHP-FPM Processes**:
```bash
docker exec web ps aux | grep -E 'nginx|php-fpm'
# Sollte zeigen:
# root 1 supervisor
# root 7 nginx: master
# www-data nginx: worker (mehrere)
# root 8 php-fpm: master
# www-data php-fpm: pool www (mehrere)
```
**Application Test**:
```bash
# Von lokalem Rechner (via WireGuard)
curl -k -I https://94.16.110.151:8443/
# Erwartete Response:
# HTTP/2 200
# server: nginx
# content-type: text/html
```
---
## Troubleshooting
### Problem 1: Supervisor Log File Permission Denied
**Symptom**:
```
PermissionError: [Errno 13] Permission denied: '/var/log/supervisor/supervisord.log'
```
**Ursache**: Supervisor kann nicht in `/var/log/supervisor/` schreiben, selbst als root.
**Lösung**: `supervisord.conf` ändern:
```ini
silent=false
logfile=/dev/null
logfile_maxbytes=0
```
**Grund**: Python's logging library kann `/dev/stdout` oder `/proc/self/fd/1` nicht im append-mode öffnen. `/dev/null` + `silent=false` macht Supervisor's logging auf stdout/stderr.
### Problem 2: EACCES Errors in Web Container
**Symptom**:
```
CRIT could not write pidfile /var/run/supervisord.pid
spawnerr: unknown error making dispatchers for 'nginx': EACCES
```
**Ursache**: Web container läuft nicht als root, sondern mit inherited user von base config.
**Lösung**: `docker-compose.prod.yml` - `user: root` setzen:
```yaml
web:
user: root
```
### Problem 3: Docker Entrypoint Override funktioniert nicht
**Symptom**: Container command zeigt entrypoint prepended:
```
/usr/local/bin/docker-entrypoint.sh /usr/bin/supervisord -c ...
```
**Ursache**: Base `docker-compose.yml` hat `web` service mit separate build context. Inherited ENTRYPOINT vom Base PHP-Image wird prepended.
**Lösung**: Explizit entrypoint clearen:
```yaml
web:
image: 94.16.110.151:5000/framework:latest
pull_policy: always
entrypoint: [] # WICHTIG: Entrypoint clearen
command: ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
```
### Problem 4: Queue Worker restarts kontinuierlich
**Symptom**:
```
docker ps # zeigt queue-worker als "Restarting"
```
**Ursache**: Base `docker-compose.yml` command sucht `/var/www/html/worker.php` das nicht existiert.
**Temporary Fix**: Service deaktivieren in `docker-compose.prod.yml`:
```yaml
queue-worker:
deploy:
replicas: 0
```
**Proper Fix**: Richtigen Worker-Command konfigurieren:
```yaml
queue-worker:
command: ["php", "/var/www/html/console.php", "queue:work"]
```
### Problem 5: HTTP Port 80 nicht erreichbar
**Symptom**: `curl http://94.16.110.151:8888/` → Connection refused
**Mögliche Ursachen**:
1. Nginx nicht auf Port 80 listening (nur 443)
2. Firewall blockiert Port 8888
3. Intentional (HTTPS-only Configuration)
**Debug**:
```bash
# Im Container checken
docker exec web netstat -tlnp | grep :80
# Nginx config testen
docker exec web nginx -t
# Nginx config anschauen
docker exec web cat /etc/nginx/http.d/default.conf
```
**Fix (falls HTTP→HTTPS Redirect gewünscht)**:
In `docker/nginx/default.production.conf`:
```nginx
server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}
```
---
## Monitoring
### Prometheus
**Zugang**: http://10.8.0.1:9090 (nur via WireGuard)
**Konfiguration**: `monitoring/prometheus/prometheus.yml`
**Scraped Targets**:
- Framework Application Metrics
- Container Metrics (cAdvisor)
- Node Exporter (Server Metrics)
### Grafana
**Zugang**: http://10.8.0.1:3000 (nur via WireGuard)
**Default Login**:
- User: `admin`
- Password: `${GRAFANA_PASSWORD}` (aus `.env`)
**Dashboards**: `monitoring/grafana/provisioning/dashboards/`
### Portainer
**Zugang**: https://10.8.0.1:9443 (nur via WireGuard)
**Features**:
- Container Management
- Stack Deployment
- Log Viewing
- Resource Usage
### Watchtower Auto-Update
Watchtower überwacht Container mit Label `com.centurylinklabs.watchtower.enable: "true"` und updated sie automatisch bei neuen Images.
**Konfiguration**:
```yaml
watchtower:
environment:
WATCHTOWER_CLEANUP: "true"
WATCHTOWER_POLL_INTERVAL: 300 # 5 Minuten
WATCHTOWER_LABEL_ENABLE: "true"
WATCHTOWER_NOTIFICATIONS: "shoutrrr"
WATCHTOWER_NOTIFICATION_URL: "${WATCHTOWER_NOTIFICATION_URL}"
```
**Monitoren**:
```bash
docker logs -f watchtower
```
---
## Maintenance
### Image Updates
**1. Lokal neues Image bauen**:
```bash
docker build -f Dockerfile.production -t 94.16.110.151:5000/framework:latest .
docker push 94.16.110.151:5000/framework:latest
```
**2. Auf Server**:
```bash
# Watchtower erkennt Update automatisch innerhalb von 5 Minuten
# Oder manuell:
docker-compose -f docker-compose.yml -f docker-compose.prod.yml pull
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
```
### Database Backups
```bash
# Manual Backup
docker exec db pg_dump -U framework_user framework_db > backup_$(date +%Y%m%d_%H%M%S).sql
# Automated (via cron)
0 2 * * * /home/deploy/scripts/backup-database.sh
```
### Log Rotation
Logs in `./storage/logs/` automatisch rotieren:
```bash
# /etc/logrotate.d/framework
/home/deploy/framework/storage/logs/*.log {
daily
rotate 14
compress
delaycompress
notifempty
missingok
create 0640 www-data www-data
}
```
### SSL Certificate Renewal
**Let's Encrypt** (automatisch via certbot):
```bash
certbot renew --deploy-hook "docker exec web nginx -s reload"
```
---
## Security Checklist
- [ ] WireGuard VPN konfiguriert und aktiv
- [ ] Firewall (UFW) konfiguriert und enabled
- [ ] Nur benötigte Ports offen (8443, 51820)
- [ ] Monitoring nur via VPN erreichbar (10.8.0.1:*)
- [ ] SSL/TLS Zertifikate gültig
- [ ] `.env` Secrets nicht in Git committed
- [ ] Database Credentials rotiert
- [ ] Redis Password gesetzt
- [ ] Docker Registry läuft lokal (nicht public)
- [ ] Container laufen mit minimal privileges
- [ ] Watchtower auto-updates aktiviert
- [ ] Backup-Strategie implementiert
- [ ] Log monitoring aktiv
---
## Performance Tuning
### PHP-FPM
`docker/php/zz-docker.production.conf`:
```ini
pm.max_children = 50 # Max. gleichzeitige Requests
pm.start_servers = 10 # Initial workers
pm.min_spare_servers = 5 # Min. idle workers
pm.max_spare_servers = 20 # Max. idle workers
pm.max_requests = 500 # Worker recycling
```
**Tuning basierend auf RAM**:
- 4GB RAM: max_children = 30
- 8GB RAM: max_children = 50
- 16GB RAM: max_children = 100
### OPcache
`docker/php/opcache.ini`:
```ini
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.validate_timestamps=0 # Production: keine Timestamp-Checks
opcache.revalidate_freq=0
```
### Nginx
```nginx
worker_processes auto;
worker_connections 1024;
keepalive_timeout 65;
client_max_body_size 20M;
```
---
## Contact & Support
**Production Server**: 94.16.110.151
**VPN Gateway**: 10.8.0.1
**Documentation**: `/home/deploy/framework/docs/`
**Issue Tracker**: [GitHub/GitLab URL]
---
## Change Log
### 2025-10-28 - Initial Production Deployment
**Changes**:
- Supervisor logging: `/dev/null` + `silent=false`
- docker-compose.prod.yml: `user: root` für web, php, queue-worker
- docker-compose.prod.yml: `entrypoint: []` für web service
- docker-compose.prod.yml: `pull_policy: always` für registry images
**Deployed**:
- Image: `94.16.110.151:5000/framework:latest`
- Digest: `sha256:eee1db20b9293cf611f53d01de68e94df1cfb3c748fe967849e080d19b9e4c8b`
**Status**: ✅ Deployment erfolgreich, Container healthy

View File

@@ -1,227 +0,0 @@
# Quick Deploy Guide
Schnellanleitung für Production Deployments.
## Voraussetzungen
- WireGuard VPN aktiv: `sudo wg-quick up wg0-production`
- SSH-Zugang konfiguriert
- Docker Registry läuft auf Production Server
## Deployment in 5 Schritten
### 1. Image bauen und pushen
```bash
# Im Projekt-Root
docker build -f Dockerfile.production -t 94.16.110.151:5000/framework:latest .
docker push 94.16.110.151:5000/framework:latest
```
**Verify Push**:
```bash
curl http://94.16.110.151:5000/v2/framework/tags/list
```
### 2. Config-Files auf Server kopieren
```bash
# Falls docker-compose.prod.yml oder .env geändert wurden
scp docker-compose.prod.yml deploy@94.16.110.151:/home/deploy/framework/
scp .env.production deploy@94.16.110.151:/home/deploy/framework/.env
```
### 3. Auf Server deployen
```bash
ssh deploy@94.16.110.151
cd /home/deploy/framework
# Pull und Deploy
docker-compose -f docker-compose.yml -f docker-compose.prod.yml pull
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
```
### 4. Status checken
```bash
# Container Status
docker-compose -f docker-compose.yml -f docker-compose.prod.yml ps
# Logs anschauen
docker-compose -f docker-compose.yml -f docker-compose.prod.yml logs -f web php
# Supervisor Status (im web container)
docker exec web supervisorctl status
```
### 5. Application testen
```bash
# Von lokaler Maschine (via WireGuard)
curl -k -I https://94.16.110.151:8443/
# Erwartetes Ergebnis:
# HTTP/2 200
# server: nginx
```
## Rollback
Falls Probleme auftreten:
```bash
# Auf Server
cd /home/deploy/framework
# Vorheriges Image ID finden
docker images 94.16.110.151:5000/framework
# Zu spezifischem Image wechseln
docker-compose -f docker-compose.yml -f docker-compose.prod.yml down
docker tag 94.16.110.151:5000/framework@sha256:<old-digest> 94.16.110.151:5000/framework:latest
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
```
## Monitoring URLs
**Zugang nur via WireGuard VPN (10.8.0.1)**:
- Prometheus: http://10.8.0.1:9090
- Grafana: http://10.8.0.1:3000 (admin / $GRAFANA_PASSWORD)
- Portainer: https://10.8.0.1:9443
## Watchtower Auto-Updates
Watchtower überwacht automatisch und updated Container mit neuem Image (alle 5 Minuten).
**Status checken**:
```bash
docker logs watchtower
```
**Manuell triggern**:
```bash
# Watchtower neu starten (triggert sofortigen Check)
docker restart watchtower
```
## Troubleshooting
### Container nicht healthy
```bash
# Logs anschauen
docker logs web
docker logs php
# Im Container debuggen
docker exec -it web sh
docker exec -it php sh
# Supervisor Status
docker exec web supervisorctl status
# Nginx/PHP-FPM Prozesse
docker exec web ps aux | grep -E 'nginx|php-fpm'
```
### Database Connection Issues
```bash
# PostgreSQL Connection testen
docker exec php php -r "new PDO('pgsql:host=db;dbname=framework_db', 'framework_user', 'password');"
# Database Logs
docker logs db
# In Database connecten
docker exec -it db psql -U framework_user -d framework_db
```
### Redis Connection Issues
```bash
# Redis Connection testen
docker exec php php -r "var_dump((new Redis())->connect('redis', 6379));"
# Redis Logs
docker logs redis
# Redis CLI
docker exec -it redis redis-cli
```
## Maintenance Commands
### Database Backup
```bash
# Manual Backup
docker exec db pg_dump -U framework_user framework_db > backup_$(date +%Y%m%d_%H%M%S).sql
```
### Logs Cleanup
```bash
# Storage Logs leeren (auf Server)
docker exec web sh -c 'rm -rf /var/www/html/storage/logs/*.log'
# Docker Logs cleanup
docker system prune -f
docker volume prune -f
```
### Image Cleanup
```bash
# Alte Images entfernen
docker image prune -a -f
# Nur untagged images
docker image prune -f
```
## Performance Check
```bash
# Container Resource Usage
docker stats
# PHP-FPM Status
docker exec web curl http://localhost/php-fpm-status
# Nginx Status
docker exec web curl http://localhost/nginx-status
# Database Connections
docker exec db psql -U framework_user -d framework_db -c "SELECT count(*) FROM pg_stat_activity;"
```
## SSL Certificate Renewal
```bash
# Let's Encrypt Renewal (auf Server als root)
certbot renew
docker exec web nginx -s reload
```
## Nützliche Aliases
Füge zu `~/.bashrc` auf Production Server hinzu:
```bash
alias dc='docker-compose -f docker-compose.yml -f docker-compose.prod.yml'
alias dcup='dc up -d'
alias dcdown='dc down'
alias dcps='dc ps'
alias dclogs='dc logs -f'
alias dcrestart='dc restart'
```
Dann kannst du einfach verwenden:
```bash
dcup # Deploy
dcps # Status
dclogs # Logs anschauen
```

View File

@@ -0,0 +1,197 @@
# Docker Registry Credentials Testen
Dieses Dokument erklärt, wie du die Docker Registry Credentials testen kannst.
## Lokales Testen
### Voraussetzungen
1. Docker muss installiert und laufend sein
2. Curl muss verfügbar sein (wird automatisch installiert falls fehlend)
### Verwendung
```bash
# Setze die Credentials als Environment-Variablen
export REGISTRY_USER="admin"
export REGISTRY_PASSWORD="dein-registry-passwort"
# Führe das Test-Script aus
./scripts/test-registry-credentials.sh
```
### Mit expliziten Werten
```bash
REGISTRY_USER="admin" \
REGISTRY_PASSWORD="dein-passwort" \
REGISTRY_DOMAIN="registry.michaelschiemer.de" \
REGISTRY_HOST="94.16.110.151" \
REGISTRY_PORT="5000" \
./scripts/test-registry-credentials.sh
```
## Was wird getestet?
Das Script führt folgende Tests durch:
### 1. HTTP Connectivity
- Testet ob die Registry über HTTP erreichbar ist (`http://94.16.110.151:5000`)
- Erwartet Status 401 (Auth erforderlich) oder 200
### 2. HTTPS Connectivity
- Testet ob die Registry über HTTPS erreichbar ist (`https://registry.michaelschiemer.de`)
- Erwartet Status 401 (Auth erforderlich) oder 200
### 3. Docker Login über HTTP
- Versucht Docker Login über HTTP
- Benötigt `insecure-registry` Konfiguration im Docker-daemon
### 4. Docker Login über HTTPS
- Versucht Docker Login über HTTPS
- Keine zusätzliche Konfiguration nötig (empfohlen)
### 5. Registry API Zugriff
- Testet ob die Registry API funktioniert
- Listet verfügbare Repositories auf
## Test in CI/CD
### Via Gitea Workflow
Das Script kann auch in einem Gitea Workflow verwendet werden:
```yaml
- name: Test Registry Credentials
shell: bash
env:
REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
run: |
./scripts/test-registry-credentials.sh
```
### Workflow ausführen
Es gibt einen dedizierten Workflow `.gitea/workflows/test-registry.yml`:
1. Gehe zu: **Actions****Test Registry Credentials**
2. Klicke auf **Run workflow**
3. Der Workflow testet automatisch die Credentials aus Gitea Secrets
## Troubleshooting
### Problem: "REGISTRY_PASSWORD ist nicht gesetzt"
**Lösung:**
```bash
export REGISTRY_PASSWORD="dein-passwort"
```
### Problem: "Unauthorized (401)" beim Login
**Ursache:** Falsche Credentials
**Lösung:**
1. Prüfe `REGISTRY_USER` - sollte `admin` sein (oder der richtige Username)
2. Prüfe `REGISTRY_PASSWORD` - muss mit dem Passwort in `deployment/stacks/registry/auth/htpasswd` übereinstimmen
3. Prüfe Gitea Secrets:
- Repository → Settings → Secrets
- Stelle sicher, dass `REGISTRY_USER` und `REGISTRY_PASSWORD` korrekt sind
### Problem: "HTTP response to HTTPS client"
**Ursache:** Docker versucht HTTPS, aber Registry läuft auf HTTP
**Lösung:**
- Für HTTP: Docker-daemon muss mit `--insecure-registry` konfiguriert werden
- Oder verwende HTTPS-Zugriff über `registry.michaelschiemer.de` (empfohlen)
### Problem: "Registry nicht erreichbar"
**Ursache:** Registry läuft nicht oder Netzwerk-Problem
**Lösung:**
```bash
# Prüfe ob Registry läuft
docker ps | grep registry
# Prüfe Registry-Logs
docker logs registry
# Prüfe Netzwerk
curl -v http://94.16.110.151:5000/v2/
```
### Problem: "404" bei HTTPS
**Ursache:** Traefik-Routing ist nicht richtig konfiguriert
**Lösung:**
1. Prüfe Traefik Labels in `deployment/stacks/registry/docker-compose.yml`
2. Prüfe ob Registry im `traefik-public` Netzwerk ist
3. Prüfe DNS-Konfiguration für `registry.michaelschiemer.de`
## Passwort prüfen/ändern
### Passwort auf dem Server prüfen
```bash
ssh deploy@94.16.110.151
cd ~/deployment/stacks/registry
cat auth/htpasswd
```
### Neues Passwort setzen
```bash
ssh deploy@94.16.110.151
cd ~/deployment/stacks/registry
# Neues Passwort setzen
htpasswd -B auth/htpasswd admin
# Registry neu starten
docker compose restart registry
```
Dann in Gitea Secrets aktualisieren:
- Repository → Settings → Secrets
- `REGISTRY_PASSWORD` mit neuem Passwort aktualisieren
## Script-Output
### Erfolgreich
```
✅ Docker ist verfügbar
✅ curl ist verfügbar
✅ Registry erreichbar über HTTPS (Status: 401 - Auth erforderlich, das ist gut!)
✅ Docker Login erfolgreich!
✅ Credentials sind korrekt und funktionieren!
```
### Fehlgeschlagen
```
❌ Docker Login fehlgeschlagen (Exit Code: 1)
⚠️ Fehler: Unauthorized (401)
Die Credentials sind falsch:
- Username: admin
- Password Länge: 24 Zeichen
```
## Integration in CI/CD
Das Script kann in jedem Workflow-Step verwendet werden:
```yaml
- name: Verify Registry Access
env:
REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
run: |
./scripts/test-registry-credentials.sh
```
Falls das Script fehlschlägt (Exit Code 1), wird der Workflow gestoppt und du bekommst klare Fehlermeldungen.

View File

@@ -1,581 +0,0 @@
# Production Deployment Troubleshooting Checklist
Systematische Problemlösung für häufige Deployment-Issues.
## Issue 1: Supervisor Log File Permission Denied
### Symptom
```
PermissionError: [Errno 13] Permission denied: '/var/log/supervisor/supervisord.log'
```
Container startet nicht, Supervisor kann Logfile nicht schreiben.
### Diagnose
```bash
docker logs web # Zeigt Permission Error
docker exec web ls -la /var/log/supervisor/ # Directory existiert nicht oder keine Permissions
```
### Root Cause
- Supervisor versucht in `/var/log/supervisor/supervisord.log` zu schreiben
- Directory existiert nicht oder keine Write-Permissions
- Auch als root problematisch in containerisierter Umgebung
### Lösung 1 (FUNKTIONIERT NICHT)
**Versuch**: `/proc/self/fd/1` verwenden
`docker/supervisor/supervisord.conf`:
```ini
logfile=/proc/self/fd/1
```
**Fehler**: `PermissionError: [Errno 13] Permission denied: '/proc/self/fd/1'`
**Grund**: Python's logging library (verwendet von Supervisor) kann `/proc/self/fd/1` oder `/dev/stdout` nicht im append-mode öffnen.
### Lösung 2 (ERFOLGREICH)
**Fix**: `/dev/null` mit `silent=false`
`docker/supervisor/supervisord.conf`:
```ini
[supervisord]
nodaemon=true
silent=false # WICHTIG: Logging trotz /dev/null
logfile=/dev/null
logfile_maxbytes=0
pidfile=/var/run/supervisord.pid
loglevel=info
```
**Warum funktioniert das?**
- `logfile=/dev/null`: Kein File-Logging
- `silent=false`: Supervisor loggt nach stdout/stderr
- Logs erscheinen in `docker logs web`
### Verification
```bash
docker logs web
# Output:
# 2025-10-28 16:29:59,976 INFO supervisord started with pid 1
# 2025-10-28 16:30:00,980 INFO spawned: 'nginx' with pid 7
# 2025-10-28 16:30:00,982 INFO spawned: 'php-fpm' with pid 8
# 2025-10-28 16:30:02,077 INFO success: nginx entered RUNNING state
# 2025-10-28 16:30:02,077 INFO success: php-fpm entered RUNNING state
```
### Related Files
- `docker/supervisor/supervisord.conf`
- `Dockerfile.production` (COPY supervisord.conf)
---
## Issue 2: Web Container EACCES Errors
### Symptom
```
2025-10-28 16:16:52,152 CRIT could not write pidfile /var/run/supervisord.pid
2025-10-28 16:16:53,154 INFO spawnerr: unknown error making dispatchers for 'nginx': EACCES
2025-10-28 16:16:53,154 INFO spawnerr: unknown error making dispatchers for 'php-fpm': EACCES
```
### Diagnose
```bash
# Container User checken
docker exec web whoami
# Falls nicht "root", dann ist das der Issue
# Docker Compose Config checken
docker inspect web | grep -i user
# Zeigt inherited user von base config
```
### Root Cause
- `web` service in `docker-compose.prod.yml` hat **kein** `user: root` gesetzt
- Inherited `user: 1000:1000` oder `user: www-data` von base `docker-compose.yml`
- Supervisor benötigt root um nginx/php-fpm master processes zu starten
### Lösung
**Fix**: `user: root` explizit setzen
`docker-compose.prod.yml`:
```yaml
web:
image: 94.16.110.151:5000/framework:latest
user: root # ← HINZUFÜGEN
# ... rest der config
```
Auch für `php` und `queue-worker` services hinzufügen:
```yaml
php:
image: 94.16.110.151:5000/framework:latest
user: root # ← HINZUFÜGEN
queue-worker:
image: 94.16.110.151:5000/framework:latest
user: root # ← HINZUFÜGEN
```
### Warum user: root?
- **Container läuft als root**: Supervisor master process
- **Nginx master**: root (worker processes als www-data via nginx.conf)
- **PHP-FPM master**: root (pool workers als www-data via php-fpm.conf)
`docker/php/zz-docker.production.conf`:
```ini
[www]
user = www-data # ← Worker processes laufen als www-data
group = www-data
```
### Verification
```bash
docker exec web whoami
# root
docker exec web ps aux | grep -E 'nginx|php-fpm'
# root 1 supervisord
# root 7 nginx: master process
# www-data 10 nginx: worker process
# root 8 php-fpm: master process
# www-data 11 php-fpm: pool www
```
### Related Files
- `docker-compose.prod.yml` (web, php, queue-worker services)
- `docker/php/zz-docker.production.conf`
- `docker/nginx/nginx.production.conf`
---
## Issue 3: Docker Entrypoint Override funktioniert nicht
### Symptom
Container command zeigt Entrypoint prepended:
```bash
docker ps
# COMMAND: "/usr/local/bin/docker-entrypoint.sh /usr/bin/supervisord -c ..."
```
Supervisor wird nicht direkt gestartet, sondern durch einen wrapper script.
### Diagnose
```bash
# Container Command checken
docker inspect web --format='{{.Config.Entrypoint}}'
# [/usr/local/bin/docker-entrypoint.sh]
docker inspect web --format='{{.Config.Cmd}}'
# [/usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf]
```
### Root Cause
1. Base `docker-compose.yml` hat `web` service mit separate build:
```yaml
web:
build:
context: docker/nginx
dockerfile: Dockerfile
```
2. Production override setzt `image:` aber cleared **nicht** den inherited ENTRYPOINT:
```yaml
web:
image: 94.16.110.151:5000/framework:latest
command: ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
```
3. Base PHP image hat ENTRYPOINT der prepended wird
4. Docker Compose merge: ENTRYPOINT + CMD = final command
### Lösung - Iteration 1 (FUNKTIONIERT NICHT)
❌ **Versuch**: Nur `command:` setzen
`docker-compose.prod.yml`:
```yaml
web:
image: 94.16.110.151:5000/framework:latest
command: ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
```
**Result**: Entrypoint wird trotzdem prepended
### Lösung - Iteration 2 (FUNKTIONIERT NICHT)
❌ **Versuch**: `pull_policy: always` hinzufügen
`docker-compose.prod.yml`:
```yaml
web:
image: 94.16.110.151:5000/framework:latest
pull_policy: always # Force registry pull
command: ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
```
**Result**: Image wird von Registry gepullt, aber Entrypoint wird trotzdem prepended
### Lösung - Iteration 3 (ERFOLGREICH)
✅ **Fix**: `entrypoint: []` explizit clearen
`docker-compose.prod.yml`:
```yaml
web:
image: 94.16.110.151:5000/framework:latest
pull_policy: always # Always pull from registry, never build
entrypoint: [] # ← WICHTIG: Entrypoint clearen
command: ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
user: root
```
**Warum `entrypoint: []`?**
- Leeres Array cleared den inherited entrypoint komplett
- `command:` wird dann direkt als PID 1 gestartet
- Keine wrapper scripts, keine indirection
### Verification
```bash
docker inspect web --format='{{.Config.Entrypoint}}'
# [] ← Leer!
docker inspect web --format='{{.Config.Cmd}}'
# [/usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf]
docker exec web ps aux
# PID 1: /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
# Kein entrypoint wrapper!
```
### Related Files
- `docker-compose.prod.yml` (web service)
### Docker Compose Override Rules
```
Base Config + Override = Final Config
Base:
web:
build: docker/nginx
→ inherited ENTRYPOINT from base image
Override (insufficient):
web:
image: 94.16.110.151:5000/framework:latest
command: [...]
→ ENTRYPOINT still prepended to command
Override (correct):
web:
image: 94.16.110.151:5000/framework:latest
entrypoint: [] ← Clears inherited entrypoint
command: [...] ← Runs directly as PID 1
```
---
## Issue 4: Queue Worker Container Restarts
### Symptom
```bash
docker ps
# queue-worker Restarting (1) 5 seconds ago
```
Container restart loop, nie healthy.
### Diagnose
```bash
docker logs queue-worker
# Error: /var/www/html/worker.php not found
# oder
# php: command not found
```
### Root Cause
Base `docker-compose.yml` hat Queue Worker Command für Development:
```yaml
queue-worker:
command: ["php", "/var/www/html/worker.php"]
```
`worker.php` existiert nicht im Production Image.
### Lösung - Option 1: Service deaktivieren
✅ **Quick Fix**: Queue Worker deaktivieren
`docker-compose.prod.yml`:
```yaml
queue-worker:
deploy:
replicas: 0 # Disable service
```
### Lösung - Option 2: Richtigen Command setzen
✅ **Proper Fix**: Console Command verwenden
`docker-compose.prod.yml`:
```yaml
queue-worker:
image: 94.16.110.151:5000/framework:latest
user: root
command: ["php", "/var/www/html/console.php", "queue:work"]
# oder für Supervisor-managed:
# entrypoint: []
# command: ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/queue-worker-supervisord.conf"]
```
### Verification
```bash
docker logs queue-worker
# [timestamp] INFO Queue worker started
# [timestamp] INFO Processing job: ...
```
### Related Files
- `docker-compose.yml` (base queue-worker definition)
- `docker-compose.prod.yml` (production override)
- `console.php` (framework console application)
---
## Issue 5: HTTP Port 80 nicht erreichbar
### Symptom
```bash
curl http://94.16.110.151:8888/
# curl: (7) Failed to connect to 94.16.110.151 port 8888: Connection refused
docker exec web curl http://localhost/
# curl: (7) Failed to connect to localhost port 80: Connection refused
```
### Diagnose
```bash
# Nginx listening ports checken
docker exec web netstat -tlnp | grep nginx
# Zeigt nur: 0.0.0.0:443
# Nginx Config checken
docker exec web cat /etc/nginx/http.d/default.conf
# Kein "listen 80;" block
```
### Root Cause - Option 1: Intentional HTTPS-only
Möglicherweise ist HTTP absichtlich disabled (Security Best Practice).
### Root Cause - Option 2: Missing HTTP Block
Nginx config hat keinen HTTP listener, nur HTTPS.
### Lösung - HTTP→HTTPS Redirect hinzufügen
✅ **Fix**: HTTP Redirect konfigurieren
`docker/nginx/default.production.conf`:
```nginx
# HTTP → HTTPS Redirect
server {
listen 80;
server_name _;
location / {
return 301 https://$host$request_uri;
}
}
# HTTPS Server
server {
listen 443 ssl http2;
server_name _;
ssl_certificate /var/www/ssl/cert.pem;
ssl_certificate_key /var/www/ssl/key.pem;
root /var/www/html/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
```
### Verification
```bash
curl -I http://94.16.110.151:8888/
# HTTP/1.1 301 Moved Permanently
# Location: https://94.16.110.151:8888/
curl -k -I https://94.16.110.151:8443/
# HTTP/2 200
# server: nginx
```
### Related Files
- `docker/nginx/default.production.conf`
- `Dockerfile.production` (COPY nginx config)
---
## General Debugging Commands
### Container Inspection
```bash
# Alle Container Status
docker-compose -f docker-compose.yml -f docker-compose.prod.yml ps
# Container Details
docker inspect web
# Container Logs
docker logs -f web
docker logs --tail 100 web
# Inside Container
docker exec -it web sh
docker exec -it php sh
```
### Supervisor Debugging
```bash
# Supervisor Status
docker exec web supervisorctl status
# Supervisor Logs
docker exec web tail -f /dev/null # Logs gehen nach stdout/stderr
# Supervisor Config testen
docker exec web supervisord -c /etc/supervisor/conf.d/supervisord.conf -n
```
### Nginx Debugging
```bash
# Nginx Config testen
docker exec web nginx -t
# Nginx reload
docker exec web nginx -s reload
# Nginx listening ports
docker exec web netstat -tlnp | grep nginx
# Nginx processes
docker exec web ps aux | grep nginx
```
### PHP-FPM Debugging
```bash
# PHP-FPM Status
docker exec web curl http://localhost/php-fpm-status
# PHP-FPM Config testen
docker exec web php-fpm -t
# PHP-FPM processes
docker exec web ps aux | grep php-fpm
# PHP Version
docker exec web php -v
# PHP Modules
docker exec web php -m
```
### Network Debugging
```bash
# Port listening
docker exec web netstat -tlnp
# DNS resolution
docker exec web nslookup db
docker exec web nslookup redis
# Network connectivity
docker exec web ping db
docker exec web ping redis
# HTTP request
docker exec web curl http://localhost/
```
### Database Debugging
```bash
# PostgreSQL Connection
docker exec php php -r "new PDO('pgsql:host=db;dbname=framework_db', 'framework_user', 'password');"
# Database Logs
docker logs db
# Connect to DB
docker exec -it db psql -U framework_user -d framework_db
# Check connections
docker exec db psql -U framework_user -d framework_db -c "SELECT count(*) FROM pg_stat_activity;"
```
### Performance Monitoring
```bash
# Container Resource Usage
docker stats
# Disk Usage
docker system df
# Image Sizes
docker images
# Volume Sizes
docker system df -v
```
---
## Checklist für erfolgreichen Deploy
### Pre-Deployment
- [ ] Image gebaut: `docker build -f Dockerfile.production -t 94.16.110.151:5000/framework:latest .`
- [ ] Image gepusht: `docker push 94.16.110.151:5000/framework:latest`
- [ ] Registry verfügbar: `curl http://94.16.110.151:5000/v2/_catalog`
- [ ] WireGuard VPN aktiv: `wg show`
- [ ] `.env.production` auf Server aktuell
- [ ] `docker-compose.prod.yml` auf Server aktuell
### Deployment
- [ ] SSH auf Server: `ssh deploy@94.16.110.151`
- [ ] Image pullen: `docker-compose -f docker-compose.yml -f docker-compose.prod.yml pull`
- [ ] Stack starten: `docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d`
### Post-Deployment Verification
- [ ] Container laufen: `docker-compose ps` zeigt alle "Up (healthy)"
- [ ] Supervisor Status: `docker exec web supervisorctl status` zeigt nginx/php-fpm RUNNING
- [ ] Nginx lauscht: `docker exec web netstat -tlnp | grep :443`
- [ ] PHP-FPM lauscht: `docker exec web netstat -tlnp | grep :9000`
- [ ] Application erreichbar: `curl -k -I https://94.16.110.151:8443/` → HTTP/2 200
- [ ] Database erreichbar: `docker exec php php -r "new PDO(...);"`
- [ ] Redis erreichbar: `docker exec php php -r "new Redis()->connect('redis', 6379);"`
- [ ] Logs sauber: `docker logs web` zeigt keine Errors
### Monitoring
- [ ] Prometheus: http://10.8.0.1:9090 erreichbar
- [ ] Grafana: http://10.8.0.1:3000 erreichbar
- [ ] Portainer: https://10.8.0.1:9443 erreichbar
- [ ] Watchtower aktiv: `docker logs watchtower` zeigt Checks
---
## Quick Reference
### Häufigste Fehlerursachen
1. **Supervisor Logging**: Verwende `logfile=/dev/null` + `silent=false`
2. **User Permissions**: Setze `user: root` in docker-compose.prod.yml
3. **Entrypoint Override**: Setze `entrypoint: []` um inherited entrypoint zu clearen
4. **Pull Policy**: Verwende `pull_policy: always` um registry image zu forcen
### Wichtigste Config-Änderungen
- `docker/supervisor/supervisord.conf`: `logfile=/dev/null`, `silent=false`
- `docker-compose.prod.yml`: `user: root`, `entrypoint: []`, `pull_policy: always`
- `docker/php/zz-docker.production.conf`: `user = www-data`, `group = www-data`