Files
xamxam/nginx/DEPLOYMENT_COMPLETE.md
2026-02-05 17:37:07 +01:00

8.7 KiB

Production Deployment Complete - Post-ERG

Date: February 5, 2026
Status: Successfully Deployed


🎉 Deployment Summary

The Post-ERG website is now successfully deployed with production-ready nginx configuration and security hardening.

What's Working

Feature Status Test Result
Public Site Working https://posterg.erg.be/ → 200 OK
SSL/TLS Working HTTPS with valid certificate
Admin Panel Protected /formulaire/ → 401 (requires password)
Database Protection Blocked /database/ → 403 Forbidden
Sensitive Files Blocked .md, .sql files → 403 Forbidden
Shared Directory Blocked /shared/ → 403 Forbidden
Security Headers Present X-Frame-Options, CSP, etc.
PHP 8.4 Running php8.4-fpm active
File Permissions Fixed posterg group, readable by www-data

🔧 What Was Fixed

1. File Permissions

Problem: Files owned by theophile:theophile with 640 permissions, nginx couldn't read them.

Solution:

# Changed group to posterg (www-data is member)
chown -R theophile:posterg /var/www/html/

# Set proper permissions
find /var/www/html -type d -exec chmod 755 {} \;
find /var/www/html -type f -exec chmod 640 {} \;

2. PHP Include Paths

Problem: Public files used ../../shared/ which doesn't work in production structure.

Solution:

  • Public files: Changed ../../shared//shared/
  • Admin files: Changed ../../shared//../shared/
  • Automated in deployment script

3. Nginx Configuration

Problem: Using basic default config with no security.

Solution: Deployed production config with:

  • Rate limiting (30/min general, 10/min admin)
  • File protection (database, configs, hidden files)
  • Admin password protection
  • Security headers
  • Proper PHP-FPM configuration
  • Upload size limits (100MB)

📋 Production Configuration

Server Details

  • Server: posterg.erg.be
  • Internal IP: 192.168.6.125
  • PHP Version: 8.4.16
  • Nginx: Latest stable
  • SSL/TLS: Handled by upstream reverse proxy

File Structure

/var/www/html/
├── index.php, memoire.php, search.php  (public files)
├── assets/                              (CSS, JS)
├── shared/                              (PHP libraries - blocked from web)
│   ├── Database.php
│   ├── RateLimit.php
│   └── config.php
├── database/                            (SQLite database - blocked from web)
│   └── posterg.db
└── formulaire/                          (admin panel - password protected)
    ├── index.php, list.php, edit.php
    └── data/
        ├── theses/                      (uploaded PDF files)
        └── covers/                      (uploaded cover images)

Security Configuration

Rate Limits:

  • General requests: 30 requests/minute (burst: 20)
  • Search endpoint: 30 requests/minute (burst: 10)
  • Admin panel: 10 requests/minute (burst: 5)

Protected Paths:

  • /database/ - Database files (403)
  • /shared/ - PHP libraries (403)
  • /data/ - Upload directories (403)
  • *.db files - Database files (403)
  • *.md, *.sql, *.sh, *.json - Sensitive files (403)
  • Hidden files (.git, .env, etc.) - (403)

Admin Access:

  • Path: /formulaire/
  • Authentication: HTTP Basic Auth
  • Password file: /etc/nginx/.htpasswd-posterg
  • User: test_posterg_22@

Security Headers:

X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), microphone=(), camera=()

🚀 Deployment Process (For Future Updates)

The deployment process has been automated and updated:

Deploy Code Changes

# Deploy public site
just deploy-public
# Automatically fixes paths: ../../shared/ → /shared/

# Deploy admin panel
just deploy-admin
# Automatically fixes paths: ../../shared/ → /../shared/

# Deploy both
just deploy

Deploy Nginx Config

# Deploy production nginx configuration
just deploy-nginx-production

# On server, run deployment script
ssh posterg
sudo bash /tmp/deploy-production.sh

