Quickstart
Zero to a verified, immutable backup of one repo, in about 10 minutes.
gitdr is a single static Linux binary that runs as a one-shot job. On macOS, run the
container (ghcr.io/gitdr-io/gitdr).
1. Get the binary
Section titled “1. Get the binary”# containerdocker run --rm ghcr.io/gitdr-io/gitdr version# or via Go (1.26+)go install gitdr.io/gitdr/cmd/gitdr@latestStatic binaries with checksums and cosign signatures are also on the releases page.
2. Make a WORM bucket
Section titled “2. Make a WORM bucket”gitdr strongly recommends an immutable destination. It warns if the bucket isn’t WORM,
and --require-worm makes it fail closed. Immutability is the whole point of a
ransomware-resistant backup, so set one up. Pick your provider.
AWS S3, Object Lock (only settable at creation):
aws s3api create-bucket --bucket my-worm-bucket --region us-east-1 \ --object-lock-enabled-for-bucketaws s3api put-object-lock-configuration --bucket my-worm-bucket \ --object-lock-configuration \ '{"ObjectLockEnabled":"Enabled","Rule":{"DefaultRetention":{"Mode":"COMPLIANCE","Days":30}}}'Google Cloud Storage, locked retention policy (the lock is irreversible):
gcloud storage buckets create gs://my-worm-bucket --location=US \ --uniform-bucket-level-access --public-access-prevention --retention-period=30dgcloud storage buckets update gs://my-worm-bucket --lock-retention-periodAzure Blob, create a storage account with version-level immutability plus blob versioning, then a container (Azure docs).
Scope the credential gitdr uses to create/put only. It never needs delete.
3. Source credentials (read-only)
Section titled “3. Source credentials (read-only)”- GitHub. Create a GitHub App with read-only repo and metadata, install it, note the App ID and Installation ID, and download the private key (PEM).
- GitLab. A project or group access token with
read_apiandread_repository.
4. Manifest signing key
Section titled “4. Manifest signing key”Every run writes an ed25519-signed manifest. Make the keypair once.
openssl genpkey -algorithm ed25519 -out manifest-signing.pemopenssl pkey -in manifest-signing.pem -pubout -out manifest-public.pemKeep manifest-signing.pem secret and off the runner if you can. verify only needs the
public key.
5. Config
Section titled “5. Config”Copy config.example.yaml to config.yaml and set the source and destination. A minimal
GitHub to S3 setup:
source: type: github repo: "acme/api" github: { appID: 123456, installationID: 7890123 }destination: type: s3 s3: { bucket: my-worm-bucket, region: us-east-1 } retention: { mode: COMPLIANCE, days: 30 }manifest: publicKeyPath: ./manifest-public.pemworm: { require: false } # warn on non-WORM and proceed. true means fail closed6. Secrets (env only, never in the YAML)
Section titled “6. Secrets (env only, never in the YAML)”export GITDR_GITHUB_APP_PRIVATE_KEY="$(cat github-app.pem)"export GITDR_MANIFEST_SIGNING_KEY="$(cat manifest-signing.pem)"export AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... # or use an instance role7. Preflight, then back up
Section titled “7. Preflight, then back up”gitdr doctor --config config.yaml # checks config, source auth, and the WORM lockgitdr backup --config config.yaml # clone, bundle, sha256, immutable upload, signed manifestdoctor writes nothing. backup exits non-zero on any failure, so treat that as a failed
backup. The run prints the manifest key.
8. Verify
Section titled “8. Verify”gitdr verify --config config.yaml --manifest <manifest-key-from-step-7>signature valid: true, artifacts N/N ok means the run is signed and intact. To prove a
real restore, follow the restore runbook.
9. Schedule it
Section titled “9. Schedule it”- Kubernetes. The Helm chart (CronJob).
- VM. The systemd timer or cron sample.
- CI. Call
gitdr backupfrom your pipeline.
Optional: client-side encryption
Section titled “Optional: client-side encryption”To keep the storage provider from reading your data, set encryption.enabled: true and
give it a 32-byte key in GITDR_ENCRYPTION_KEY (64-char hex, base64, or raw). verify
stays key-free. restore needs the key.