diff --git a/docs/README.md b/docs/README.md index 5ca9b7f..8830975 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,6 +16,7 @@ This directory separates **current reference** docs, **proposals/plans**, and | Doc | Contents | |-----|----------| | [development.md](development.md) | Dev workflow, structure, builds, testing, linting | +| [environment.md](environment.md) | Runtime stack, PHP/nginx/DB/Node requirements, server specs | | [deployment.md](deployment.md) | Server setup, deploy, backups, rollback | | [database.md](database.md) | SQLite schema, migrations, tables, common ops | | [search.md](search.md) | `/search` and `/repertoire` behaviour | diff --git a/docs/environment.md b/docs/environment.md new file mode 100644 index 0000000..ca2f229 --- /dev/null +++ b/docs/environment.md @@ -0,0 +1,123 @@ +# Environment / runtime requirements + +The software stack and server environment required to run XAMXAM. This is the +machine-facing counterpart to the product spec in +[`spec-sheet.md`](spec-sheet.md). + +## Production server (`xamxam`) + +| Item | Value | +|------|-------| +| **OS** | Debian 13 (trixie), `x86_64` | +| **Web server** | nginx 1.26 (config: `nginx/xamxam.conf`) | +| **PHP** | PHP-FPM 8.4 (pool `www`, master config `/etc/php/8.4/fpm/`) | +| **Database** | SQLite 3 (WAL mode), `/var/www/xamxam/storage/xamxam.db` | +| **App root** | `/var/www/xamxam/` (DocumentRoot → `app/public/`) | +| **App user** | `www-data`, group `xamxam` | +| **Node.js** | *Not required on the server* — assets are built locally and rsync'd | + +## PHP (≥ 8.4) + +Declared in `composer.json` (`"php": ">=8.4"`, platform lock `8.4`). + +### Required extensions (`composer.json` `require`) + +- `ext-json` +- `ext-openssl` +- `ext-pdo` + +### Implicitly required (used by the code or transitive deps) + +Verified present in the production `php -m` output and on the FPM pool: + +- `pdo_sqlite` / `sqlite3` — the primary datastore +- `curl` — PeerTube/Nextcloud/HTTP integrations (Guzzle uses it) +- `mbstring` / `iconv` / `intl` — string handling, Markdown, translations +- `session` — admin auth + CSRF (see [`security.md`](security.md)) +- `sodium` — `Crypto` (libsodium) for encrypted fields (SMTP password) +- `zlib` / `phar` — Composer autoload + PHAR-based tooling +- `gd` — not used directly, present transitively (image handling is `finfo`) +- `fileinfo` — upload MIME validation (`finfo`) +- `calendar`, `ctype`, `filter`, `hash`, `tokenizer`, `xml`, `libxml` — PHP core + extensions, present by default + +### Recommended (production) + +- `opcache` (+ `opcache.preload` optional) — bytecode cache +- `xdebug` — **disabled/not loaded in production** (dev only) + +### PHP — other runtime settings + +- **Session GC** — tuned in `/etc/php/8.4/fpm/conf.d/zz-xamxam-session.ini` (see + [`security.md`](security.md#php-fpm-session-gc-configuration)): `gc_maxlifetime = 43200`, + `gc_probability = 1`, `gc_divisor = 100`. Must stay ≥ the app's + `ABSOLUTE_TIMEOUT_SECONDS` (12 h). +- **Upload limits** — storage partition temp dir at + `/var/www/xamxam/storage/tmp/php-uploads/` (not `/tmp` tmpfs); see + [`file-uploads.md`](file-uploads.md). +- **Logs** — Monolog writes to `/var/log/xamxam/` (provisioned by the deploy + script). + +## Composer dependencies + +From `composer.json`: + +| Package | Purpose | +|---------|---------| +| `guzzlehttp/guzzle` `^7.9` | HTTP client (PeerTube, Nextcloud, integrations) | +| `league/commonmark` `^2.4` | Markdown rendering (pages, help blocks) | +| `monolog/monolog` `^3.10` | Logging | +| `phpmailer/phpmailer` `^6.9` | SMTP (STARTTLS/SMTPS/plain) | + +Dev-only: `phpunit/phpunit ^11`, `phpstan/phpstan ^2.1`, +`friendsofphp/php-cs-fixer ^3.95`, `symfony/polyfill-iconv ^1.31`. + +## Node.js / npm (build-time only) + +Used **locally** to build frontend assets — not needed on the production server. +Build tooling is pinned in `package.json` `devDependencies`: + +| Package | Purpose | +|---------|---------| +| `rolldown` | JS bundling | +| `lightningcss` | CSS minification | +| `@biomejs/biome` | lint/format | +| `chokidar-cli` | dev watch mode | + +Run `npm ci` (not `npm install`) to install; `npm run build` (or `just build`) +to produce `app/public/assets/`. + +## nginx + +- Config source: `nginx/xamxam.conf`; installed to + `/etc/nginx/sites-available/xamxam` (symlinked from `sites-enabled/`). +- PHP handled via `fastcgi_pass` to the `php8.4-fpm` pool `www`. +- Security headers enforced here (HSTS, CSP, etc.) — see + [`security.md`](security.md) and `nginx/docs/SECURITY_HEADERS.md`. +- Static assets served from `app/public/`; `/storage`, `/src`, `/templates`, + DB/env hidden files are blocked. + +## Database + +- SQLite 3 file DB (`app/storage/xamxam.db`) in **WAL mode**. +- Schema + migrations: `app/src/DatabaseMigrations.php`; see + [`database.md`](database.md). +- Backups: WAL-safe `sqlite3 .backup` (see [`deployment.md`](deployment.md)). +- `sqlite3` CLI required on the server for backup/query helpers. + +## Toolchain / CLI + +Required on the **dev** machine (and `just` on deploy-from-local): + +- **PHP** ≥ 8.4 (same extensions as above, plus `sqlite3` for local DB) +- **Composer** 2.x +- **Node.js + npm** (for the JS build) +- **`just`** (command runner; see justfile) +- **`ssh`** access to `xamxam` for `just deploy*` + +## See also + +- [`development.md`](development.md) — local dev workflow, structure, builds +- [`deployment.md`](deployment.md) — server setup, deploy, backups, rollback +- [`security.md`](security.md) — security posture, session GC tuning +- [`spec-sheet.md`](spec-sheet.md) — product/feature spec (fiche technique)