Files
DanConwayDev 5fed50e5e3 ci(release): publish OCI container images
Motivation: Release images should be built, checked, published, and consumed through the same Nostr-native OCI path operators will use, without relying on an unreviewed local release procedure.

Approach: Add a checked-in container manifest, a Docker-to-OCI layout helper, automatic tag publication and pull verification, a safe exact-tag backfill workflow, and deployment CI that imports and runs the exact generated layout.

Correctness: Release tags come only from reviewed OCI index annotations; ordinary publication preserves prior tags; historical backfills cannot move latest or prerelease channels; generated images and temporary resources use bounded, validated names and cleanup.

Excluded scope: This change does not alter ngit-grasp runtime behavior, change package versions, create v3.0.2, publish a container, move a release tag, or run the heavyweight container build in the coding VM.

Validation: git diff --check; shellcheck on all container scripts; actionlint on all affected workflows; ngit parsing of .ngit/containers.yaml; canonical source and v3.0.1 tag resolution. The PR pipeline performs the full OCI build, import, and deployment test.

Assisted-by: Codex (GPT-5)
2026-09-10 15:30:13 +00:00

1.9 KiB

Deploy ngit-grasp

ngit-grasp supports several single-instance production layouts. Choose the guide matching the host you already operate; every guide implements the same deployment contract.

Environment Start here Supplied artifact
Docker or Podman host Docker and Compose Published OCI image, compose.yaml, optional Caddy overlay
NixOS NixOS module nixosModules.default
Debian, Ubuntu, or another systemd Linux Static binary and systemd Static flake package and service unit
Proxmox LXC or VM Proxmox Direct systemd or Compose path
Railway, Render, or Fly.io Managed hosting Provider configuration templates

For a fresh internet-facing VPS, the shortest supported path is Docker Compose with the Caddy overlay:

cp deploy.env.example .env
# Set NGIT_DOMAIN in .env and point its DNS records at this server.
export NGIT_IMAGE="ncontainer.io/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit-grasp:latest"
docker compose -f compose.yaml -f compose.caddy.yaml pull ngit-grasp
docker compose -f compose.yaml -f compose.caddy.yaml up --no-build -d
scripts/verify-deployment.sh https://ngit.example.com

The Caddy path requires ports 80 and 443. If the host already has a reverse proxy, follow the loopback-only path in the Docker guide instead.

Unsupported layouts

Do not deploy ngit-grasp to serverless functions, an ephemeral filesystem, or multiple replicas. It owns long-lived WebSockets, background synchronization, local Git repositories, LMDB state, and a durable relay identity.

Kubernetes can run the container as a one-replica StatefulSet with a ReadWriteOnce volume, but the repository does not yet ship or promise a Helm chart. A container host or systemd service is simpler unless Kubernetes is an existing operational requirement.