Files
kgva/deploy/provision-lxc.sh
T
karim 51a94b85d3 cms: add openbureau-core CMS (DB-less, auth: local) — vendored at cms/core
kgva can now be edited through openbureau-core instead of Decap: a small Node CMS
(git subtree at cms/core) with a schema-driven editor at /admin, file-based login
(no Supabase/Postgres), Markdown on disk. cms/kgva.config.js models the content
(portfolio/pages/sections); docker-compose builds the core image (Hugo 0.163.3,
no VITE_SUPABASE_URL → local-auth admin) and mounts the repo as the site. seed an
admin via cms/seed-admin.mjs; deploy/provision-lxc.sh + ADMIN.md updated.

Verified DB-less end-to-end on real content (staged): local login → schema-driven
editor → 42 entries (de/en) → stats → create/preview/cleanup; unknown frontmatter
(image galleries) preserved on save. The LIVE static site (CT130 timer→hugo→nginx)
is unaffected — hugo ignores cms/; the CMS is dormant until provisioned.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 01:52:49 +02:00

61 lines
2.8 KiB
Bash
Executable File

#!/usr/bin/env bash
# Provision an LXC for the kgva website (Docker + compose). RUN ON THE PROXMOX NODE.
#
# SAFE CUTOVER (recommended): create this NEW container on a FREE/temporary IP,
# test it, then point Caddy's upstream at it. Remove the OLD container only after
# the new one is verified. Do NOT reuse the old IP up front (IP conflict + no
# rollback). Override any value via env, e.g.: CTID=141 IP=10.0.0.50/24 ./provision-lxc.sh
set -euo pipefail
CTID="${CTID:-141}" # must be free: pct status $CTID → should error
HOSTNAME_="${HOSTNAME_:-kgva}"
IP="${IP:-CHANGE_ME/24}" # NEW/temporary ip, NOT the old one yet
GW="${GW:-CHANGE_ME}"
BRIDGE="${BRIDGE:-vmbr0}"
STORAGE="${STORAGE:-local-lvm}"
TEMPLATE="${TEMPLATE:-local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst}"
REPO="${REPO:-https://git.kgva.ch/karim/kgva.git}"
DISK="${DISK:-6}"; CORES="${CORES:-2}"; RAM="${RAM:-1024}"
echo "Creating LXC $CTID ($HOSTNAME_) on $IP ..."
pct create "$CTID" "$TEMPLATE" \
--hostname "$HOSTNAME_" --cores "$CORES" --memory "$RAM" \
--rootfs "${STORAGE}:${DISK}" \
--net0 "name=eth0,bridge=${BRIDGE},ip=${IP},gw=${GW}" \
--features nesting=1 --unprivileged 1 --onboot 1
pct start "$CTID"
sleep 6
pct exec "$CTID" -- bash -lc '
set -e
export DEBIAN_FRONTEND=noninteractive
apt-get update && apt-get install -y ca-certificates curl git
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian $(. /etc/os-release; echo $VERSION_CODENAME) stable" \
> /etc/apt/sources.list.d/docker.list
apt-get update && apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
rm -rf /opt/kgva && git clone '"$REPO"' /opt/kgva
cd /opt/kgva
# DB-less CMS env: random token secret (once).
[ -f cms/.env ] || sed "s#CHANGE_ME#$(openssl rand -hex 32)#" cms/.env.example > cms/.env
# the CMS runs as uid 1000 and must write content/ + build public/.
chown -R 1000:1000 /opt/kgva
docker compose build
# seed an admin on first provision; password saved to cms/ADMIN_PASSWORD.txt.
if [ ! -f cms/users.json ]; then
PW="$(openssl rand -base64 12)"
docker compose run --rm -T cms node /site/cms/seed-admin.mjs karim@gabrielevarano.ch "$PW"
printf "%s\n" "$PW" > cms/ADMIN_PASSWORD.txt
chown 1000:1000 cms/ADMIN_PASSWORD.txt cms/users.json
fi
docker compose up -d
'
echo
echo "done. CMS admin at http://${IP%/*}:8080/admin/ (login: karim@… / cms/ADMIN_PASSWORD.txt)"
echo "test: curl -I http://${IP%/*}:8080"
echo "then point Caddy at ${IP%/*}:8080 (see deploy/Caddyfile), reload caddy,"
echo "verify the domain, and only THEN remove the old container."