mirror of
https://relay.ngit.dev/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit-grasp.git
synced 2026-10-05 23:18:24 +00:00
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)
160 lines
5.2 KiB
Markdown
160 lines
5.2 KiB
Markdown
# Deploy with Docker or Podman
|
|
|
|
This is the portable default for a Linux host. The repository ships a
|
|
multi-stage `Dockerfile`, a loopback-only Compose service, and an optional
|
|
Caddy overlay for automatic HTTPS.
|
|
|
|
The image contains ngit-grasp, Git, CA certificates, and a small init process.
|
|
It prepares `/data` and then runs ngit-grasp as UID/GID `10001`.
|
|
|
|
Stable release images are published through Nostr, with their OCI blobs stored
|
|
on Blossom. Docker and Podman can pull them through the ncontainer gateway:
|
|
|
|
```bash
|
|
docker pull ncontainer.io/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit-grasp:latest
|
|
```
|
|
|
|
`latest` tracks the newest stable release. Replace it with an explicit release
|
|
version for a reproducible deployment. Release candidates are also published
|
|
under their prerelease channel, such as `rc`.
|
|
|
|
## Prerequisites
|
|
|
|
- Docker Engine with Compose v2, or a compatible Podman Compose setup
|
|
- durable local storage for the named volume
|
|
- a domain whose DNS points to the host
|
|
- ports 80 and 443 available when using bundled Caddy
|
|
|
|
Review the [deployment contract](../reference/deployment-contract.md) before
|
|
placing the state volume on remote or managed storage.
|
|
|
|
## Fresh VPS with automatic HTTPS
|
|
|
|
Create the small deployment environment file:
|
|
|
|
```bash
|
|
cp deploy.env.example .env
|
|
```
|
|
|
|
Set `NGIT_DOMAIN` in `.env`, then start the relay and Caddy:
|
|
|
|
```bash
|
|
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
|
|
docker compose -f compose.yaml -f compose.caddy.yaml ps
|
|
scripts/verify-deployment.sh https://ngit.example.com
|
|
```
|
|
|
|
Caddy obtains and renews the certificate. The relay is also published on
|
|
`127.0.0.1:7334` for local diagnostics, but it is not directly reachable from
|
|
the network.
|
|
|
|
The bundled Caddy configuration serves ngit-grasp at the domain root. To share
|
|
a hostname using `NGIT_BASE_PATH`, use an existing reverse proxy and configure
|
|
its path routing explicitly.
|
|
|
|
## Existing reverse proxy
|
|
|
|
Start only the relay service:
|
|
|
|
```bash
|
|
export NGIT_IMAGE="ncontainer.io/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit-grasp:latest"
|
|
docker compose pull ngit-grasp
|
|
docker compose up --no-build -d
|
|
curl -H 'Accept: application/nostr+json' http://127.0.0.1:7334
|
|
```
|
|
|
|
To build a checked-out source revision instead, leave `NGIT_IMAGE` unset and
|
|
use `docker compose up --build -d` with the same Compose file selection.
|
|
|
|
Proxy the public HTTPS hostname to `http://127.0.0.1:7334`. Preserve WebSocket
|
|
upgrades, request methods, bodies, and query strings. Forwarded client IP
|
|
headers are ignored by default; configure `NGIT_TRUSTED_PROXY_CIDRS` only after
|
|
identifying the exact container-visible proxy address and keeping the backend
|
|
private.
|
|
|
|
## State and identity
|
|
|
|
The `ngit-grasp-data` named volume is mounted at `/data` and contains all
|
|
durable state. The first start creates `/data/.relay-owner.nsec`; retaining the
|
|
volume retains the public identity advertised in NIP-11.
|
|
|
|
Inspect the resolved volume without guessing its Compose prefix:
|
|
|
|
```bash
|
|
docker volume inspect ngit-grasp_ngit-grasp-data
|
|
```
|
|
|
|
Do not use `docker compose down --volumes` in production. It deletes the relay
|
|
identity, events, and Git repositories.
|
|
|
|
## Operations
|
|
|
|
```bash
|
|
# Logs
|
|
docker compose logs --follow ngit-grasp
|
|
|
|
# Controlled restart
|
|
docker compose restart ngit-grasp
|
|
|
|
# Stop while retaining state
|
|
docker compose stop
|
|
|
|
# Start again
|
|
docker compose start
|
|
```
|
|
|
|
When the Caddy overlay is active, include both `-f` arguments for commands that
|
|
must operate on the complete project.
|
|
|
|
## Backup
|
|
|
|
Stop the writer, archive the complete volume, and start it again:
|
|
|
|
```bash
|
|
docker compose stop ngit-grasp
|
|
docker run --rm \
|
|
--volume ngit-grasp_ngit-grasp-data:/data:ro \
|
|
--volume "$PWD:/backup" \
|
|
alpine:3.22 \
|
|
tar -czf /backup/ngit-grasp-data.tar.gz -C /data .
|
|
docker compose start ngit-grasp
|
|
```
|
|
|
|
Store the archive away from the Docker host. Test restoration into a separate,
|
|
non-public deployment before relying on it.
|
|
|
|
## Upgrade
|
|
|
|
Read `CHANGELOG.md`, take a backup, select an explicit release tag, and replace
|
|
the container without overlapping the old and new writers:
|
|
|
|
```bash
|
|
export NGIT_IMAGE="ncontainer.io/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit-grasp:3.0.2"
|
|
docker compose pull ngit-grasp
|
|
docker compose stop ngit-grasp
|
|
docker compose up --no-build -d ngit-grasp
|
|
scripts/verify-deployment.sh https://ngit.example.com
|
|
```
|
|
|
|
Replace `3.0.2` with the intended release. For a source-built deployment,
|
|
check out that tag and run `docker compose build --pull ngit-grasp` before
|
|
starting the service instead.
|
|
|
|
For storage-changing releases, follow the linked migration guide and restore
|
|
the pre-upgrade volume snapshot before attempting a binary rollback.
|
|
|
|
## Validate the image locally
|
|
|
|
The repository includes a destructive-to-test-resources-only integration
|
|
check. It builds the image, creates uniquely named temporary container and
|
|
volume resources, replaces the container, and confirms the NIP-11 pubkey did
|
|
not change:
|
|
|
|
```bash
|
|
scripts/test-container-deployment.sh
|
|
```
|
|
|
|
Set `CONTAINER_ENGINE=podman` to exercise a compatible Podman CLI.
|