From ddd8462f3237d533ebca85ec236665a89a6a32db Mon Sep 17 00:00:00 2001 From: claude-hdb Date: Sun, 12 Jul 2026 19:18:46 +0000 Subject: [PATCH] chore: re-home the control-plane dump to rig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit scripts/dump-coolify-db.sh ran `docker exec coolify-db pg_dump` — it only works ON the control-plane box, as root, under a scheduler. cast is the off-box tool: its own README says "cast runs on your machine: it is an API client, and a server should never install it." The script contradicted that invariant, and cast's src/ never referenced it — it was payload that survived the rig/cast split without being re-homed. It now lives in rig as `rig coolify backup install` (heavy-duty/rig#9), which also installs age + awscli, a systemd timer, and a templated 0600 bindings file — none of which cast could do from off the box. Two defects were fixed in the move rather than carried over: the script now refuses to upload an empty artifact (a failed pg_dump piped into age still yields a valid, tiny, encrypted file that looks exactly like a working backup), and the unit defaults the aws-cli >= 2.23 checksum knobs that S3-compatible backends reject. The two scripts that remain are genuinely cast's: both drive the Coolify API or reach a box over SSH, from off the box. README now states that boundary so the next on-box script does not land here. Co-Authored-By: Claude Opus 4.8 --- README.md | 9 +++++++-- scripts/dump-coolify-db.sh | 12 ------------ 2 files changed, 7 insertions(+), 14 deletions(-) delete mode 100755 scripts/dump-coolify-db.sh diff --git a/README.md b/README.md index 35a9e97..fb7540d 100644 --- a/README.md +++ b/README.md @@ -123,8 +123,13 @@ manifest. A product-side change must not be able to lower its own guard. ## Scripts Operational helpers, all argument-driven (`scripts/`): register a GitHub App with -Coolify, dump the Coolify control-plane database age-encrypted to S3, restore a -database backup into a target container. +Coolify, restore a database backup into a target container. + +**They run where cast runs — off the box.** They drive the Coolify API, or reach a +box over SSH; none of them expects to be executing *on* a server. Anything that +belongs on a box, as root, under a scheduler is [rig](https://github.com/heavy-duty/rig)'s +job, not cast's — including the nightly age-encrypted dump of the control-plane +database, which is now `rig coolify backup install`. ## Development diff --git a/scripts/dump-coolify-db.sh b/scripts/dump-coolify-db.sh deleted file mode 100755 index 95512ca..0000000 --- a/scripts/dump-coolify-db.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -# Nightly on the coolify box: dump Coolify's own Postgres, age-encrypt -# client-side (dump holds GitHub App key, server SSH keys, all env values), -# ship to S3. Forensics only — a fresh instance is recreated, never restored. -set -euo pipefail -: "${AGE_RECIPIENT:?age public key for the backup identity}" -: "${S3_BUCKET:?s3 bucket, e.g. s3://my-backups/coolify-db}" -STAMP=$(date -u +%Y%m%dT%H%M%SZ) -OUT="/tmp/coolify-db-${STAMP}.sql.age" -docker exec coolify-db pg_dump -U coolify coolify | age -r "$AGE_RECIPIENT" -o "$OUT" -aws s3 cp "$OUT" "${S3_BUCKET}/" --endpoint-url "${S3_ENDPOINT:?hetzner s3 endpoint}" -rm -f "$OUT"