Repository navigation
Troubleshooting
Failure modes you can trace to something in this repo. Start by looking at the containers:
docker compose ps
Then the logs for one service:
docker compose logs -f api
error while interpolating services.postgres.environment.POSTGRES_PASSWORD: required variable DB_PASSWORD is missing a value: set DB_PASSWORD in .env
Four variables use Compose's :? syntax and have no default: DB_PASSWORD,
API_INTERNAL_SECRET, REPORTMATE_PASSPHRASE, NEXTAUTH_SECRET. The message
names whichever one is empty. You are either missing .env entirely (cp .env.example .env) or running docker compose from a directory other than the
one holding .env.
The password in DATABASE_URL is built from DB_PASSWORD, but
POSTGRES_PASSWORD only takes effect when Postgres initialises an empty data
directory. Changing DB_PASSWORD in .env after the first start leaves the
volume holding the old password, and the API can no longer connect.
Either put the original password back in .env, or change it inside Postgres:
docker compose exec postgres psql -U reportmate -d reportmate -c "ALTER ROLE reportmate WITH PASSWORD 'new-password';"
Then set the same value in .env and docker compose up -d. Wiping the volume
also works and destroys all data.
The browser calls the dashboard's own routes, and the dashboard calls the API
server-side at http://api:8000, so an empty dashboard is a web to api
problem, not a browser or CORS one. Check, in order:
- The API is up and healthy:
curl http://localhost:8000/api/v1/health. -
API_INTERNAL_SECRETmatches on both containers (see below). - The
weblog shows the failing request:
docker compose logs -f web
schema/init.sql is mounted into /docker-entrypoint-initdb.d and Postgres
runs that directory only when the data directory is empty. If a volume was
created before the schema file existed, or the bind mount path was wrong at
first start, the database came up empty and stayed that way.
Confirm what is in there:
docker compose exec postgres psql -U reportmate -d reportmate -c "\dt"
If the tables are genuinely absent and there is no data to lose,
docker compose down -v followed by docker compose up -d re-runs the init
script. If there is data, apply the file by hand instead:
docker compose exec -T postgres psql -U reportmate -d reportmate < schema/init.sql
Its tables, indexes, and columns all use IF NOT EXISTS, so re-running is safe
for those. The CREATE TRIGGER statements near the end do not — Postgres has
no IF NOT EXISTS for triggers — so on a database that already has them you
will see trigger "update_devices_updated_at" for relation "devices" already exists and the script stops there. Drop the existing triggers first, or run
the file in pieces.
The passphrase the agent sends must be one of the values in
REPORTMATE_PASSPHRASE. The API accepts a comma-separated list there, so
during rotation keep the old value in the list until every endpoint has the new
one.
Check what the running container actually has, rather than what you think you
put in .env:
docker compose exec api printenv REPORTMATE_PASSPHRASE
API_INTERNAL_SECRET must be byte-identical on api and web. The Compose
file wires both from one .env value, so a mismatch means one of the
containers is stale — it was created before you last edited .env. Recreate
both:
docker compose up -d --force-recreate api web
The published ghcr.io/reportmate/web image has demo mode compiled off, so
DEMO_MODE in .env has no effect. Configure an identity provider, or build a
demo-mode dashboard image. See Configuration.
api uses condition: service_healthy, so it waits for pg_isready. If
Postgres never turns healthy, read its log:
docker compose logs postgres
A common cause is an error inside schema/init.sql on a first start — Postgres
aborts initialisation and the container will not become healthy. The failing
statement appears in that log.
packer/setup.sh runs with set -euo pipefail, so the first failing command
ends the build and the failing line is in the output. The usual causes are no
network from the build VM when adding the Docker apt repository, or no KVM on
the build host (the qemu source sets accelerator = "kvm").
CI runs shellcheck --severity=error packer/setup.sh, packer validate, and
docker compose config --quiet, so syntax problems in a pull request are
caught before this point.
first-boot.sh generated them because no .env was present. Read them off the
booted machine:
sudo cat /opt/reportmate/.env
The three application secrets will be the same string; see Appliance Image.
Deployment tooling MIT licensed; application images licensed separately (server AGPL-3.0, clients MIT) — reportmate.app