Installing Bowrain Server
A Bowrain deployment runs as several cooperating services:
- 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.
The steps below set up a stack for local evaluation. For a production stack with TLS, backups and a reverse proxy, see Self-Hosting, which also holds 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
You build the server and worker from source. The GitHub Releases for this
repository carry the kapi CLI, the kapi-bowrain plugin and the Bowrain
desktop app, and no server artifact, so the compose stack above also builds
the server image locally.
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.