Skip to content

Get started with Docker Compose

The repository ships a Compose stack under deploy/compose/: a hardened single-node deployment (embedded SQLite, zero external dependencies) plus two overlays — a Postgres multi-tenant override and a disaster-recovery backup profile. This tutorial takes you from up -d to a configured control plane with backups.

The container wraps the same single binary as every other install; only the packaging differs. The commands below are the stack’s own documented entry points (deploy/compose/*.yml), and the first-run flow they drive is the same one verified end-to-end against the binary in the single-node tutorial.

1. Bring up the single-node stack (SQLite)

Section titled “1. Bring up the single-node stack (SQLite)”
  1. Start it:

    Terminal window
    docker compose -f deploy/compose/docker-compose.yml up -d

    What you get, by design:

    | Property | Value | |---|---| | Ports | 127.0.0.1:8443 (HTTPS: REST + web UI), 127.0.0.1:8444 (gRPC) — bound to localhost on the host; expose deliberately | | Data | named volume olivares-data/var/lib/olivares (SQLite store, audit signing key, TLS material) | | Hardening | runs as 65532:65532, read-only root, all capabilities dropped, no-new-privileges, tmpfs /tmp | | Healthcheck | none in-container (the image is distroless — no shell). Probe /livez and /readyz from the host |

  2. Read the one-time setup token from the logs:

    Terminal window
    docker compose -f deploy/compose/docker-compose.yml logs olivares \
    | sed -n '/FIRST-BOOT SETUP/,/========================/p'
  3. Create the first administrator, log in, and create your organization — exactly as in the single-node tutorial (the API is the same; the TLS certificate is self-signed on first boot, so curl -k for the bootstrap):

    Terminal window
    curl -ksf -X POST https://localhost:8443/v1/setup \
    -H 'Content-Type: application/json' \
    -d '{"token":"<olst_ token>","email":"you@example.com","password":"<strong-password>"}'

Sources are declared in one operator file named by OLIVARES_SOURCES_CONFIG (connect a source). For the container, mount the file and set the variable with a small override:

# deploy/compose/docker-compose.sources.yml (yours — not shipped)
services:
olivares:
environment:
OLIVARES_SOURCES_CONFIG: /etc/olivares/sources.json
volumes:
- ./sources.json:/etc/olivares/sources.json:ro
Terminal window
docker compose -f deploy/compose/docker-compose.yml \
-f deploy/compose/docker-compose.sources.yml up -d
docker compose -f deploy/compose/docker-compose.yml logs olivares | grep "ingest: wired source"

Remember the paths inside sources.json are container paths — a pgAudit log tail, for example, needs the Postgres log directory mounted read-only into the container as well.

3. Encrypted DR backups (the backup profile)

Section titled “3. Encrypted DR backups (the backup profile)”

The stack ships a one-shot backup service that produces an encrypted, ledger-continuity-safe bundle (olivares dr backup) and prunes bundles older than 14 days:

Terminal window
# Write your KEK passphrase once (keep it OUT of the repo / image):
printf 'a strong DR passphrase' > deploy/compose/dr-pass
docker compose -f deploy/compose/docker-compose.yml \
-f deploy/compose/docker-compose.backup.yml \
--profile backup run --rm backup

Wrap that command in host cron for a scheduled RPO, and mirror the olivares-backups volume offsite — a same-host backup is not disaster recovery, and the passphrase must travel separately from the bundles (3-2-1). The full procedure, including the restore drill (olivares dr verify), is in backup & restore.

4. Optional: the Postgres multi-tenant override

Section titled “4. Optional: the Postgres multi-tenant override”

For the multi-tenant topology, layer the Postgres override. It brings up a Postgres 16, provisions the least-privilege olivares_app role (no superuser, no BYPASSRLS — the engine refuses to start against a privileged role, because row-level security is the tenant backstop), and points the engine at it:

Terminal window
cp deploy/compose/.env.example deploy/compose/.env
# set POSTGRES_SUPERUSER_PASSWORD and OLIVARES_DB_PASSWORD in .env
docker compose -f deploy/compose/docker-compose.yml \
-f deploy/compose/docker-compose.postgres.yml up -d
Terminal window
curl -ks https://localhost:8443/readyz
# {"leader":true,"setup_required":false,"status":"ok","store":"up"}
curl -ks https://localhost:8443/metrics | grep olivares_store_up