# 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 `localhost` to `localhost michaelschiemer.de` - Both HTTP redirect and HTTPS server blocks now support the production domain - Health check mapping updated to allow `michaelschiemer.de` domain ✅ **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 ```bash # 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. ```bash # 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 1. **Test HTTPS Access**: ```bash curl -I https://michaelschiemer.de/ ``` 2. **Check Certificate Details**: ```bash echo | openssl s_client -servername michaelschiemer.de -connect michaelschiemer.de:443 2>/dev/null | openssl x509 -noout -dates ``` 3. **Verify Docker Containers**: ```bash 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**: ```nginx map $host $block_health { default 1; # Block everything by default localhost 0; # Allow localhost (development) michaelschiemer.de 0; # Allow production domain } ``` **HTTP Server Block**: ```nginx server { listen 80; server_name localhost michaelschiemer.de; # Support both domains return 301 https://$host$request_uri; } ``` **HTTPS Server Block**: ```nginx 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: ```yaml 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: ```bash 0 12,0 * * * /home/deploy/renew-certificates.sh >> /var/log/letsencrypt-renewal.log 2>&1 ``` The renewal script: 1. Stops the nginx container 2. Renews certificates using certbot 3. Copies renewed certificates to the correct location 4. Restarts all services ## Troubleshooting ### Common Issues 1. **Domain not resolving to server IP**: ```bash dig +short michaelschiemer.de # Should return: 94.16.110.151 ``` 2. **Firewall blocking port 80/443**: ```bash # Check if ports are open nmap -p 80,443 94.16.110.151 ``` 3. **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 4. **Docker container won't start**: ```bash # Check container logs ssh deploy@94.16.110.151 'cd /home/deploy/michaelschiemer && docker compose logs web' ``` ### Manual Certificate Check ```bash # 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 ```bash # 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 1. **Certificate Storage**: Certificates are stored in `/var/www/ssl/` and mounted read-only in containers 2. **Automatic Renewal**: Certificates automatically renew before expiration 3. **Strong SSL Configuration**: TLS 1.2+ with secure cipher suites 4. **Security Headers**: HSTS, CSP, and other security headers configured 5. **HTTP to HTTPS Redirect**: All HTTP traffic redirected to HTTPS ## Next Steps After SSL Setup 1. **Test the Application**: Visit https://michaelschiemer.de/ 2. **Monitor Logs**: Check nginx and application logs for any issues 3. **Set up Monitoring**: Consider setting up SSL certificate expiration monitoring 4. **Performance Testing**: Run performance tests with SSL enabled 5. **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.