Okapi

Quickstart

Requires Docker and Docker Compose. This gets you a working instance on your own machine; see Installation for a production deployment.

1. Start the stack

Download the Compose file and bring it up:

curl -O https://useokapi.app/docker-compose.yml
docker compose up -d

That's the whole stack — two services, db (Postgres) and app (the Okapi binary), pinned to the current published image. It boots with working defaults so you can evaluate right away: a 14-day trial, no license key.

The downloaded file looks like this, trimmed to the essentials:

services:
  db:
    image: postgres:18-alpine
    environment:
      POSTGRES_USER: ${POSTGRES_USER:-okapi}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-okapi}
      POSTGRES_DB: ${POSTGRES_DB:-okapi}
      # Password for the okapi_app application role created on first boot.
      # Set a strong value in .env before your first production boot.
      OKAPI_APP_DB_PASSWORD: ${OKAPI_APP_DB_PASSWORD:-okapi}
    volumes:
      - okapi-db:/var/lib/postgresql
    configs:
      # Creates the non-superuser okapi_app role on a fresh database.
      - source: okapi_app_role
        target: /docker-entrypoint-initdb.d/01-create-application-role.sh

  app:
    image: ghcr.io/useokapi/okapi:0.6.0 # pinned to the current published release — the same version the download above gives you
    depends_on:
      db:
        condition: service_healthy
    environment:
      OKAPI_DATABASE_URL: postgres://okapi_app:${OKAPI_APP_DB_PASSWORD:-okapi}@db:5432/okapi?sslmode=disable
      OKAPI_BASE_URL: ${OKAPI_BASE_URL:-http://localhost:8480}
      OKAPI_SECRET_KEY: ${OKAPI_SECRET_KEY:-change-me-generate-with-openssl-rand-base64-32}
    ports:
      - "${OKAPI_APP_PORT:-8480}:8080"

volumes:
  okapi-db:

OKAPI_APP_DB_PASSWORD sets the password for okapi_app, the non-superuser Postgres role the app connects as — the compose file's inline init script creates it automatically on a fresh database volume. Row-level tenant isolation only holds for non-superuser connections, so this role matters even for a local trial. The default (okapi) is fine to try things out; generate a real value (openssl rand -hex 32) before you put anything real behind this.

The app is published on host port 8480 by default (OKAPI_APP_PORT overrides it); Postgres data persists in the okapi-db volume.

2. Complete first-run setup

On first boot Okapi generates a one-time setup token and logs a ready line with the full URL. Read it from the app logs:

docker compose logs app
Okapi is ready — complete setup … /setup?token=…

Open that URL. It's a WordPress-style setup screen: create your superadmin account and name your organization. If you lose the line, reprint it anytime:

docker compose exec app /okapi setup-url

3. Create a project and copy a DSN

  1. Create a project from the dashboard.
  2. Open the project's DSN Keys tab and copy the public key — the DSN Keys tab shows a ready-to-copy DSN in the exact form your SDK expects.

4. Send a first event

Point your app's existing Sentry SDK at the DSN — see SDK setup for every language. As a quick smoke test with Python:

import sentry_sdk
sentry_sdk.init(dsn="http://YOUR_PUBLIC_KEY@localhost:8480/1")

Trigger an error and watch it appear under Issues within a few seconds.

Next: Installation for a real deployment, or SDK setup for your specific language/framework.