clickclack/docs/deployment.md
2026-05-08 09:11:41 +01:00

4.2 KiB

read_when
shipping a release, building Docker, or planning a new install
changing how data is laid out on disk

Deployment

ClickClack ships as one Go binary that embeds the Svelte SPA and the SQL migrations. The deployment story is "drop a binary on a box, point it at a data directory, run it behind a reverse proxy."

Public surfaces:

  • clickclack.chat — product website.
  • app.clickclack.chat — chat app. The same app is also available at /app for local development and simple single-host deployments.
  • docs.clickclack.chat — documentation site built by pnpm docs:site.

Single binary

pnpm install
pnpm build                                          # builds the SPA into apps/api/internal/webassets/dist
go build -o clickclack ./apps/api/cmd/clickclack
./clickclack serve --addr :8080 --data /var/lib/clickclack

The Go build step requires the SPA dist/ to be present because webassets uses go:embed. The pnpm build script copies apps/web/dist into apps/api/internal/webassets/dist; CI must run it before go build.

Releases

GoReleaser is configured in .goreleaser.yml. It builds clickclack for Linux, macOS, Windows, and FreeBSD on amd64 and arm64, with Windows archives emitted as .zip and the others as .tar.gz. Linux .deb and .rpm packages are generated through nfpm.

pnpm install
goreleaser release --snapshot --clean

The GoReleaser config runs pnpm build before compiling so the embedded SPA is refreshed. Publishing is handled by .github/workflows/release.yml on v* tags or manual dispatch with an existing tag.

Docker

The provided Dockerfile is multi-stage:

docker build -t clickclack .
docker run --rm -p 8080:8080 -v clickclack-data:/app/data clickclack

Stages:

  1. node:25-alpine — installs pnpm dependencies and runs pnpm build.
  2. golang:1.26-alpine — builds the Go binary, importing the SPA dist.
  3. alpine:3.23 — runtime image, runs as the clickclack user, exposes 8080, mounts /app/data as a volume.

Override the entrypoint command to run admin tasks:

docker run --rm -v clickclack-data:/app/data clickclack \
  admin bootstrap --name "Peter" --email steipete@gmail.com

Data layout

<data>/
  clickclack.db                  # SQLite database (WAL files alongside)
  uploads/                       # local files for /api/uploads
  logs/                          # reserved; nothing writes here today

Back this directory up. SQLite WAL means a snapshot of the directory is consistent enough, but prefer the online backup:

clickclack backup --data /var/lib/clickclack --out /var/backups/clickclack-$(date +%F).db

Reverse proxy

Required for TLS, Origin enforcement, and request size limits. The WebSocket endpoint accepts upgrades with InsecureSkipVerify=true today, so the proxy is the right place to enforce origin policy.

A minimal nginx block:

location / {
  proxy_pass http://127.0.0.1:8080;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
  proxy_read_timeout 300s;
}

GitHub OAuth

If you want GitHub login, set:

CLICKCLACK_PUBLIC_URL=https://chat.example.com
CLICKCLACK_GITHUB_CLIENT_ID=...
CLICKCLACK_GITHUB_CLIENT_SECRET=...
CLICKCLACK_GITHUB_ALLOWED_ORG=openclaw
CLICKCLACK_DEV_BOOTSTRAP=false

Configure the GitHub OAuth app callback to <public-url>/api/auth/github/callback. When CLICKCLACK_GITHUB_ALLOWED_ORG is set, ClickClack asks GitHub for read:org and only accepts active members of that org. See features/auth.md.

Migrations

clickclack serve applies migrations on boot. For zero-downtime deploys, run clickclack migrate ahead of the new binary so the old binary doesn't see unexpected tables. Migrations live in apps/api/internal/store/sqlite/migrations/ and are append-only.

Backups and restore

# hot backup
clickclack backup --out /var/backups/clickclack-$(date +%F).db

# JSON dump (good for sanity, not for restore)
clickclack export --out /var/backups/clickclack-$(date +%F).json

Restore is a file swap: stop clickclack, replace <data>/clickclack.db, delete any stale *.db-wal/*.db-shm, start it back up.