Skip to content

feat: hosted deployment stack — production compose, /healthz, image publish, ops runbook#71

Merged
BunsDev merged 2 commits into
mainfrom
feat/hosted-deploy-stack
Jul 8, 2026
Merged

feat: hosted deployment stack — production compose, /healthz, image publish, ops runbook#71
BunsDev merged 2 commits into
mainfrom
feat/hosted-deploy-stack

Conversation

@BunsDev

@BunsDev BunsDev commented Jul 8, 2026

Copy link
Copy Markdown
Member

What

The operational half of the HOSTED.md beta gates. Architecture: one VM + Docker Compose, because the store is single-writer SQLite and the container worker backend drives the host Docker daemon — a cluster buys nothing at beta scale, and Hosted Dedicated later is this same stack on a customer-dedicated VM.

  • deploy/hosted/ — production compose (adapter + Caddy TLS ingress + Litestream → Cloudflare R2 SQLite replication, 10s sync / 30-day retention), .env.example, idempotent provision.sh (Docker, ufw 22/80/443, unattended upgrades, uid-10001 dir ownership, docker-gid wiring for the unprivileged worker).
  • GET /healthz — unauthenticated liveness/readiness probing the store; returns only {"ok": true}/503, no tenant data. Wired into the server router, compose healthcheck, and runbook monitoring.
  • publish.yml — GHCR image publish (latest + SHA on main, semver on tags); Dockerfile gains curl for the healthcheck.
  • docs/hosted-deploy.md — first-deploy runbook (target: gh.opencoven.ai on Hetzner), monitoring signals, backup/restore drill, upgrades, incident basics. Cross-linked from HOSTED.md's beta-gate section.

Testing

  • cargo check --all-targets / clippy -- -D warnings / cargo test --all ✅ (298 passed, incl. new healthz test)
  • Python adapter suite ✅
  • docker compose config validates; bash -n provision.sh clean
  • No secrets committed — .env is a template; keys/config are mounted at runtime

…ublish, ops runbook

The operational half of the HOSTED.md beta gates (the six code gates are
shipped). Single-VM architecture matching what the code wants: single-writer
SQLite and a container worker backend that drives the host Docker daemon.

- deploy/hosted/: production compose (adapter + Caddy TLS ingress +
  Litestream SQLite replication to Cloudflare R2), Caddyfile, litestream.yml,
  .env.example, and an idempotent provision.sh for Ubuntu 24.04 (Docker,
  firewall 22/80/443, layout, docker-gid + uid-10001 permissions).
- /healthz: unauthenticated liveness/readiness route probing the store —
  compose healthcheck and uptime monitors point at it; leaks no tenant data.
- Dockerfile: add curl for the container healthcheck.
- .github/workflows/publish.yml: build/push ghcr.io/opencoven/coven-github
  (latest + SHA on main, semver on tags).
- docs/hosted-deploy.md: first-deploy runbook, monitoring signals, backup and
  restore drill, upgrade and incident basics. Cross-linked from HOSTED.md.

Validated: docker compose config, bash -n provision.sh, full CI gates.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Val Alexander <bunsthedev@gmail.com>
Copilot AI review requested due to automatic review settings July 8, 2026 20:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds the operational “hosted” deployment stack for the coven-github GitHub App adapter (single-VM Docker Compose), plus a minimal /healthz probe and GHCR image publishing to support production rollouts and monitoring.

Changes:

  • Introduces deploy/hosted/ production stack (Compose + Caddy TLS ingress + Litestream to Cloudflare R2) and an idempotent Ubuntu provisioning script.
  • Adds unauthenticated GET /healthz and wires it into the server router (plus a small route test).
  • Adds a GH Actions workflow to publish images to GHCR and documents the end-to-end hosted deploy runbook.

Reviewed changes

Copilot reviewed 11 out of 13 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
HOSTED.md Cross-links the hosted operational runbook/stack into the beta gates section.
docs/hosted-deploy.md Adds first-deploy + monitoring/backup/restore/upgrade incident runbook for the hosted VM stack.
Dockerfile Installs curl to support container healthchecks against /healthz.
deploy/hosted/provision.sh Adds host provisioning script for Docker, firewall, unattended upgrades, and /opt/coven-github layout.
deploy/hosted/litestream.yml Configures Litestream replication to Cloudflare R2 with retention and sync interval.
deploy/hosted/compose.yaml Defines production services (adapter, Caddy, Litestream) including healthcheck and docker-sock wiring.
deploy/hosted/Caddyfile Adds TLS ingress config for the webhook domain via Caddy.
deploy/hosted/.env.example Provides a template for required deployment secrets/config values.
crates/webhook/src/routes.rs Implements /healthz route and adds a liveness “leaks nothing” test.
crates/server/src/main.rs Wires /healthz into the axum router.
.github/workflows/publish.yml Adds GHCR publish workflow for latest/SHA on main and semver tags on releases.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/webhook/src/routes.rs Outdated
let state = app_state();
let response = healthz(State(state)).await.into_response();
assert_eq!(response.status(), StatusCode::OK);
let bytes = axum::body::to_bytes(response.into_body(), usize::MAX)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Val Alexander <bunsthedev@gmail.com>
@BunsDev BunsDev merged commit 12be5b6 into main Jul 8, 2026
1 check passed
@BunsDev BunsDev deleted the feat/hosted-deploy-stack branch July 8, 2026 21:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants