Search documentation

Search documentation pages and headings.

Skip to content

Operations · Tutorial

Self-hosting

Build and run Krakstack Auth with PostgreSQL while accounting for its current build-time configuration and service dependencies.

Krakstack Auth runs as a Bun application backed by PostgreSQL. The current deployment model is not yet a generic pull-and-configure container: Vite public values and the administration organization ID are compiled into browser assets.

Published image status#

The GitHub Container Registry package is the artifact used by the official deployment. Its build receives official-instance URLs and an organization ID. Runtime VITE_* variables cannot replace values already embedded by Vite.

Do not deploy ghcr.io/krakcons/krakstack-auth:latest as a differently configured auth service until a generic image pipeline or runtime public configuration is available. Build a deployment-specific image from a reviewed source revision instead.

Build-time prerequisites#

The current admin route requires VITE_KRAKSTACK_AUTH_ORGANIZATION_ID. Establishing that organization for a new database is deployment-specific and not yet covered by an automated first-admin bootstrap. Resolve this bootstrap before exposing the service.

Build with the public origin and administration organization that belong to the deployment:

bash
docker build \  --build-arg VITE_SITE_URL=https://auth.example.com \  --build-arg VITE_KRAKSTACK_AUTH_URL=https://auth.example.com \  --build-arg VITE_KRAKSTACK_AUTH_ORGANIZATION_ID=organization_id \  -t krakstack-auth:local .

Docker Compose#

The application listens on port 3000. Its start command applies Drizzle migrations before starting the server.

yaml
services:  auth:    image: krakstack-auth:local    restart: unless-stopped    ports:      - "3000:3000"    environment:      DATABASE_URL: postgres://krakstack:${POSTGRES_PASSWORD}@postgres:5432/krakstack_auth      BETTER_AUTH_SECRET: ${BETTER_AUTH_SECRET}      BETTER_AUTH_URL: https://auth.example.com      BETTER_AUTH_TRUSTED_ORIGINS: https://auth.example.com,https://app.example.com      S3_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID}      S3_SECRET_ACCESS_KEY: ${S3_SECRET_ACCESS_KEY}      S3_BUCKET: ${S3_BUCKET}    depends_on:      postgres:        condition: service_healthy
  postgres:    image: postgres:17    restart: unless-stopped    environment:      POSTGRES_DB: krakstack_auth      POSTGRES_USER: krakstack      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}    volumes:      - postgres-data:/var/lib/postgresql/data    healthcheck:      test: ["CMD-SHELL", "pg_isready -U krakstack -d krakstack_auth"]      interval: 5s      timeout: 5s      retries: 10
volumes:  postgres-data:

Generate BETTER_AUTH_SECRET with openssl rand -base64 32 and keep every secret outside version control. The current API layer requires S3 configuration. Production email flows require SES credentials when they run. See configuration for the complete categories.

Start and validate#

bash
docker compose up -ddocker compose logs -f auth

Validate more than /api/auth/ok: test a database-backed session, enabled email flow, asset operation, OAuth callback, and administrative access. The ok endpoint is liveness only.

Production checklist#

  • Terminate TLS and redirect HTTP to HTTPS.
  • Back up PostgreSQL and test restoration.
  • Keep the public auth origin stable.
  • Restrict the administration organization and rotate service keys.
  • Configure SES deliverability and S3 durability.
  • Monitor database latency and dependency failures separately from liveness.
  • Review trusted origins and OAuth redirect URIs after deployment changes.
  • Follow the upgrade and recovery runbook; an older image is not guaranteed to support a forward-migrated database.