Skip to main content

Fork bring-up & deploy automation

A Zeq node is self-hostable: its own database, its own field key, its own audit trail, zero coupling to anyone else's. infra/zeq-fork.sh is the single tool for the three things you do to a node over its life — stand one up, update the fleet, and check the mesh — so each is one command instead of a runbook.

./infra/zeq-fork.sh health # read-only mesh sweep
./infra/zeq-fork.sh deploy --all [--dry-run] # build once → every node
./infra/zeq-fork.sh bringup <domain> <api_port> <pg_port> [--dry-run]

Every mutating path takes --dry-run: it prints the exact SSH / Docker / build commands it would run and touches nothing, while still running the read-only probes. Run it that way first.

health — the read-only mesh sweep

For each live node it reads /api/health (status + commit) and /api/zeq/conformance (the golden-vector result + registry version), then checks cross-node uniformity: every node in one mesh should run the same commit and the same registry_version. A split means either a deploy didn't reach every node (deploy drift) or two nodes disagree on the operator registry (registry drift) — both are bugs, both fail the sweep.

✓ zeq.dev health=ok conf=ok 17/17 sha=34ffb0690874 reg=95aa2149d8ae
✓ zeqsdk.com health=ok conf=ok 17/17 sha=34ffb0690874 reg=95aa2149d8ae

git_sha across mesh: uniform (no deploy drift)
registry_version across mesh: uniform (synchronized physics)

It needs no credentials — every field it reads is already public — so it is the one subcommand that is safe to run from CI. --json emits a machine-readable report; exit 0 means every node is healthy, conformant, and uniform, 5 means something drifted.

deploy — build once, ship to every node

The bundle is built locally (a node has no build toolchain inside its container), shipped once, then docker cp'd into every api container the tool discovers from docker ps — not a hard-coded list, so a node added yesterday is included automatically. Each container restarts, and the post-deploy health sweep is the acceptance gate: a deploy that leaves the mesh split fails loudly. The canonical test suite runs first and blocks a red deploy (SKIP_TESTS=1 is the documented escape hatch for re-shipping an already-green commit).

bringup — a sovereign node in one command

bringup runs the full bring-up sequence and bakes in the one step that is easy to forget and expensive to skip:

StepWhat happens
spinThe isolated stack — its own Postgres, api container, field key, public mount — comes up behind nginx with a fresh certificate. DNS must already point at the host.
schema convergeThe new database is converged to the canonical schema (drizzle-kit push) over an SSH tunnel before the api leans on it. This is idempotent: it brings any starting state up to the current schema.
preboot gateA no-toolchain SQL check on the host confirms every required table and column is present — the cheap sanity gate, run against the new database.
verifyThe api restarts against the converged schema and the health sweep runs against the new node.

The schema-converge step exists because the first fork ever stood up crash-looped on its first compute: it had been brought up against a point-in-time database dump that lagged the code, so a table the runtime expected wasn't there. Converging the schema from the canonical source — rather than restoring a snapshot — removes that failure mode at the root. bringup makes it part of the one command, not a step you remember.

The only host state a node needs is the two bootstrap pointers (the field key that unlocks the vault, and the database URL to reach it); every other secret lives inside the node's own encrypted vault, hydrated at boot. Nothing about a node lives in a checked-in file.

In GitHub Actions

The read-only sweep ships as a composite action, so any repo — yours or a fork's — can gate on the live mesh. No secrets, because it only reads public endpoints:

# .github/workflows/mesh-health.yml
name: Zeq mesh health
on:
schedule: [{ cron: "*/30 * * * *" }] # every 30 min
workflow_dispatch:
jobs:
mesh:
runs-on: ubuntu-latest
steps:
- uses: hulyasmath/zeq-framework/.github/actions/zeq-mesh-health@main
# with:
# mesh: "zeq.dev zeqsdk.com zeqstate.com zeqond.com zeqapi.com"

It writes a node-by-node table to the job summary and fails the run on any down node, conformance failure, or mesh drift. deploy and bringup are operator commands rather than CI steps — they need host access and run from where the build toolchain lives.

See next

Source: infra/zeq-fork.sh; the action at .github/actions/zeq-mesh-health/. The lower-level primitives it orchestrates are infra/spin-domain.sh (stack + cert), infra/preboot-schema-check.sh (the SQL gate), and infra/deploy-vps.sh (single node).