Winch Labs

Self-hosting

Installing Garboard

One Go binary and one Postgres 16 with the pgvector extension. No queue, no service mesh, no orchestration framework — a deliberate monolith.

Before you start

Garboard is distributed to design partners: signed release binaries with checksums, and a registry path with pull credentials. There is no public download. Email us if you want to evaluate a self-hosted install.

Postgres needs pgvector, and will not shout if it is missing

At startup Garboard runs CREATE EXTENSION IF NOT EXISTS vector. If that fails, the server still starts. It logs

store: episodic memory disabled (pgvector unavailable)

sets its episodic-memory gauge to false, and serves everything else normally.

Point a stock managed Postgres at it without enabling the extension and you get an install that looks healthy and is quietly missing a feature. Enable pgvector before first boot, and check that log line after it. On AWS RDS and Aurora PostgreSQL the extension is available but must be created.

Migrations run themselves

Schema migrations are versioned, advisory-locked and applied at startup. An upgrade is “replace the binary, restart”, and it is safe with several instances starting at once — the advisory lock means one applies and the others wait.

Migrations are forward-only. See upgrades and rollback before you plan a rollback strategy, because the honest answer is narrower than you might assume.

The minimum configuration

GARBOARD_DB_URL=postgres://…?sslmode=require
GARBOARD_BASE_URL=https://garboard.example.com   # must be publicly reachable
GARBOARD_GITHUB_APP_ID=…
GARBOARD_GITHUB_PRIVATE_KEY_FILE=/etc/garboard/app.pem
GARBOARD_WEBHOOK_SECRET=…
GARBOARD_SECRET_KEY=…                            # see below — back this up

GARBOARD_BASE_URL must be reachable from the internet, because your git host has to call <base>/webhook.

Everything is environment variables. There is no config file, and no flag that reads one. The complete list is generated from the source.

Back up GARBOARD_SECRET_KEY before you store anything

This is the envelope root key. Every per-organisation secret is sealed against it — most visibly an organisation’s SSO client secret.

Two consequences:

  • Without it set, an admin cannot save an identity provider at all. There is nothing to encrypt the client secret with, so per-organisation SSO is simply unavailable on an instance that does not set it.
  • Lose it and everything sealed with it is permanently unopenable. There is no recovery path. It is backup-critical in the way a database is, not configuration in the way a port number is.

GARBOARD_KMS_KEY_ID selects an external KMS key instead, with the same consequence managed elsewhere.

Helm

A chart ships the same shape for Kubernetes: the binary plus Postgres, every credential passed by reference rather than as a plain value.

image.repository has no useful default — there is no public mirror — so set it to wherever you mirrored the image.

Then connect a git host

Install the GitHub App, or see GitLab, which is experimental.

What it will never need

No cloud credentials. There is no code path that runs terraform apply or performs any cloud write. Everything Garboard produces is a comment, a check run, or a commit on a branch a human reviews. Your infrastructure keeps being changed only by your existing pipeline.