Files
xamxam/nginx/PRODUCTION_DEPLOYMENT.md
Théophile Gervreau-Mercier 7fca85d1c1 refactor: rename database → storage
More semantically accurate: contains SQLite files, schema, fixtures, test data.
Updated all references in code, scripts, docs.
2026-02-12 12:12:58 +01:00

7.1 KiB

Production Deployment Guide - Post-ERG

This guide will help you deploy the production nginx configuration with proper security and permissions.

🎯 Overview

Your current setup:

  • Server IP: 192.168.6.125 (internal)
  • PHP Version: 8.4
  • SSL/TLS: Handled by reverse proxy (already working)
  • Issue: File permissions preventing nginx from reading files

🚀 Quick Deployment

From your local machine:

# Deploy the production config and deployment script
just deploy-nginx-production

# SSH to the server and run the deployment
ssh posterg
sudo /tmp/deploy-production.sh

📋 Step-by-Step Deployment

1. Set Up Admin Password (First Time Only)

ssh posterg
sudo htpasswd -c /etc/nginx/.htpasswd-posterg admin
# Enter a strong password when prompted

💡 Tip: Generate a strong password:

openssl rand -base64 32

2. Deploy Configuration

From your local machine:

# Upload nginx config and deployment script
rsync -vur ./nginx/posterg-production.conf posterg:/tmp/posterg.conf
rsync -vur ./nginx/deploy-production.sh posterg:/tmp/deploy-production.sh

3. Run Deployment Script

On the server:

ssh posterg
sudo chmod +x /tmp/deploy-production.sh
sudo /tmp/deploy-production.sh

The script will:

  • Fix file permissions (set to posterg group)
  • Install nginx configuration
  • Test nginx configuration
  • Reload nginx
  • Check PHP-FPM status

🔧 Manual Deployment (Alternative)

If you prefer to do it manually:

Step 1: Fix Permissions

ssh posterg

# Set correct ownership (posterg group)
sudo chown -R theophile:posterg /var/www/html/

# Set directory permissions
sudo find /var/www/html -type d -exec chmod 755 {} \;

# Set file permissions (group readable)
sudo find /var/www/html -type f -exec chmod 640 {} \;

# Make upload directories writable
sudo chmod 775 /var/www/html/formulaire/data/theses
sudo chmod 775 /var/www/html/formulaire/data/covers

# Protect database
sudo chmod 640 /var/www/html/storage/posterg.db
sudo chown www-data:posterg /var/www/html/storage/posterg.db

Step 2: Deploy Nginx Config

# Copy config
sudo cp /tmp/posterg.conf /etc/nginx/sites-available/posterg

# Enable site
sudo ln -sf /etc/nginx/sites-available/posterg /etc/nginx/sites-enabled/posterg

# Disable default site
sudo rm -f /etc/nginx/sites-enabled/default

# Test configuration
sudo nginx -t

# Reload nginx
sudo systemctl reload nginx

Step 3: Verify PHP-FPM

# Check PHP-FPM is running
sudo systemctl status php8.4-fpm

# If not running, start it
sudo systemctl start php8.4-fpm
sudo systemctl enable php8.4-fpm

🧪 Testing

Test Public Site

# Should return 200 OK
curl -I http://localhost/

# Should return 200 OK with HTML
curl http://localhost/index.php

Test Admin Protection

# Should return 401 Unauthorized
curl -I http://localhost/formulaire/

# Should return 200 OK with credentials
curl -u admin:your_password http://localhost/formulaire/

Test File Protection

# These should all return 403 Forbidden
curl -I http://localhost/storage/posterg.db
curl -I http://localhost/README.md
curl -I http://localhost/shared/Database.php
curl -I http://localhost/.git/config

Test Security Headers

curl -I http://localhost/ | grep -E "X-Frame|X-Content|X-XSS"

From Your Browser

Visit https://posterg.erg.be/ - should work now!

🔍 Troubleshooting

Still Getting 403 Forbidden

Check file permissions:

ls -la /var/www/html/index.php
# Should show: -rw-r----- 1 theophile posterg ...

Check nginx user is in posterg group:

groups www-data
# Should show: www-data : www-data posterg

Check directory permissions:

ls -lad /var/www/html
# Should show: drwxr-xr-x ... posterg

502 Bad Gateway

Check PHP-FPM:

sudo systemctl status php8.4-fpm
sudo systemctl restart php8.4-fpm

Check socket file:

ls -la /var/run/php/php8.4-fpm.sock
# Should exist and be writable by www-data

Admin Password Not Working

Reset password:

sudo htpasswd /etc/nginx/.htpasswd-posterg admin

Check file exists:

ls -la /etc/nginx/.htpasswd-posterg
# Should show: -rw-r--r-- 1 root root ...

Database Not Accessible to PHP

Fix database permissions:

sudo chown www-data:posterg /var/www/html/storage/posterg.db
sudo chmod 640 /var/www/html/storage/posterg.db
sudo chmod 755 /var/www/html/storage/

Can't Write Uploaded Files

Fix upload directory permissions:

sudo chmod 775 /var/www/html/formulaire/data/theses
sudo chmod 775 /var/www/html/formulaire/data/covers
sudo chown -R theophile:posterg /var/www/html/formulaire/data/

📊 Monitoring

Watch Logs

# Access logs
sudo tail -f /var/log/nginx/posterg_access.log

# Error logs
sudo tail -f /var/log/nginx/posterg_error.log

# PHP errors
sudo tail -f /var/log/php8.4-fpm.log

Check Nginx Status

sudo systemctl status nginx
sudo nginx -t

Check Resource Usage

# Nginx processes
ps aux | grep nginx

# PHP-FPM processes
ps aux | grep php-fpm

# Disk usage
df -h /var/www/html

🔒 Security Checklist

After deployment, verify:

  • Public site accessible at https://posterg.erg.be/
  • Admin panel requires password
  • Database files return 403 Forbidden
  • Sensitive files (.md, .sql) return 403 Forbidden
  • Shared directory returns 403 Forbidden
  • Security headers present in responses
  • PHP-FPM running and accessible
  • File uploads work in admin panel
  • Search functionality works
  • Logs are being written

🔄 Updating the Site

For future updates:

# Deploy code changes
just deploy

# Reload nginx if config changed
ssh posterg "sudo systemctl reload nginx"

# Clear PHP opcache if needed
ssh posterg "sudo systemctl reload php8.4-fpm"

🆘 Emergency Recovery

If something goes wrong:

Restore Default Config

ssh posterg
sudo rm /etc/nginx/sites-enabled/posterg
sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default
sudo systemctl reload nginx

Reset Permissions

ssh posterg
sudo chown -R www-data:www-data /var/www/html
sudo find /var/www/html -type d -exec chmod 755 {} \;
sudo find /var/www/html -type f -exec chmod 644 {} \;
sudo systemctl reload nginx

📞 Support Resources

🎉 Success Criteria

You know the deployment is successful when:

  1. Visit https://posterg.erg.be/ - shows homepage
  2. Visit https://posterg.erg.be/formulaire/ - asks for password
  3. Search works correctly
  4. Individual thesis pages load
  5. Admin can upload files
  6. No 403 or 502 errors in logs
  7. Security headers present (check with curl -I)

Need help? Check the error logs first:

sudo tail -f /var/log/nginx/posterg_error.log