Run OpenSourceOM with Docker Compose
docker-compose.yml in the core repository starts two services: Postgres 16 and
an API image built from the local Dockerfile. The image entrypoint is
om and the command is serve.
cp .env.example .env
docker compose up -d
docker compose ps
Postgres listens on host port 5432 with user, password, and database opensourceom
unless you override POSTGRES_USER, POSTGRES_PASSWORD, and
POSTGRES_DB. The API listens on OM_API_PORT (default 8080) and
receives OM_API_SECRET from .env. A volume named
postgres-data keeps the database across restarts.
Migrations
The API container does not migrate on startup. From a checkout, with the CLI on the host:
go build -o om ./cmd/om
./om migrate
The CLI’s default database host is localhost, which is the published port.
.env.example sets POSTGRES_HOST=postgres, and the API service in
the compose file sets that same value on the container. The CLI does not read
.env. Do not export POSTGRES_HOST=postgres into the shell that
runs om on your machine.
CLI against Compose
Build om on the host (or unpack a release binary) and use it for scans. The
container image can also run one-off commands if you point it at the Compose network:
docker compose run --rm api migrate api migrate works because the image entrypoint is already om.
Cloud scans are easier on the host, where your AWS, Azure, and GCP credential files already
live. The API container does not mount those credentials. To scan from the container you
would pass the credential environment yourself, for example
-e AWS_REGION -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY, and the database
host inside that network is postgres, which the service already sets.
If the CLI cannot connect
POSTGRES_HOST=postgresin the shell is the usual miss. That hostname exists only on the Compose network. Unset it, or setPOSTGRES_HOST=localhost, for a CLI on the host.- Password, user, and database must match what Compose used to initialize the volume. Changing
POSTGRES_PASSWORDin.envafter the first start does not alter an existing volume. - The API waits until Postgres is healthy.
om migrateon the host does not. If it runs before the port is open, retry it. relation "nodes" does not existmeans migrate has not been applied to this database.
GET http://localhost:8080/v1/health returns
{"status":"ok","service":"opensourceom-api"} when the API process is up. It
does not check Postgres. A scan that fails on the database while health is ok means the CLI
and the container are not using the same connection settings.
Useful commands
docker compose logs -f api
docker compose down
docker compose down -v down -v deletes the Postgres volume. The next start is an empty database and
needs om migrate again.
Copyright © 2026 OpenSourceOM. Licensed under Apache-2.0.