Deployment and updates
The standard self-hosted stack runs TimescaleDB, Redis, and one unified Riviamigo container containing the API, web app, nginx origin, and backup tools. Only the unified app is bound to the host, on port 8080 by default.
Place an authenticated HTTPS tunnel or identity-aware reverse proxy in front of the app and restrict direct port 8080 access with your host firewall. Never publish the API listener, database, or Redis directly.
Initial deployment
-
Copy
compose/.env.exampleto.env. Set separate strong database and Redis passwords plus your exact public HTTPSALLOWED_ORIGINSvalue. Internal service URLs and persistent application keys are generated automatically. -
Start the stack:
docker compose --env-file .env -f compose/docker-compose.yml up -d -
Verify it:
docker compose --env-file .env -f compose/docker-compose.yml pscurl http://localhost:8080/health -
Configure an authenticated gateway that forwards to port
8080and supports WebSockets. -
Open the HTTPS address and create the first owner account.
Persistent files
The standard stack keeps operator-visible files under ./data:
| Host directory | Container path | Contents |
|---|---|---|
data/db | /db | PostgreSQL data |
data/redis | /data | Redis append-only state |
data/backups | /backups | Downloadable recovery packages |
data/cache | /data/cache | Application cache files, including vehicle artwork |
Do not delete data during updates. Copy recovery packages off-host for disaster recovery.
Logs and updates
docker compose --env-file .env -f compose/docker-compose.yml logs -f
docker compose --env-file .env -f compose/docker-compose.yml logs -f riviamigo
docker compose --env-file .env -f compose/docker-compose.yml pull
docker compose --env-file .env -f compose/docker-compose.yml up -d
The app applies immutable, forward-only database migrations on startup. Pin
IMAGE_TAG to an exact Calendar Version for repeatable deployments. Existing
pre-release installations must complete the one-time explicit baseline
adoption in the release database cutover runbook
before starting the flattened public release; startup never edits migration
bookkeeping automatically.
The PostgreSQL 18 image cannot reuse a PostgreSQL 16 data directory. Before upgrading an existing PostgreSQL 16 installation, create and verify a recovery package plus a raw pg_dump, stop the old stack, move its data directory aside, and restore into a newly initialized PostgreSQL 18 volume. Never point PostgreSQL 18 at the former PG16 directory. Follow the backup and restore runbook for the validation sequence.
Redis 8 can read the tested Redis 7 append-only snapshot format. Preserve a copy of data/redis before the upgrade. If Redis rejects the snapshot, start with an empty Redis directory; users will need to sign in again and external providers may need to reconnect, but PostgreSQL telemetry and configuration remain intact.
Build from source
docker compose --env-file .env -f compose/docker-compose.yml -f compose/docker-compose.build.yml up -d --build
Local development continues to use pnpm dev:stack and compose/docker-compose.dev.yml; production image consolidation does not change that workflow.
Upgrade from the former named volumes
Before the first start with the host-visible layout, stop the old stack and create a current recovery package. Then migrate the old volumes:
docker compose --env-file .env -f compose/docker-compose.yml down
node scripts/migrate-production-storage.mjs --project riviamigo
docker compose --env-file .env -f compose/docker-compose.yml up -d
The migration refuses running source volumes and non-empty destinations, verifies copied file counts, and retains the old volumes for rollback. Pass the prior Compose project name through --project if it was not riviamigo.
Stopping and recovery
docker compose --env-file .env -f compose/docker-compose.yml down
down retains ./data. Removing the containers does not remove bind-mounted application data. See backup and restore before replacing or deleting the data directory.