Install with Docker Compose
Jangka ships as one Docker image, iqbalr3000/jangka, and needs Postgres 18. The release compose file runs both on
one host. This page explains what's in it and how to run it on a server. To get a trial running quickly,
see Quick start.
The compose file
Download it into its own directory:
mkdir jangka && cd jangka
curl -fsSL https://raw.githubusercontent.com/iqbalr3000/jangka/v1.0.0-rc.1/docker/docker-compose.yml -o docker-compose.ymlThis is the whole file:
name: jangka
services:
postgres:
image: postgres:18
environment:
POSTGRES_USER: jangka
POSTGRES_PASSWORD: jangka
POSTGRES_DB: jangka
volumes:
# PG18 stores data in /var/lib/postgresql/18/docker; mounting .../data would not persist.
- pgdata:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U jangka -d jangka"]
interval: 5s
timeout: 3s
retries: 10
app:
image: iqbalr3000/jangka:${JANGKA_VERSION:-latest}
# The setup wizard tells admins to run `docker logs jangka`.
container_name: jangka
depends_on:
postgres:
condition: service_healthy
environment:
DATABASE_URL: postgres://jangka:jangka@postgres:5432/jangka
MASTER_KEY: ${MASTER_KEY:?set MASTER_KEY (openssl rand -base64 32)}
PUBLIC_URL: ${PUBLIC_URL:-http://localhost:3000}
ports:
- "3000:3000"
volumes:
pgdata:| Part | What it does |
|---|---|
postgres | Postgres 18. It isn't published on a host port, so only the app can reach it. That's why a fixed password is acceptable here. |
pgdata | Named volume with all database data. It survives docker compose down and image upgrades. |
app | Jangka, at the version set in JANGKA_VERSION. It runs database migrations on start, then serves the web app and API on port 3000. |
container_name: jangka | A fixed name, so docker logs jangka works. The setup wizard shows that command. |
To use a Postgres server you already run instead of the bundled one, see Use an existing Postgres.
The .env file
Compose reads .env from the same directory and fills in ${MASTER_KEY}, ${PUBLIC_URL} and
${JANGKA_VERSION}. On a server, set all three:
MASTER_KEY=generated-with-openssl-rand-base64-32
PUBLIC_URL=https://jangka.example.com
JANGKA_VERSION=1.0.0-rc.1Pin an exact version. Without JANGKA_VERSION the compose file falls back to latest, which release
candidates don't publish, and which would change under you on the next docker compose pull.
Generate the key with openssl rand -base64 32. Without it, docker compose up stops with
set MASTER_KEY.
PUBLIC_URL is the address people type into the browser, without a trailing path. Jangka uses it for
session cookies, the CSRF origin check and SSO redirect URIs, so it has to match that address exactly.
Other variables, such as LOG_LEVEL or TRUST_PROXY, go under app.environment in the compose file. See the
Configuration reference.
Start and check it
docker compose up -d
docker compose psThe app's image has a health check that calls GET /api/v1/health, which also checks the database.
docker compose ps shows the app as healthy once it's serving traffic. The first start takes longer
because migrations create the schema.
Change the port
The app listens on port 3000 inside the container. To serve it on another host port, change the left side of the mapping. This keeps it on port 8080, reachable only from the host itself, which suits a reverse proxy on the same machine:
ports:
- "127.0.0.1:8080:3000"Everyday commands
Run these in the directory that holds docker-compose.yml.
docker compose logs -f app # follow the app's logs (JSON, one line per event)
docker compose restart app # restart the app, e.g. after a crash loop is fixed
docker compose up -d # apply changes to the compose file or .env
docker compose down # stop and remove the containers; data stays in pgdata