0010: Vibe Kanban POC — Self-Hosted Deployment
Summary
Deploy Vibe Kanban Cloud to k8s-lab as a self-hosted kanban board for AI development workflows. The component lives in the ai-dev repo but deploys to the code-server namespace, following the established OpenClaw cross-namespace pattern.
Problem Statement
The AI development environment needs a kanban board for tracking work. Vibe Kanban is an AI-native project management tool that integrates with coding agents. We want to self-host it on k8s-lab and make it accessible alongside the existing code-server and OpenCode tooling.
Goals
- Deploy a working Vibe Kanban Cloud instance on k8s-lab
- Accessible via public ingress at
vibe-kanban.lab.ctoaas.co - Authenticate users via Google OAuth (ingress gate) + GitHub OAuth (VK identity)
- Mount
code-server-storagePVC read-write for workspace/worktree operations (core functionality — VK creates git worktrees on disk to isolate task work) - Follow existing deployment patterns (Kustomize component, ArgoCD sync, ESO secrets)
Non-Goals
- Relay/tunnel server (not needed — web UI accessed directly)
- Azurite/blob storage for attachments (can add later)
- Multi-user team features (single-user POC)
Architecture Findings
Vibe Kanban Cloud Stack
Vibe Kanban Cloud is a 3-service stack:
| Service | Image | Port | Purpose |
|---|---|---|---|
| remote-server | Built from crates/remote/Dockerfile | 8081 | Rust binary serving web UI + REST API |
| remote-db | postgres:16-alpine | 5432 | PostgreSQL with wal_level=logical |
| electric | electricsql/electric:1.3.3 | 3000 | ElectricSQL real-time sync |
Key facts:
- State is stored in PostgreSQL (not markdown/files)
- OAuth is mandatory — no single-user or password mode exists
- No pre-built Docker images — build from source via image-factory (
crates/remote/Dockerfile), pinned version - The remote-server serves the full web UI (React SPA) + API on a single port (8081)
- Health check:
GET http://127.0.0.1:8081/v1/health - Build time: 10-15 minutes (Rust compilation)
Workspace & Filesystem Interaction
VK is not a passive kanban board — it actively interacts with the filesystem:
- When you create a workspace, VK creates a git worktree on disk (a separate working directory with its own branch)
- Worktrees are stored in
.vibe-kanban-workspaces/(configurable) - Coding agents launched by VK read/write files in these worktrees
- VK can create PRs, manage branches, and run git operations
This means the code-server-storage PVC must be mounted read-write with appropriate UID/GID permissions. The VK server also needs git credentials (SSH keys or tokens) for remote git operations.
Startup Ordering
ElectricSQL depends on a database user (electric_sync) that the remote-server creates on first startup via migrations. The required startup order is:
- PostgreSQL starts first (readiness:
pg_isready) - remote-server starts after Postgres is healthy (runs migrations, creates
electric_syncuser) - ElectricSQL starts after remote-server is healthy (connects as
electric_sync)
Source Code
https://github.com/BloopAI/vibe-kanban
Deployment Pattern
Cross-Namespace Pattern (Following OpenClaw)
The component lives in the ai-dev repo at infrastructure/kustomize/components/vibe-kanban/ but deploys to the code-server namespace. This works because:
- The component’s
kustomization.yamlsetsnamespace: code-server - Kustomize stamps this namespace on all resources in the component
- The ArgoCD
ai-devAppProject allowsnamespace: '*' - ArgoCD applies the rendered manifests to whichever namespace Kustomize assigned
Reference implementation: infrastructure/kustomize/components/openclaw/ (same pattern).
Authentication Strategy
Dual-layer authentication — both layers serve different purposes:
Ingress layer (access control): Keep the standard traefik Google OAuth middleware (traefik-google-auth@kubernetescrd). This prevents unauthenticated access from the public internet. The Google OAuth cookie is shared across *.lab.ctoaas.co, so you’ll already be authenticated from other services (code-server, etc.) — no extra login prompt.
Application layer (user identity): VK’s built-in GitHub OAuth provides user identity within the app. The code-server namespace already has the gh-oauth secret via ClusterExternalSecret. The callback URL (/v1/oauth/github/callback) should pass through the forwardAuth middleware since you’d already have a valid Google OAuth session cookie.
Important: The existing GitHub OAuth App must have Vibe Kanban’s callback URL added:
https://vibe-kanban.lab.ctoaas.co/v1/oauth/github/callback
Note: If VK also supports Google OAuth natively, we could potentially use the same Google credentials for both layers, reducing to a single sign-in. Worth investigating but not required for POC.
Secrets
| Secret | Source | Notes |
|---|---|---|
GITHUB_CLIENT_ID | Existing gh-oauth secret in code-server ns | Already available via ClusterExternalSecret |
GITHUB_CLIENT_SECRET | Existing gh-oauth secret in code-server ns | Already available via ClusterExternalSecret |
VIBEKANBAN_REMOTE_JWT_SECRET | New — add to central-secret-store | Generate with openssl rand -base64 48 |
DB_PASSWORD | New — add to central-secret-store | Secure password for Postgres |
ELECTRIC_ROLE_PASSWORD | New — add to central-secret-store | Must match between remote-server and electric |
New secrets are pulled via an ExternalSecret resource in the component, referencing the central-secret-store ClusterSecretStore (same pattern as OpenClaw’s externalsecret.yaml).
PVC Usage
| PVC | Created By | Mount Mode | Purpose |
|---|---|---|---|
code-server-storage | Pre-existing (remote-development) | Read-write | Source code access for workspace/worktree creation, git operations |
vibe-kanban-db | This component | Read-write | Postgres data (/var/lib/postgresql/data), 5Gi |
vibe-kanban-electric | This component | Read-write | ElectricSQL persistent state (/app/persistent), 1Gi |
Security context: The code-server-storage PVC is owned by UID 1000 (coder). The VK remote-server must run as runAsUser: 1000, fsGroup: 1000 to match, same as other pods that mount this PVC (code-server, codev, static-files).
Node scheduling: code-server-storage is ReadWriteOnce and already shared by multiple pods on the same node. VK pods must also land on that node — may need a nodeSelector or affinity rule if scheduling becomes an issue.
Git Credentials
VK needs git credentials for worktree operations and PR creation. The code-server namespace has:
ssh-keysecret — SSH private key for git operationsgh-oauthsecret — GitHub token for API operations
Mount the SSH key into the VK container (same pattern as code-server) to enable remote git operations.
Docker Image
Build via image-factory rather than a one-off manual build:
- Enrol in
image-factory-state/images.yaml - Source:
BloopAI/vibe-kanban(upstream directly — no fork needed for POC) - Dockerfile:
crates/remote/Dockerfile - This gives automated rebuilds, base image tracking, and version pinning
- Image published to
ghcr.io/craigedmunds/vibe-kanban-remote:<pinned-version>
Resource Estimates
| Service | CPU Request | Memory Request | CPU Limit | Memory Limit |
|---|---|---|---|---|
| remote-server | 100m | 256Mi | 500m | 1Gi |
| remote-db | 100m | 256Mi | 500m | 1Gi |
| electric | 50m | 128Mi | 250m | 512Mi |
| Total | 250m | 640Mi | 1250m | 2.5Gi |
Open Questions
-
GitHub OAuth App callback: Need to verify the existing GitHub OAuth App supports multiple callback URLs, and add
https://vibe-kanban.lab.ctoaas.co/v1/oauth/github/callback. -
Google OAuth at both layers: If VK supports Google OAuth natively, could use the same Google OAuth app for both traefik and VK — single sign-in experience. Worth checking VK’s OAuth config options.
-
VK_ALLOWED_ORIGINS: Must be set tohttps://vibe-kanban.lab.ctoaas.coon the remote-server, or API requests will get 403 behind the ingress. -
SERVER_DATABASE_URLinterpolation: The URL includes$(DB_PASSWORD)relying on Kubernetes env var substitution. SinceDB_PASSWORDis defined beforeSERVER_DATABASE_URLin the container spec, this should work — but worth watching during first deployment. -
Image-factory source: Using
BloopAI/vibe-kanbandirectly. Fork only if we need local patches later. -
Workspace directory location: VK defaults to
.vibe-kanban-workspaces/— need to verify this is configurable and decide where on the PVC to place it.