Files
xamxam/nginx/docs/PRODUCTION_DEPLOYMENT.md
T
Pontoporeia 0e009c49d4 docs: align deployment/setup docs with current code
- nginx/docs/PRODUCTION_DEPLOYMENT.md: drop stale htpasswd/Basic-auth model,
  manual server-side deploy step, /var/www/posterg paths and hardcoded IP; describe
  the PHP-layer AdminAuth, automated 📋 Deploying nginx configuration…
xamxam.conf

sent 145 bytes  received 125 bytes  540.00 bytes/sec
total size is 10,012  speedup is 37.08
deploy-server.sh

sent 143 bytes  received 113 bytes  512.00 bytes/sec
total size is 8,519  speedup is 33.28, and what deploy-server.sh
  actually does.
- nginx/docs/QUICK_REFERENCE.md: replace htpasswd user management with AdminAuth
  guidance; fix php8.2->php8.4, log paths, admin rate limit (300r/m), socket path.
- nginx/README.md, nginx/SETUP.md: note 📋 Deploying nginx configuration…
xamxam.conf

sent 145 bytes  received 125 bytes  540.00 bytes/sec
total size is 10,012  speedup is 37.08
deploy-server.sh

sent 143 bytes  received 113 bytes  170.67 bytes/sec
total size is 8,519  speedup is 33.28 automates
  deploy-server.sh (no manual ssh/sudo step).
- docs/deployment.md: correct deploy-code scope (code-only, no --chown), fix the
  /var/log/xamxam provisioning step (deploy-server.sh via deploy-nginx, not
  deploy-code), document the setup-server.sh prerequisite and fresh-box caveat.
- README.md: replace the incomplete manual first-time setup snippet with the
  real setup-server.sh + provision-server flow and a fresh-box caveat.
2026-09-18 16:26:49 +02:00

3.7 KiB

Production Deployment Guide

Deploying the XAMXAM production nginx configuration and administering the site.

Overview

  • Host: xamxam (SSH alias), app root /var/www/xamxam/
  • PHP Version: 8.4
  • SSL/TLS: Terminated by an upstream reverse proxy (nginx itself listens on 80)
  • Document Root: /var/www/xamxam/public/ (deployed flat, not under app/)
  • Web / FPM user: www-data, app group: xamxam

Everything is orchestrated from your local machine through the justfile. just deploy-nginx uploads both nginx/xamxam.conf and scripts/deploy-server.sh to the server, runs the latter as root (installing the config, fixing permissions, testing and reloading nginx and php-fpm), then cleans up the remote temp files:

just deploy-nginx

No manual server-side step is needed — the recipe already does it. For a full code + dependencies + migrations deploy, run just deploy (which includes deploy-nginx). See ../../docs/deployment.md.

What scripts/deploy-server.sh does (as root):

  • Fixes ownership to www-data:xamxam across /var/www/xamxam/
  • Sets directory permissions to 2775 (setgid) and files to 664
  • Locks SQLite databases (and WAL/SHM sidecars) to 660; .env to 640
  • Creates writable cache / upload-tmp / var/{cache,logs,tmp} dirs for php-fpm
  • Provisions /var/log/xamxam/ (app log dir) and /var/backups/xamxam/ (backups)
  • Installs a php-fpm session-GC tuning file (zz-xamxam-session.ini)
  • Installs nginx/xamxam.conf into sites-available, symlinks it, backs up old uploads, prunes old backups, validates with nginx -t, and reloads nginx + php-fpm

Admin authentication

The admin panel is protected by the application's PHP session auth layer (src/AdminAuth.php), not by nginx htpasswd/Basic-auth. The user supplies a single password on /admin/login.php; no username, no /etc/nginx/.htpasswd.

Configure the admin password in the admin panel at /admin/parametres → Account tab (a fresh DB starts unauthenticated until a password is set). See PHP_AUTH_LAYER.md for the full authentication details.

Verification

After a successful deploy:

curl -I https://xamxam.erg.be/               # expect 200
curl -I https://xamxam.erg.be/admin/         # expect 200 (login page / 302 to it)
curl -I https://xamxam.erg.be/storage/xamxam.db   # expect 404 / 403 (blocked)
curl -I https://xamxam.erg.be/src/Database.php    # expect 404 / 403 (blocked)
just deploy-verify-permissions               # expect "All permissions OK"

Security headers (X-Frame-Options, X-Content-Type-Options, Strict-Transport-Security, Referrer-Policy, Permissions-Policy, Content-Security-Policy) are emitted by the nginx config; see SECURITY_HEADERS.md.

Troubleshooting

502 Bad Gateway

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

Nginx config error

ssh xamxam
sudo nginx -t

Still getting 403 Forbidden

Check ownership/group and that www-data is a member of the xamxam group:

ls -la /var/www/xamxam/public/index.php
groups www-data          # should include xamxam

If permissions are wrong, re-run the permission-fixing deploy script:

just deploy-nginx        # re-applies deploy-server.sh (perms + config)

See also