The Coolify control-plane database holds the GitHub App private key, every registered server's SSH key, and every environment value for every environment it manages. Backing it up was a manual runbook step, and the dump script lived in cast — the off-box tool, whose src never references it. It runs on the box, as root, under a scheduler: that is rig's job description. It matters beyond tidiness. The dump is forensics, not a restore path — a lost control plane is rebuilt fresh and reconciled from the manifest. So there will be a next control-plane box, and as a runbook step it was born un-backed-up, depending on someone remembering mid-incident. Now it is backed up from birth. rig installs the machinery and templates /etc/coolify-dump.env empty at 0600, never reading it back — no credential passes through rig. The script's own guards make an unfilled file fail the unit loudly rather than ship plaintext. systemd timer over cron: EnvironmentFile is the right idiom for 0600 secrets, failures surface in systemctl status instead of being mailed into the void, and Persistent=true catches a run missed while the box was down. Two hazards the cast script missed, carried into the unit: - aws-cli >= 2.23 enables default upload checksums that S3-compatible backends reject; Debian 13 ships 2.23.6, so the unit defaults both checksum knobs to when_required. - A failed pg_dump piped into age still yields a valid, tiny, encrypted file that uploads cleanly every night and looks exactly like a working backup. The script now refuses to upload an empty artifact. Closes #8 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
43 lines
1.4 KiB
Bash
Executable file
43 lines
1.4 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# rig coolify install — pinned Coolify install; AUTOUPDATE=false so the
|
|
# platform never self-updates underneath its operators. Upgrades are an
|
|
# explicit act.
|
|
set -euo pipefail
|
|
|
|
log() { printf 'rig-coolify: %s\n' "$*"; }
|
|
die() { printf 'rig-coolify: ERROR: %s\n' "$1" >&2; exit "${2:-1}"; }
|
|
|
|
usage() {
|
|
cat <<'EOF'
|
|
usage: rig coolify install --version <pin>
|
|
|
|
Installs Coolify at exactly <pin> (e.g. 4.1.2) with AUTOUPDATE=false.
|
|
Control-plane box only. The version pin is required — you state the floor
|
|
your tooling is verified against; there is no default.
|
|
EOF
|
|
}
|
|
|
|
VERSION=""
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--version)
|
|
[ $# -ge 2 ] || die "--version needs a value" 2
|
|
VERSION="$2"; shift 2 ;;
|
|
-h|--help) usage; exit 0 ;;
|
|
*) die "unknown flag: $1" 2 ;;
|
|
esac
|
|
done
|
|
if [ -z "$VERSION" ]; then
|
|
usage >&2
|
|
die "--version <pin> is required" 2
|
|
fi
|
|
|
|
[ "$(id -u)" -eq 0 ] || die "must run as root"
|
|
|
|
export AUTOUPDATE=false
|
|
log "installing coolify ${VERSION} (AUTOUPDATE=false)"
|
|
curl -fsSL https://cdn.coollabs.io/coolify/install.sh -o /tmp/coolify-install.sh
|
|
bash /tmp/coolify-install.sh "$VERSION"
|
|
log "coolify ${VERSION} installed with AUTOUPDATE=false"
|
|
log "next: rig coolify backup install (nightly control-plane dump — do this before the box holds anything)"
|
|
log "then: your bootstrap runbook (admin user, API token, GitHub App, S3 destination)"
|