This is a short example for how to setup Chap-core locally as a service using docker-compose.
Requirements:
Clone the Chap core repo by running git clone https://github.com/dhis2-chap/chap-core.git
Create the environment file with cp .env.example .env. The services read the database credentials from it.
Run the docker compose file with docker compose -f compose.yml up. The first time you do this, it can take a few minutes to finish. Once it’s completed, it should have created the following docker services:
redis for receiving and queueing job requestsworker for executing the incoming work requests from queuechap containing the main functionality and the rest-apipostgres for storing chap-related dataCheck that the chap rest api works by going to http://localhost:8000/docs
The repository ships several compose files. compose.yml and compose.ghcr.yml are base files and are alternatives to each other — never stack them, because both define the chap and worker services, so the merged file carries both build and image settings for them and, on older Compose versions, duplicate security_opt / cap_drop entries that fail validation. Everything else is an overlay layered on top of a base with additional -f flags. Both base files keep redis and postgres on a separate backend network; chap and worker join it alongside the default network, so model services on the default network cannot reach the broker or the database.
| File | Kind | Purpose |
|---|---|---|
compose.yml |
base | Builds chap and worker from local source. The default for development and for the documented server install. |
compose.ghcr.yml |
base | Same services pulled as pre-built images from GHCR. Use instead of compose.yml. Self-contained: download this one file and run it without a checkout or an .env. |
compose.marketplace.yml |
overlay | Written by chap-admin in the deployment directory. Holds the marketplace model services it installed. Not in the repository. |
compose.chapkit.yml |
overlay | Includes compose.ewars.yml. Kept for development only; see below. |
compose.ewars.yml |
overlay | Starts the EWARS chapkit service directly. The service registers a model template but gets no configurations, so it cannot be run. Deployments install EWARS with chap-admin instead, and must not use both. |
compose.override.yml.example |
overlay template | Optional extra services (chtorch, ewars_plus). Copy to compose.override.yml. Compose merges that file automatically only when no -f flag is used; with any -f flag you must list it explicitly, last. |
compose.dev.yml |
overlay | Bind-mounts local source into chap, builds the worker from Dockerfile.inla, and exposes the postgres port on the host. |
compose.test.yml |
overlay | One-shot pytest container. |
compose.integration.test.yml |
overlay | Frontend emulator running the end-to-end database flow. |
compose.r-model.integration.test.yml |
overlay | End-to-end flow for an R-based model. |
Common combinations:
# Base only (plus compose.override.yml, if one exists)
docker compose up -d
# With the marketplace models installed by chap-admin (what the installation guide uses)
docker compose -f compose.yml -f compose.marketplace.yml up -d
# Development, with local source bind-mounted
docker compose -f compose.yml -f compose.dev.yml up -d
# Pre-built images instead of a local build
docker compose -f compose.ghcr.yml up -d
compose.ghcr.yml is the only file you need on a server. It pulls pre-built
images and every setting has a working default, so it runs exactly as
downloaded – no checkout, no .env, no edits:
curl -O https://raw.githubusercontent.com/dhis2-chap/chap-core/master/compose.ghcr.yml
docker compose -f compose.ghcr.yml up -d
All optional. Put them in an .env file beside the compose file rather than
inline on the command line: Compose reads .env on every command, so a later
pull or up keeps the same values, whereas an inline VAR=x docker compose
... applies to that one command and silently reverts afterwards.
| Variable | Default | Purpose |
|---|---|---|
CHAP_IMAGE_TAG |
latest |
Tag for both the chap-core and chap-worker images. latest is the newest release, master follows the master branch, and a release tag (for example v1.2.3) pins a version. The tag must exist in GHCR; all three are published by the image build workflow. |
POSTGRES_USER |
chap |
Database user. |
EWARS_IMAGE_TAG |
a sha-<commit> build |
Tag of the EWARS model service image in compose.ewars.yml. Model overlays pin a specific build so the stack stays reproducible; the model’s publish workflow tags every build as sha-<short commit> and releases as semver. Set this to move the pin. |
POSTGRES_PASSWORD |
chap |
Database password. Postgres is never published to the host, but override this for anything beyond a local trial. It is interpolated into a database URI, so it must be URL-safe – no @, :, /, ?, # or %. |
POSTGRES_DB |
chap_core |
Database name. |
CHAP_DATABASE_URL |
composed from the three above | Full, percent-encoded database URL. Takes precedence, and is how you use a password containing reserved characters. |
CHAP_ROOT_PATH |
empty | Path prefix when serving behind a reverse proxy. |
CHAP_API_TOKEN |
empty | API token. Unset means no authentication. |
CHAP_CORS_ORIGINS |
http://localhost:3000 |
Comma-separated browser origins allowed by CORS. Not needed when the Modeling App connects through the DHIS2 Route API. |
Pinning a release and setting a password with reserved characters:
cat > .env <<'EOF'
CHAP_IMAGE_TAG=v1.2.3
POSTGRES_PASSWORD=str@ng/pass
CHAP_DATABASE_URL=postgresql://chap:str%40ng%2Fpass@postgres:5432/chap_core
EOF
docker compose -f compose.ghcr.yml up -d
Pass the same -f compose.ghcr.yml flag to every later down, pull and
logs command in that stack.
Docker Compose does not remember which overlays you used, so pass the same -f flags to every subsequent down, build and logs command in that stack. The make restart, make force-restart and make chap-version targets carry the compose.yml + compose.chapkit.yml pair for development, so EWARS runs there without configurations.
Marketplace models are not started by an overlay in the repository. After the first docker compose up, run chap-admin install-all from the deployment directory; it starts the model services, registers them with their verified configurations, and writes compose.marketplace.yml. See Running marketplace models.
To add a model service of your own, see Running Your Own Model.