export MSYS_NO_PATHCONV=1 first.
Start and stop
--wait returns when the server is healthy, or with an error if a service failed. After docker compose ps -a, the services setup, migrate and seed show Exited (0). That is normal: they run once per start. postgres and api show Up (healthy).
Health
/health returns {"status":"UP"} whenever the server process runs. /ready also checks the database and the execution_intents table, and returns 503 with "status":"NOT_READY" and a reason when either is missing. The container’s health check uses /ready.
Logs
runtime_engine_constructed in which every value should be true, then API running on http://0.0.0.0:3000.
Upgrade
migrateapplies only migrations the database does not have yet, each in its own transaction, and prints[migrate] <n> applied, <m> already applied;seedadds only new policy versions, and prints how many it added and kept;setupkeeps your keys and API keys.
Back up
A complete backup has two parts. Back up both, at the same time. 1. The database:./parmana-local, which holds the signing keys and API keys. Copy it with your usual file backup, as root on Linux, because its files belong to uid 1000.
Restore
Into a deployment with an empty database, fromparmana.dump and a copy of ./parmana-local:
migrate runs before the restore so the roles the schema grants to exist. --clean --if-exists then replaces its empty tables with the backup’s.
Check: docker compose logs migrate ends with 0 applied, docker compose logs seed reports 0 added, and a record you know, for example GET /refusal/<businessTransactionId>, returns 200.
This procedure was tested on 2026-09-25: a Refusal Record and a policy approval made before the backup were both present after a full wipe and restore.
Change the database password
Postgres stores the password when the database is first created. ChangingPARMANA_DB_PASSWORD alone makes migrate fail with password authentication failed for user "parmana" and the server does not start. Change it in the database first:
curl -s http://127.0.0.1:3000/ready returns "status":"READY".
Change the published address or port
SetPARMANA_BIND and PARMANA_PORT, then run docker compose up -d --wait. See Configuration reference. Put a TLS terminating proxy in front before binding to anything other than 127.0.0.1.
Signing keys
- The public keys in
parmana-local/keys/*.public.pemare what others use to verify your records. Publish them to whoever verifies. - There is no key rotation procedure for the self hosted deployment yet. Replacing
defaultorgatewaymakes the server sign new records with the new key; records signed earlier verify only with the old public key, so keep every old public key. - To keep the signing key in AWS KMS instead of a file, see AWS KMS signing. That setup has not been tested with the self hosted deployment.