- Move 12 markdown files from root to docs/ subdirectories - Organize documentation by category: • docs/troubleshooting/ (1 file) - Technical troubleshooting guides • docs/deployment/ (4 files) - Deployment and security documentation • docs/guides/ (3 files) - Feature-specific guides • docs/planning/ (4 files) - Planning and improvement proposals Root directory cleanup: - Reduced from 16 to 4 markdown files in root - Only essential project files remain: • CLAUDE.md (AI instructions) • README.md (Main project readme) • CLEANUP_PLAN.md (Current cleanup plan) • SRC_STRUCTURE_IMPROVEMENTS.md (Structure improvements) This improves: ✅ Documentation discoverability ✅ Logical organization by purpose ✅ Clean root directory ✅ Better maintainability
5.5 KiB
Production SSL Setup for michaelschiemer.de
This guide explains how to fix the SSL configuration for the production domain https://michaelschiemer.de/
Current Status
✅ Nginx Configuration Fixed
- Updated server_name from
localhosttolocalhost michaelschiemer.de - Both HTTP redirect and HTTPS server blocks now support the production domain
- Health check mapping updated to allow
michaelschiemer.dedomain
✅ Deployment Script Enhanced
- Added SSL certificate checks in
deploy.sh - Automatic creation of temporary self-signed certificates if Let's Encrypt certificates are missing
- Ensures Docker containers can start even without valid SSL certificates
Setup Instructions
Step 1: Deploy Updated Configuration
# Deploy the updated nginx configuration
./deploy.sh
This will deploy the updated nginx configuration and create temporary self-signed certificates if needed.
Step 2: Generate Let's Encrypt SSL Certificates
Important: Make sure michaelschiemer.de points to your server IP 94.16.110.151 before running this.
# Run the SSL setup script
./setup-production-ssl.sh
This script will:
- Check DNS resolution for the domain
- Install certbot on the production server
- Stop nginx temporarily
- Generate Let's Encrypt certificates using HTTP-01 challenge
- Copy certificates to the expected location (
/var/www/ssl/) - Restart the application with valid SSL certificates
- Set up automatic certificate renewal (twice daily)
Step 3: Verify SSL Setup
-
Test HTTPS Access:
curl -I https://michaelschiemer.de/ -
Check Certificate Details:
echo | openssl s_client -servername michaelschiemer.de -connect michaelschiemer.de:443 2>/dev/null | openssl x509 -noout -dates -
Verify Docker Containers:
ssh deploy@94.16.110.151 'cd /home/deploy/michaelschiemer && docker compose ps'
Configuration Changes Made
1. Nginx Configuration (docker/nginx/default.conf)
Health Check Mapping:
map $host $block_health {
default 1; # Block everything by default
localhost 0; # Allow localhost (development)
michaelschiemer.de 0; # Allow production domain
}
HTTP Server Block:
server {
listen 80;
server_name localhost michaelschiemer.de; # Support both domains
return 301 https://$host$request_uri;
}
HTTPS Server Block:
server {
listen 443 ssl;
server_name localhost michaelschiemer.de; # Support both domains
ssl_certificate /var/www/ssl/fullchain.pem;
ssl_certificate_key /var/www/ssl/privkey.pem;
# ... rest of SSL configuration
}
2. Docker Compose Volume Mounting
SSL certificates are mounted from ./ssl to /var/www/ssl in the nginx container:
volumes:
- ./ssl:/var/www/ssl:ro
3. Enhanced Deployment Script
The deployment script now:
- Checks for existing SSL certificates
- Creates temporary self-signed certificates if Let's Encrypt certificates are missing
- Ensures the application can start regardless of certificate status
Certificate Renewal
Automatic renewal is set up with a cron job that runs twice daily:
0 12,0 * * * /home/deploy/renew-certificates.sh >> /var/log/letsencrypt-renewal.log 2>&1
The renewal script:
- Stops the nginx container
- Renews certificates using certbot
- Copies renewed certificates to the correct location
- Restarts all services
Troubleshooting
Common Issues
-
Domain not resolving to server IP:
dig +short michaelschiemer.de # Should return: 94.16.110.151 -
Firewall blocking port 80/443:
# Check if ports are open nmap -p 80,443 94.16.110.151 -
Certificate generation fails:
- Ensure domain points to server IP
- Check if port 80 is accessible from internet
- Verify no other services are using port 80 during certificate generation
-
Docker container won't start:
# Check container logs ssh deploy@94.16.110.151 'cd /home/deploy/michaelschiemer && docker compose logs web'
Manual Certificate Check
# SSH to production server
ssh deploy@94.16.110.151
# Check certificate files
ls -la /home/deploy/michaelschiemer/ssl/
cat /home/deploy/michaelschiemer/ssl/fullchain.pem | openssl x509 -noout -text
Force Certificate Regeneration
# SSH to production server
ssh deploy@94.16.110.151
cd /home/deploy/michaelschiemer
# Remove existing certificates
rm -rf ssl/live ssl/archive ssl/*.pem
# Run the SSL setup script again
./setup-production-ssl.sh
Security Considerations
- Certificate Storage: Certificates are stored in
/var/www/ssl/and mounted read-only in containers - Automatic Renewal: Certificates automatically renew before expiration
- Strong SSL Configuration: TLS 1.2+ with secure cipher suites
- Security Headers: HSTS, CSP, and other security headers configured
- HTTP to HTTPS Redirect: All HTTP traffic redirected to HTTPS
Next Steps After SSL Setup
- Test the Application: Visit https://michaelschiemer.de/
- Monitor Logs: Check nginx and application logs for any issues
- Set up Monitoring: Consider setting up SSL certificate expiration monitoring
- Performance Testing: Run performance tests with SSL enabled
- Security Audit: Run SSL Labs test: https://www.ssllabs.com/ssltest/
The SSL configuration is now production-ready and should provide secure HTTPS access to your Custom PHP Framework application.