Docker Compose¶
This page takes you from nothing to a running, healthy Adriano with Docker Compose, against your own catalog file and identity provider. Read Deploying Adriano first; it explains what you deploy and how to register the identity provider client. Read this page top to bottom; every step is required unless marked optional.
Prerequisites¶
Docker Engine with Docker Compose v2.24 or newer. Older Compose versions cannot read the optional environment file this stack uses.
The things listed in Deploying Adriano: an identity provider client, a record source and a TLS-terminating ingress or load balancer.
Obtaining the stack¶
Download docker-compose.yml and deploy/compose.defaults.env
from the source archive of the release you deploy, and keep the
relative paths: put compose.defaults.env in a deploy/ folder
next to docker-compose.yml.
The stack has two services:
dbPostgreSQL 18 with a named volume (
adriano-db-data). Remove it, and thedepends_onentry ofadriano, if you use your own PostgreSQL (see Using your own PostgreSQL).adrianoThe Adriano image. It is the only service published on the host (port 8180 by default).
Pin the image to one release in .env (next section) and pull it:
docker compose pull adriano
Configuration¶
You provide two files next to docker-compose.yml:
.envEnvironment settings: database password, OIDC settings, and the secrets that the catalog file names (source access tokens and push tokens). Every setting is described in Configuration reference. Keep this file out of version control; it holds secrets.
catalog.yamlWhich sources to index, the approval policy and the role permissions. See The catalog file.
A minimal production .env:
# The release to run: a full version, never a channel
ADRIANO_IMAGE_TAG=2026.10.1
# Database (the bundled db service)
ADRIANO_DB_PASSWORD=<long random password>
ADRIANO_DATABASE_URL=postgresql://adriano:<same password>@db:5432/adriano
# Your catalog file on the Docker host
ADRIANO_CATALOG_FILE_HOST=./catalog.yaml
# OIDC: used by the API and by the web UI
ADRIANO_OIDC_AUTHORITY=https://idp.example.com/realms/adr
ADRIANO_OIDC_CLIENT_ID=adriano-web
ADRIANO_OIDC_AUDIENCE=adr_viewer
ADRIANO_OIDC_ROLES_CLAIM=realm_access.roles
# Secrets that catalog.yaml refers to by name
# only needed for a gitlab source
ADRIANO_GITLAB_TOKEN_PLATFORM=<GitLab access token>
ADRIANO_PUSH_TOKEN_PLATFORM=<long random token>
# Never set the dev-only sign-in settings here:
# ADRIANO_DEV_AUTH_ENABLED, ADRIANO_DEV_SHARED_SECRET
Warning
ADRIANO_CATALOG_FILE_HOST defaults to the bundled demo
catalog.
Always set it to your own file, or Adriano indexes the sample
records.
The ./samples mount in docker-compose.yml only serves the
demo catalog; remove it once you use your own.
The bundled database address uses the default credentials.
When you change ADRIANO_DB_PASSWORD, change the password in
ADRIANO_DATABASE_URL as well.
Validate the catalog file before the first start (the database does not need to be running):
docker compose run --rm --no-deps adriano adriano check-config
Fix every line marked error before you continue.
Bring-up¶
Start the stack:
docker compose up -d
Compose starts
db, waits until it is healthy, then startsadriano. Adriano applies pending database migrations before it serves (setADRIANO_MIGRATE_ON_STARTtofalseto turn this off and runadriano migrateyourself).Point your ingress or load balancer at the published port, with TLS. Forward the
X-Forwarded-For,X-Forwarded-ProtoandX-Forwarded-Hostheaders. Adriano trusts them only from the addresses inADRIANO_FORWARDED_ALLOW_IPS: set it to your proxy’s address, or to*if only the proxy can reach the published port.Run the first poll, so the catalog has content:
docker compose exec adriano adriano poll
Each registration prints one line with its status and counts. See Polling sources for what
partialandfailedmean.Schedule polls, as described in the next section.
If CI should push draft records, hand out the push tokens (Pushing candidates from CI).
Scheduling polls¶
Compose has no scheduler.
Run adriano poll from cron or a systemd timer on the Docker host,
for example every 15 minutes:
*/15 * * * * docker compose -f /opt/adriano/docker-compose.yml exec -T adriano adriano poll >> /var/log/adriano-poll.log 2>&1
-T is needed because cron has no terminal.
Alert on a non-zero exit code; Polling sources lists them.
Verification¶
The service is healthy:
docker compose ps -a
adrianoanddbshowhealthy.The health endpoint answers:
curl -fsS http://localhost:8180/healthz
A healthy production deployment answers:
{"status": "ok", "database": "ok", "config": "ok", "policy": "configured", "registrations": "synced", "rbac": "configured", "auth": "oidc", "version": "2026.10.1"}
versionis the release you pinned.authmust beoidc. Any value containingdevmeans the development sign-in bypass is active: stop and fix it (see Authentication and access). Every field is explained in Health checks and logs.Open the web UI through your ingress and sign in with a user that has the
readpermission. The sign-in page must not offer a “Dev sign-in” button.Sign in as an operator and open the Sources page. Every registration should show the status OK.
Upgrade and rollback¶
An upgrade may change the database schema, and a schema change cannot be undone by going back to the old image. Back up the database first (Backup, restore and retention). Then:
Set
ADRIANO_IMAGE_TAGin.envto the new version.Validate your catalog file against the new release (
docker compose run --rm --no-deps adriano adriano check-config).Pull and recreate:
docker compose pull adriano docker compose up -d
The new container applies the migrations before it serves. Plan a short maintenance window: the old release may not work against the new schema.
Verify as above.
To roll back, set the previous version and run docker compose up
-d.
That works only while the release you left did not change the
schema.
If it did, restore the backup taken before the upgrade
(Backup, restore and retention) and then start the previous version.
Upgrading has the details.
Using your own PostgreSQL¶
To use a managed PostgreSQL (version 18 is what Adriano is tested with):
Set
ADRIANO_DATABASE_URLin.envto its address. Your value wins over the bundled default.Remove the
dbservice and thedepends_onentry ofadrianofromdocker-compose.yml.
For production, create the two database users described in
Database roles and tamper resistance.
Run the migrations with the owner and the application with the
application user: start once with
ADRIANO_DATABASE_URL set to the owner’s address, then switch
it to the application user’s address, or set
ADRIANO_MIGRATE_ON_START to false and run the
migrations with the owner before each upgrade:
docker compose run --rm --no-deps \
-e ADRIANO_DATABASE_URL=<owner address> adriano adriano migrate