# Backend, database and storage

Understand initialization, shared runtime roles and persistent data in the core reference setup.

The [reference core](/install/reference.md) starts PostgreSQL, RustFS and a one-shot
bucket initializer before the API becomes usable. Its migration, API and jobs
services use the same pinned server image and mounted `server/server.yaml`.

| Service | Command/responsibility | Persistent data |
| --- | --- | --- |
| `postgres` | Database with the selected release's vector/text-search extensions | `database` volume |
| `storage` | S3-compatible recording/file storage | `recordings` volume |
| `storage-init` | Idempotent creation of private `recordings` bucket | Exits after initialization |
| `migrator` | `migrate`, once before API/jobs start | Updates database schema |
| `server` | `serve`, backend API | Shared `uploads` plus database/storage |
| `jobs` | `run jobs`, released background job runtime | Same config/uploads/database/storage |

The [PostgreSQL Dockerfile](/examples/reference/database/Dockerfile) preserves
the maintained extension setup so historical migrations can run on a fresh
database. Do not remove extensions based only on the current schema's indexes.
The database and storage have no host-published ports in this example.

## Validate and initialize

From the archive root, with the profile's complete Compose prefix:

```sh
docker compose --env-file secrets.env run --rm --no-deps migrator validate-config
docker compose --env-file secrets.env run --rm --no-deps migrator validate-config --resolve-env
docker compose --env-file secrets.env up --build -d postgres storage storage-init
docker compose --env-file secrets.env up --build -d
docker compose --env-file secrets.env ps --all
```

`storage-init` and `migrator` must exit zero. Runtime config validation does not
connect to databases/providers or prove credentials work. Check logs without
publishing them if they contain user data. Verify public API discovery at
`https://YOUR_HOST/api/info/v1/server_info` and complete the client recording test.

Keep `db.run_migrations: false` when using the explicit migrator. Never start
a different jobs version against the new schema accidentally. The jobs/API
upload mount must remain shared, and all private configuration must survive
container recreation. See [backups and upgrades](/operations/backup-upgrade.md).
