diff --git a/SERVER.md b/SERVER.md new file mode 100644 index 0000000..d59ddb4 --- /dev/null +++ b/SERVER.md @@ -0,0 +1,92 @@ +# Server — dvla-api + +Production host for the `dvla-api` Laravel application. Single VPS, single app. +This file is the source of truth for how the box is configured. Update it when +you change the box. + +## Host + +- **Provider / type:** Hetzner Cloud CX23 (2 vCPU, 4 GB RAM, 80 GB disk) +- **OS:** Ubuntu 24.04 LTS (noble) +- **Public IP:** 37.27.203.46 +- **Hostname:** ubuntu-4gb-dvla-api +- **Swap:** 2 GB swapfile at `/swapfile` (mounted via `/etc/fstab`) + +## Users + +- `root` — break-glass admin only +- `deploy` (UID 1000) — owns the app directory, performs deployments +- `www-data` — nginx + PHP-FPM runtime user; group-shared with `deploy` for file access + +> **Note:** This box runs **one** app. If a second app is ever added, the +> default PHP-FPM `www` pool MUST be split into per-app pools running as +> per-app system users, or the apps will be able to read each other's `.env` +> and SQLite files. See the earlier project chats for the multi-app layout. + +## Web stack + +- **nginx** 1.24 — site config: `/etc/nginx/sites-available/dvla-api` + - Listens on `:80` (HTTP only — TLS pending) + - `server_name 37.27.203.46;` + - Document root: `/var/www/dvla-api/public` +- **PHP-FPM** 8.4 — pool: default `www.conf` + - Runs as `www-data:www-data` + - Socket: `/run/php/php8.4-fpm.sock` + - `pm = dynamic`, `pm.max_children = 5` (CX23-appropriate) + +## Application + +- **Path:** `/var/www/dvla-api` +- **Owner:** `deploy:www-data`, directories have SGID bit (`drwxrwsr-x`) so + new files inherit the `www-data` group automatically +- **Framework:** Laravel 11 on PHP 8.4 +- **Git remote:** SSH to Gitea via deploy key (see `DEPLOY.md`) +- **Branch deployed:** `main` + +## Database — SQLite + +- **File:** `/var/www/dvla-api/database/database.sqlite` +- **Perms:** file `660`, directory `770`, both owned `deploy:www-data` + - Directory must be writable by `www-data` so SQLite can create + `-journal` / `-wal` / `-shm` siblings +- **Journal mode:** WAL (enabled with + `sqlite3 database/database.sqlite "PRAGMA journal_mode=WAL;"`) +- **Backups:** __ + +`SESSION_DRIVER`, `CACHE_STORE`, and `QUEUE_CONNECTION` are all `database`, +meaning sessions/cache/queue tables live in the same SQLite file as app +data. Acceptable for low traffic; revisit if write contention shows up +(`database is locked` errors in `storage/logs/laravel.log`). + +## Queue / scheduler + +- **Worker:** __ +- **Scheduler:** __ + +## Network / firewall + +- **UFW:** __ +- **Open ports (verified via `ss -tlnp`):** + - 22 — SSH + - 80 — HTTP (nginx) + - 53 — systemd-resolved, loopback only (not public) +- **TLS:** __ + +## Backups + +__ + +## Known divergences from the multi-app pattern in project chats + +This box was set up for a single app and intentionally simplified: +- Single `deploy` user instead of `deploy-` +- Default `www-data` PHP-FPM pool instead of a per-app pool +- No Redis (cache/sessions/queue all on SQLite) + +These are acceptable as long as this box hosts one app. Revisit the older +project chats before adding a second app to this VPS. diff --git a/routes/web.php b/routes/web.php index 86a06c5..4575056 100644 --- a/routes/web.php +++ b/routes/web.php @@ -4,4 +4,5 @@ use Illuminate\Support\Facades\Route; Route::get('/', function () { return view('welcome'); + });