# Deployment Server setup, deployment, and rollback procedures for Post-ERG. --- ## One-Time Server Setup Run before first deploy: ```bash just setup-server ``` This creates `/var/www/posterg/` with correct ownership/permissions: - Owner: `www-data:posterg` - Directories: **2775** (setgid — new files inherit `posterg` group) - Files: **664** - Database files: **660** > **Important:** After running `setup-server`, log out and back in on the server (or `newgrp posterg`) so group membership is active before deploying. ### Why setgid (2775)? rsync uses `--chown=www-data:posterg`. Both `padlock` and `www-data` must write to dirs. With `2775 + group=posterg`, new subdirs inherit the group automatically. --- ## Deploying ```bash just deploy # Push all app files just deploy-db # Push initial database (aborts if remote DB exists) just deploy-nginx # Push + apply nginx config ``` ### First-Time Deployment Since we moved from `/var/www/html/` to `/var/www/posterg/`: 1. **Setup server directory** (one time): ```bash just setup-server ``` 2. **Deploy application**: ```bash just deploy ``` Uploads to `/var/www/posterg/`, excludes tests/docs/vendor. 3. **Deploy nginx config**: ```bash just deploy-nginx ssh posterg sudo bash /tmp/deploy-production.sh sudo systemctl reload nginx ``` 4. **Verify**: ```bash just server-status curl -I https://posterg.erg.be/ # 200 ✓ curl -I https://posterg.erg.be/admin/ # 200 ✓ curl -I https://posterg.erg.be/storage/ # 404 ✓ ``` ### Subsequent Deployments ```bash just deploy ``` --- ## Server Directory Structure ``` /var/www/posterg/ # Application root (private) ├── public/ # DocumentRoot (nginx points here) │ ├── index.php │ ├── search.php │ ├── memoire.php │ ├── admin/ │ └── assets/ ├── includes/ # Templates (private) ├── config/ # Configuration (private) ├── storage/ # Database + uploads (private) │ ├── posterg.db │ └── theses/ ├── src/ # PHP classes (private) └── scripts/ # Admin tools (private) ``` **Nginx DocumentRoot:** `/var/www/posterg/public/` Only `public/` is web-accessible. Everything else is physically private. --- ## Managing Admin Users ```bash ssh posterg "sudo bash /var/www/posterg/scripts/manage-admin-users.sh" ``` Interactive menu for adding/changing/deleting htpasswd entries at `/etc/nginx/.htpasswd-posterg`. --- ## Security Verification After every deploy, verify private files are inaccessible: ```bash curl -I https://posterg.erg.be/storage/test.db # Must 404 curl -I https://posterg.erg.be/config/bootstrap.php # Must 404 curl -I https://posterg.erg.be/src/Database.php # Must 404 ``` --- ## Troubleshooting ### rsync Permission Denied ```bash just setup-server # Fixes directory permissions # Then log out/in on server and retry ``` Manual fix: ```bash ssh posterg sudo chown -R www-data:posterg /var/www/posterg sudo find /var/www/posterg -type d -exec chmod 2775 {} \; sudo find /var/www/posterg -type f -exec chmod 664 {} \; sudo chmod 660 /var/www/posterg/storage/*.db ``` ### Nginx 403 Forbidden ```bash ssh posterg sudo find /var/www/posterg -type d -exec chmod 2775 {} \; sudo find /var/www/posterg -type f -exec chmod 664 {} \; sudo chmod 660 /var/www/posterg/storage/*.db ``` ### Database Permission Error ```bash ssh posterg sudo chown www-data:posterg /var/www/posterg/storage/posterg.db sudo chmod 660 /var/www/posterg/storage/posterg.db ``` ### Nginx 500 / Site 404 Check nginx DocumentRoot: ```bash ssh posterg "grep 'root ' /etc/nginx/sites-available/posterg" # Should show: root /var/www/posterg/public; ``` ### Admin 404 Nginx may still use old `/formulaire/` location. Update `nginx/posterg.conf` to use `/admin/`. --- ## Rollback If something goes wrong: ```bash # Restore old nginx config ssh posterg sudo cp /etc/nginx/sites-available/posterg.backup /etc/nginx/sites-available/posterg sudo systemctl reload nginx # Or restore old site (if backed up) sudo rm -rf /var/www/posterg sudo mv /var/www/html.backup /var/www/html ``` With jj: ```bash jj log jj edit ``` --- ## Commands Reference | Command | Purpose | |---------|---------| | `just setup-server` | Create `/var/www/posterg/` (first time only) | | `just deploy` | Deploy application files | | `just deploy-nginx` | Update nginx configuration | | `just deploy-db` | Deploy database file | | `just server-status` | Check server health | | `just server-logs` | View server logs |