The deployment scripts now automatically:

  1. Copy files to server
  2. Fix PHP include paths
  3. Set correct permissions
  4. Test nginx configuration
  5. Reload services

🧪 Testing & Verification

Automated Tests

# On server
cd /var/www/html

# Test public site
curl -I http://localhost/                # Should: 200 OK

# Test admin protection
curl -I http://localhost/formulaire/     # Should: 401 Unauthorized

# Test security
curl -I http://localhost/database/posterg.db   # Should: 403 Forbidden
curl -I http://localhost/README.md             # Should: 403 Forbidden
curl -I http://localhost/shared/Database.php   # Should: 403 Forbidden

External Tests

# From your local machine
curl -I https://posterg.erg.be/           # Should: 200 OK
curl -I https://posterg.erg.be/formulaire/  # Should: 401

Browser Tests

  1. Visit https://posterg.erg.be/ - Homepage loads
  2. Search functionality works
  3. Individual thesis pages work
  4. Admin requires password: https://posterg.erg.be/formulaire/
  5. Can upload files in admin (after login)

📊 Monitoring

Log Files

# Nginx access log
tail -f /var/log/nginx/posterg_access.log

# Nginx error log
tail -f /var/log/nginx/posterg_error.log

# PHP error log
tail -f /var/www/html/error.log

Service Status

# Check nginx
sudo systemctl status nginx

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

# Test nginx config
sudo nginx -t

🔐 Admin Access

Login Credentials

Change Password

ssh posterg
sudo htpasswd /etc/nginx/.htpasswd-posterg test_posterg_22@

Add Additional Admin Users

ssh posterg
sudo htpasswd /etc/nginx/.htpasswd-posterg newusername

🔄 Maintenance

Update Website Content

# From local machine
just deploy

# Content is automatically updated on server

Reload Nginx (after config changes)

ssh posterg
sudo nginx -t                    # Test configuration
sudo systemctl reload nginx      # Reload if test passes

Restart PHP-FPM (if needed)

ssh posterg
sudo systemctl restart php8.4-fpm

Update SSL Certificate

SSL/TLS is handled by the upstream reverse proxy. Contact the infrastructure team if certificate renewal is needed.


🆘 Troubleshooting

Site Returns 403 Forbidden

Check file permissions:

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

Check nginx user:

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

Site Returns 500 Internal Server Error

Check PHP errors:

tail -f /var/log/nginx/posterg_error.log
tail -f /var/www/html/error.log

Check PHP-FPM:

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

Admin Panel Not Working

Check password file:

ls -la /etc/nginx/.htpasswd-posterg

Reset password:

sudo htpasswd /etc/nginx/.htpasswd-posterg test_posterg_22@

After Deploying, Site Broken

Check if paths were fixed:

grep "require_once" /var/www/html/index.php
# Should show: __DIR__ . '/shared/Database.php'
# NOT: __DIR__ . '/../../shared/Database.php'

Manually fix if needed:

ssh posterg "cd /var/www/html && sed -i \"s|__DIR__ . '/../../shared/|__DIR__ . '/shared/|g\" *.php"

📞 Support Contacts

  • Deployment Issues: Check logs first
  • Nginx Config: /etc/nginx/sites-available/posterg
  • PHP Config: /etc/php/8.4/fpm/pool.d/www.conf
  • Database: /var/www/html/database/posterg.db

Success Checklist

After any deployment, verify:

  • Public site loads: https://posterg.erg.be/
  • Search works
  • Individual thesis pages work
  • Admin requires password
  • Admin can log in
  • File uploads work (in admin)
  • Database is protected (403)
  • Sensitive files blocked (403)
  • No errors in logs
  • Security headers present

📚 Documentation Files

  • posterg-production.conf - Production nginx configuration
  • deploy-production.sh - Automated deployment script
  • PRODUCTION_DEPLOYMENT.md - Detailed deployment guide
  • DEPLOY_NOW.md - Quick deployment instructions
  • DEPLOYMENT_COMPLETE.md - This file

Deployment completed successfully on February 5, 2026 🎉