# 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.