- setup_server.sh: full rewrite to match materia/template pattern — adds Docker install, git/curl/ca-certificates apt install, age + sops install (arch-aware), uv install as service user, age keypair generation, SSH config write (root+chown); removes systemd unit copy (was buggy: copied before repo was cloned) - NEW bootstrap_supervisor.sh: ~45 lines — age key check, clone/fetch, tag checkout, sops decrypt, uv sync, copy landing-backup + supervisor systemd units, enable + start - deploy.sh: replace 53-line self-install preamble (sops/age install + keypair generation + exit-1 flow) with simple sops check + decrypt; Docker blue/green logic unchanged Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
73 lines
3.4 KiB
Bash
73 lines
3.4 KiB
Bash
#!/bin/bash
|
|
# Bootstrap Padelnomics supervisor after setup_server.sh + adding keys.
|
|
# Run once on the server after SSH deploy key is added to GitLab
|
|
# and the server age key is committed to .env.prod.sops.
|
|
#
|
|
# Usage:
|
|
# ssh root@<server_ip> 'bash -s' < infra/bootstrap_supervisor.sh
|
|
#
|
|
# Prerequisites:
|
|
# - setup_server.sh already run (padelnomics_service user, SSH deploy key, age keypair, uv)
|
|
# - Deploy key added to GitLab (Settings → Repository → Deploy Keys)
|
|
# - Server age public key added to .sops.yaml + .env.prod.sops committed + pushed
|
|
|
|
set -euo pipefail
|
|
|
|
SERVICE_USER="padelnomics_service"
|
|
REPO_DIR="/opt/padelnomics"
|
|
GITLAB_PROJECT="deemanone/padelnomics"
|
|
UV="/home/${SERVICE_USER}/.local/bin/uv"
|
|
|
|
[ "$(id -u)" = "0" ] || { echo "ERROR: Run as root"; exit 1; }
|
|
|
|
# ── Check age keypair ─────────────────────────────────────────────────────────
|
|
|
|
AGE_KEY_FILE="/home/${SERVICE_USER}/.config/sops/age/keys.txt"
|
|
if [ ! -f "${AGE_KEY_FILE}" ]; then
|
|
echo "ERROR: Age keypair not found at ${AGE_KEY_FILE}"
|
|
echo "Run infra/setup_server.sh first, then add the printed keys, then re-run."
|
|
exit 1
|
|
fi
|
|
|
|
# ── Clone or update repository ────────────────────────────────────────────────
|
|
|
|
if [ -d "${REPO_DIR}/.git" ]; then
|
|
sudo -u "${SERVICE_USER}" git -C "${REPO_DIR}" fetch --tags --prune-tags origin
|
|
else
|
|
sudo -u "${SERVICE_USER}" git clone \
|
|
"git@gitlab.com:${GITLAB_PROJECT}.git" "${REPO_DIR}"
|
|
fi
|
|
|
|
LATEST_TAG=$(sudo -u "${SERVICE_USER}" \
|
|
git -C "${REPO_DIR}" tag --list --sort=-version:refname "v*" | head -1)
|
|
if [ -n "${LATEST_TAG}" ]; then
|
|
sudo -u "${SERVICE_USER}" git -C "${REPO_DIR}" checkout --detach "${LATEST_TAG}"
|
|
fi
|
|
|
|
# ── Decrypt secrets ───────────────────────────────────────────────────────────
|
|
|
|
sudo -u "${SERVICE_USER}" bash -c \
|
|
"sops --input-type dotenv --output-type dotenv -d ${REPO_DIR}/.env.prod.sops > ${REPO_DIR}/.env"
|
|
chmod 600 "${REPO_DIR}/.env"
|
|
|
|
# ── Python dependencies ───────────────────────────────────────────────────────
|
|
|
|
sudo -u "${SERVICE_USER}" bash -c "cd ${REPO_DIR} && ${UV} sync --all-packages"
|
|
|
|
# ── Systemd services ──────────────────────────────────────────────────────────
|
|
|
|
cp "${REPO_DIR}/infra/landing-backup/padelnomics-landing-backup.service" /etc/systemd/system/
|
|
cp "${REPO_DIR}/infra/landing-backup/padelnomics-landing-backup.timer" /etc/systemd/system/
|
|
cp "${REPO_DIR}/infra/supervisor/padelnomics-supervisor.service" /etc/systemd/system/
|
|
systemctl daemon-reload
|
|
systemctl enable --now padelnomics-landing-backup.timer
|
|
systemctl enable --now padelnomics-supervisor
|
|
|
|
echo ""
|
|
echo "=== Bootstrap complete! ==="
|
|
echo ""
|
|
echo "Check status: systemctl status padelnomics-supervisor"
|
|
echo "View logs: journalctl -u padelnomics-supervisor -f"
|
|
echo "Backup timer: systemctl list-timers padelnomics-landing-backup.timer"
|
|
echo "Tag: $(sudo -u "${SERVICE_USER}" git -C "${REPO_DIR}" describe --tags --always)"
|