Installing Bowrain Server
A Bowrain deployment is several cooperating services, not a single binary:
- bowrain-server: the REST + gRPC API (one process; gRPC is multiplexed onto the HTTP port).
- bowrain-worker: the async worker that ingests pushes and runs the drafting jobs a run enqueues against an upstream AI provider.
- PostgreSQL: the authoritative store (projects, blocks, workspaces, users, jobs). The server requires PostgreSQL; there is no SQLite or file backend.
- A job queue (Amazon SQS, or an SQS-compatible broker such as ElasticMQ) and Redis for the event bus (Redis Streams), shared by the server and worker.
- bowrain-web: the static web UI, served as its own container.
- An OIDC identity provider (for example Keycloak) and an SMTP sender.
This page covers local evaluation. For a production stack with TLS, backups, and a reverse proxy, see Self-Hosting, which is the canonical reference for the full architecture and the complete environment-variable set.
One-command local stack
The repository ships a self-contained local stack at bowrain/compose.full.yaml: server, worker, PostgreSQL, ElasticMQ (SQS-compatible job queue), Redis, MinIO, Keycloak (with a pre-imported realm), and Mailpit. It defaults to the offline demo provider, so the full push → draft → pull cycle works with no API keys and no OIDC setup:
docker compose -f bowrain/compose.full.yaml up -d --build --wait
Endpoints once it is up:
| URL | Service |
|---|---|
http://localhost:8080 | bowrain-server API (and the web UI with --profile web) |
http://localhost:8080/api/v1/health | Health check |
http://localhost:8180 | Keycloak admin console (admin / admin) |
http://localhost:8025 | Mailpit (captured emails) |
To serve the web UI from the server, add the web profile:
docker compose -f bowrain/compose.full.yaml --profile web up -d --build
For real drafts, set BOWRAIN_PLATFORM_PROVIDER (for example gemini) and the matching API key in a .env file; see Self-Hosting.
Tear down with docker compose -f bowrain/compose.full.yaml down -v.
Self-hosting from published images
To run from the published ghcr.io/neokapi/ images against your own OIDC provider, use the reference stack at bowrain/deploy/docker/compose.yaml: Traefik, PostgreSQL, ElasticMQ, Redis, the server, the worker, and the web UI.
docker compose -f deploy/docker/compose.yaml up -d
At minimum, provide an external OIDC issuer, a JWT secret, and (for drafting) an upstream provider:
POSTGRES_PASSWORD=... # database password
BOWRAIN_JWT_SECRET=$(openssl rand -base64 32) # JWT signing secret
BOWRAIN_OIDC_ISSUER_URL=... # your realm's issuer URL
BOWRAIN_OIDC_CLIENT_SECRET=... # the bowrain client's secret
BOWRAIN_PLATFORM_PROVIDER=gemini # or bedrock / openai / anthropic / ollama
BOWRAIN_PLATFORM_API_KEY=... # provider API key
See Self-Hosting for the full production walkthrough, including TLS, backups, and the complete service topology.
Building the binaries
The server and worker are built from source. Neither is published as a
download: the GitHub Releases for this repository carry the kapi CLI, the
kapi-bowrain plugin and the Bowrain desktop app, and no server artifact.
The compose stack above builds the server image locally for the same reason.
git clone https://github.com/neokapi/neokapi.git
cd neokapi
make -C bowrain build-server
Both still require a reachable PostgreSQL, plus a shared job queue (SQS or an SQS-compatible broker) and Redis when the server and worker run as separate processes.
Run the server (PostgreSQL is required; the connection string must use the postgres:// scheme):
bowrain-server \
--database-url postgres://bowrain:password@localhost/bowrain \
--jwt-secret change-me-in-production \
--oidc-issuer-url https://keycloak.example.com/realms/bowrain \
--oidc-client-id bowrain \
--oidc-client-secret your-client-secret \
--port 8080
The schema is created automatically on first start; migrations run on startup. The async worker is configured entirely through environment variables; see Configuration.
systemd service
/etc/systemd/system/bowrain-server.service:
[Unit]
Description=Bowrain Server
After=network.target
[Service]
Type=simple
User=bowrain
Group=bowrain
Environment=BOWRAIN_DATABASE_URL=postgres://bowrain:password@localhost/bowrain
Environment=BOWRAIN_QUEUE_BACKEND=sqs
Environment=SQS_ENDPOINT=http://localhost:9324
Environment=BOWRAIN_EVENT_BACKEND=redis
Environment=BOWRAIN_REDIS_URL=redis://localhost:6379
ExecStart=/usr/local/bin/bowrain-server \
--jwt-secret ${BOWRAIN_JWT_SECRET} \
--oidc-issuer-url https://keycloak.example.com/realms/bowrain \
--oidc-client-id bowrain \
--oidc-client-secret ${BOWRAIN_OIDC_CLIENT_SECRET} \
--port 8080
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable --now bowrain-server
sudo systemctl status bowrain-server
OIDC provider setup
Bowrain Server requires an OIDC provider for authentication. Any OIDC-compliant provider works (Keycloak, Auth0, Okta, Azure AD, Dex). The local stack above imports a pre-configured Keycloak realm automatically; for your own provider see the OIDC provider setup in Self-Hosting.
Health check
Verify the server is running:
curl http://localhost:8080/api/v1/health
Next steps
- Configuration: the complete environment-variable and CLI-flag reference.
- Getting Started: first login, workspaces, invitations.
- Self-Hosting: production deployment with TLS and backups.