Skip to main content

repository-setup

This skill should be used when the user asks to "set up a restic repository on Cloudflare R2", "configure restic with S3 credentials", "create the restic encryption password", "initialize a restic repo", "fix restic AccessDenied on R2", or needs to wire up the password, R2/S3 env file, repository URL, and run restic init.

Source facts

Repository
Agents-Store/codex-plugins
Last source activity
November 1, 2026 at 02:46
Detected SKILL.md language
English
Stars
0
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
2 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
repository-setup
description
This skill should be used when the user asks to "set up a restic repository on Cloudflare R2", "configure restic with S3 credentials", "create the restic encryption password", "initialize a restic repo", "fix restic AccessDenied on R2", or needs to wire up the password, R2/S3 env file, repository URL, and run restic init.
# restic Repository Setup (Cloudflare R2 / S3) Create the encryption password, wire up the storage credentials, and initialize the repository. restic always encrypts client-side (AES-256) — **the password is the only key; lose it and the backup is permanently unrecoverable.** R2 server-side encryption is redundant here. ## Step 1 — Encryption password ```bash install -d -m700 /root/.restic openssl rand -base64 48 > /root/.restic/password # strong random key chmod 600 /root/.restic/password ``` > **STOP — copy this password off the server right now** (password manager / vault). Without it, none of the backups can ever be restored. This is the single most important action in the whole setup. ## Step 2 — Storage credentials env file Write `/root/.restic/r2.env` (mode 600). For **Cloudflare R2**: ```bash cat > /root/.restic/r2.env <<'EOF' AWS_ACCESS_KEY_ID=<R2 access key id> AWS_SECRET_ACCESS_KEY=<R2 secret access key> AWS_DEFAULT_REGION=auto RESTIC_REPOSITORY=s3:https://<account_id>.r2.cloudflarestorage.com/<bucket> RESTIC_PASSWORD_FILE=/root/.restic/password RESTIC_COMPRESSION=auto EOF chmod 600 /root/.restic/r2.env ``` - **Repository URL form:** `s3:https://<account_id>.r2.cloudflarestorage.com/<bucket>` — note the `s3:` prefix in front of the full `https://` endpoint. - **`AWS_DEFAULT_REGION=auto` is required for R2** (or pass `-o s3.region=auto`). Standard AWS region names do not work. - **`RESTIC_COMPRESSION`:** `auto` is a sound default. On 0.19+ the zstd levels `fastest` and `better` are also valid next to `max` and `off` — `fastest` uses the least CPU, `max` compresses hardest. 0.19 also loads the repository index much faster, which helps `check`/`prune`/`mount` on large R2 repositories. - Other S3-compatible providers: same shape, e.g. Wasabi `s3:https://s3.<region>.wasabisys.com/<bucket>`, MinIO `s3:http://host:9000/<bucket>`, AWS `s3:s3.amazonaws.com/<bucket>` (+ real region). **Sourcing for any manual restic command:** ```bash set -a; . /root/.restic/r2.env; set +a ``` ## Step 3 — Initialize and verify ```bash set -a; . /root/.restic/r2.env; set +a # IDEMPOTENCY: never re-init over an existing repo. Check first. if restic cat config >/dev/null 2>&1; then echo "Repository already exists — do NOT re-init (would not overwrite, but never regenerate the password)." else restic init # creates the encrypted repo (format v2 by default; `--repository-version latest|stable` to choose) fi restic cat config # readable config => keys + password work; expect "version":2 ``` `"version":2` confirms repository format v2 — compression is active. If it shows v1 (older binary created it), upgrade in place: `restic migrate upgrade_repo_v2`. ## R2 API token requirements The R2 API token must have: - **Object Read & Write** permission - a scope that **includes this bucket** (or all buckets in the account) - the bucket must exist in the **same account** whose `account_id` is in the endpoint ## Troubleshooting `init` (AccessDenied / connection) | Symptom | Cause | Fix | |---------|-------|-----| | `AccessDenied` | token lacks Object Read & Write, or scope excludes the bucket | re-issue the R2 token with Object Read & Write covering the bucket | | `AccessDenied` but token looks right | `account_id` in the endpoint ≠ the token's account | match the endpoint's account id to the token's account (the #1 cause) | | signature / region errors | missing region | `AWS_DEFAULT_REGION=auto` (or `-o s3.region=auto`) | | bucket lookup / vhost failures | provider needs path-style | add `-o s3.bucket-lookup=path` | | `NoSuchBucket` | bucket not created | create the bucket in the R2 dashboard first | | `SignatureDoesNotMatch` | clock skew or wrong secret | sync time (`timedatectl`), re-check the secret key | Fix R2 tokens in the Cloudflare dashboard → R2 → Manage R2 API Tokens. ## R2 cost & lifecycle - R2 has **zero egress fees**; you pay for storage + Class A/B operations. restic's pack format keeps operation counts reasonable. - **CRITICAL — never set a bucket lifecycle rule that deletes or expires objects.** restic owns retention via `forget --prune` (see `backup-script`); any external deletion corrupts the repository. A lifecycle rule that only **aborts incomplete multipart uploads** is safe and recommended. ## Encryption at rest restic encrypts everything client-side before upload, so the objects in R2 are already ciphertext. Enabling R2/S3 SSE on top is harmless but redundant — it does not protect you if the restic password is lost. ## Gotchas - **Password loss = total, unrecoverable loss.** Force an off-server copy before `init`. - **Idempotency:** check `restic cat config` before `init`; **never regenerate the password over an existing repo** — you'd lose access to every prior snapshot. - Both `/root/.restic/password` and `/root/.restic/r2.env` must be mode **600**, root-owned. Never commit `r2.env` to git. - Repo format v2 / compression needs restic **≥ 0.14**; target **≥ 0.19.1** (see `setup`). - **A typo in `RESTIC_COMPRESSION` is fatal since 0.19.0** — valid values are `off`, `auto` (default), `fastest`, `better`, `max`. Same for `RESTIC_PACK_SIZE` and `RESTIC_READ_CONCURRENCY`. ## What this skill does NOT cover - Choosing what to back up → `discover-backup-sources` - The backup script and retention → `backup-script` - Restoring → `disaster-recovery`
View on GitHub