Files
xamxam/docs/deployment.md
Pontoporeia 3cd96ed28a Deduplicate and standardise documentation
- Consolidate 36 markdown files → 14 (plus TODO.md)
- Merge overlapping docs into authoritative files:
  - database.md (from DATABASE_SPECIFICATION + QUICK_SCHEMA_REFERENCE + DATABASE_CONFIG + SETUP)
  - deployment.md (from SERVER_SETUP + COMPLETE_DEPLOYMENT_GUIDE + DEPLOYMENT_STEPS)
  - security.md (from SECURITY_ANALYSIS + TODO.SECURITY)
  - development.md (from DEVELOPMENT_GUIDE + LIVE_RELOAD_SETUP + TEST_CENTRALIZATION)
  - migration-history.md (from 11 past migration docs)
- Standardise all filenames to lowercase
- Remove non-doc files (Context.md research notes, chat export)
- Remove superseded docs (SECURITY.md pre-SQLite, SECURITY_IMPLEMENTATION, README_SECURE_SEARCH)
- Fix stale cross-references
2026-04-15 14:24:44 +02:00

205 lines
4.7 KiB
Markdown

# 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 <previous-change-id>
```
---
## 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 |