Skip to content

Host repositories with ngit-grasp

ngit-grasp combines a Nostr relay with an authorised Git smart-HTTP server. Run it to provide repository hosting without becoming the source of truth for the repositories it stores.

If you only want to use somebody else's provider, install ngit. You do not need to operate a server.

GRASP keeps that choice reversible. Try self-hosting alongside one or more providers, then remove the service later if it no longer suits you; contributors do not need to change remotes or re-clone. Unlike a self-hosted Forgejo instance, an ngit-grasp service is not a long-term repository-hosting commitment.

Choose a deployment

EnvironmentStarting pointWhy
Fresh VPSDocker Compose with CaddyShort path to persistent storage and TLS
NixOSFlake moduleDeclarative service and protected credentials
Existing Linux hostHardened systemd unitDirect binary lifecycle
Proxmox LXC or VMDirect or Compose deploymentFits an existing virtualisation host
Managed container hostPaaS deploymentWorks when persistent volumes and WebSockets are available
DevelopmentNix development shellPinned Rust and test dependencies

The imported deployment chooser covers these paths in more detail, while the deployment contract defines their shared runtime and persistence requirements.

Container quick start

From a clean ngit-grasp checkout, select the published stable image:

bash
cp deploy.env.example .env
# Set NGIT_DOMAIN and point DNS at this host.
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://git.example.com

A running container is not enough. The verification script checks the public WebSocket relay, Git smart HTTP, discovery, storage, and proxy behaviour.

Configure the service

The generated operator reference is the authority for all public commands, environment options, defaults, validation rules, and secret precedence:

The reference and operator guides are pinned to the exact v3.0.2 release. Do not infer missing settings from this overview.

Private repository service

Private repository support requires ngit v3+ and ngit-grasp v3+. The current model is self-hosted: maintainers operate a GRASP-08 service for their group and manage its npub whitelist themselves. See the imported GRASP-08 private service design for implementation detail.

Private mode applies to the whole service, not one repository. Start with:

dotenv
NGIT_PRIVATE_MODE=true
NGIT_PRIVATE_MEMBERS=<MAINTAINER_NPUB>,<COLLABORATOR_NPUB>

Every listed member can read the service's repository trust domain. Normal GRASP repository authorisation still decides who may write signed state. A whitelist change requires a service restart, and private mode cannot be combined with the unauthenticated GRASP-06 contributor endpoint.

Set NGIT_PRIVATE_PUBLIC_ORIGIN when the externally visible origin cannot be inferred from NGIT_DOMAIN, such as when TLS terminates upstream. Review the generated private configuration options and constraints before starting the service.

Once the service is ready, follow Private repositories to publish the repository, grant access, and test an authenticated clone. That guide also separates today's operator work from the intended provider and Nostr-group direction.

Protect the important boundaries

Identity and secrets

Supply the relay-owner secret through a protected environment or service credential. Do not put it in a command-line argument, Compose file, or committed environment file.

Storage

Back up both relay state and Git object storage. When every hosted repository is replicated across other GRASP providers, you can rebuild an empty service and resynchronise it from the surviving providers. Backups are therefore less critical than for a centralised forge's sole copy, but still shorten recovery. Memory mode is for tests; its Git data is temporary.

Network exposure

Keep the service on loopback when a reverse proxy is the only public entry point. Configure trusted proxy CIDRs explicitly and test WebSocket upgrades as well as ordinary HTTP.

Consider running grasp-audit against your services to check for configuration issues.

Observability

Prometheus metrics are available below the configured base path. Monitor relay health, Git operations, proactive sync, purgatory, rate limiting, and storage before offering a public service. See the imported monitoring overview and Prometheus and Grafana setup.

Next