d32e4d487e
SLICE-05 (devops-engineer): firstboot-hook.sh — installs Docker inside CT (apt: docker.io, docker-compose-v2, git, curl), clones praxis repo from Gitea (GITEA_TOKEN baked into snippet per G-101 fix), runs install-service.sh SLICE-06 (devops-engineer): install-service.sh — creates praxis user, writes /etc/praxis/server.env from lxc.environment vars (G-103: all 16 env vars), installs praxis.service systemd unit (Type=simple, ExecStartPre=docker compose build, ExecStart=docker compose up, TimeoutStartSec=600 per RESEARCH Q8) SLICE-07 (devops-engineer): lxc-deploy.sh orchestrator — stage snippet → clone → config → start → health-check, idempotent (--recreate/--reconfigure), rollback on failure, auto VMID allocation (D-027) REQ-DEPLOY-06, 09, 10, 11 covered. ---ci--- project: praxis phase: 1 milestone: v0.2 status: execute slice: 05-07 wave: 3 ---/ci---
85 lines
2.8 KiB
Bash
Executable File
85 lines
2.8 KiB
Bash
Executable File
#!/bin/sh
|
|
# Praxis — Proxmox LXC first-boot hookscript.
|
|
#
|
|
# Adapted from coreci/scripts/proxmox/firstboot-hook.sh.
|
|
# Coreci fetches a pre-built Go binary + pct-pushes it; praxis installs
|
|
# Docker inside the CT, clones the repo from Gitea, builds the image,
|
|
# and starts the service via systemd (D-022, D-028, D-029).
|
|
#
|
|
# Referenced by lxc-config.sh via hookscript=local:snippets/praxis-firstboot.sh.
|
|
# Proxmox invokes this script at CT lifecycle phases on the PVE HOST
|
|
# (not inside the CT). The `post-start` phase does the work.
|
|
#
|
|
# G-101 FIX: GITEA_TOKEN is baked into this snippet by stage-snippet.sh
|
|
# (the hookscript runs on the PVE host where lxc.environment is invisible).
|
|
# The token is used to clone the private Gitea repo inside the CT.
|
|
#
|
|
# Proxmox passes: $1 = VMID, $2 = phase
|
|
# Environment (baked in by stage-snippet.sh):
|
|
# GITEA_TOKEN — bearer token for the private Gitea repo
|
|
# PRAXIS_VERSION — git ref (default: main)
|
|
# GITEA_HOST — Gitea hostname (default: git.cloudinit.dev)
|
|
|
|
set -eu
|
|
|
|
vmid="${1:-}"
|
|
phase="${2:-}"
|
|
|
|
log() { printf '[praxis-hook %s] %s\n' "$phase" "$*" >&2; }
|
|
|
|
case "$phase" in
|
|
post-start) : ;;
|
|
*) exit 0 ;;
|
|
esac
|
|
|
|
log "VMID=${vmid} — first-boot praxis install (Docker-in-LXC)"
|
|
|
|
VERSION="${PRAXIS_VERSION:-main}"
|
|
GITEA_HOST="${GITEA_HOST:-git.cloudinit.dev}"
|
|
GITEA_ORG="coreci"
|
|
GITEA_REPO="praxis"
|
|
CLONE_URL="https://${GITEA_TOKEN}@${GITEA_HOST}/${GITEA_ORG}/${GITEA_REPO}.git"
|
|
|
|
# Idempotency: skip if praxis is already installed and running.
|
|
if pct exec "$vmid" -- sh -c '[ -x /usr/local/bin/praxis-deploy ] && systemctl is-active --quiet praxis' 2>/dev/null; then
|
|
log "praxis already installed and active — skipping"
|
|
exit 0
|
|
fi
|
|
|
|
# Step 1: Install Docker + docker-compose-v2 inside the CT (D-028).
|
|
# Debian 12 standard template + nesting=1 supports Docker.
|
|
log "installing Docker inside CT ${vmid}"
|
|
pct exec "$vmid" -- sh -c '
|
|
set -e
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
apt-get update -qq
|
|
apt-get install -y -qq docker.io docker-compose-v2 git curl
|
|
systemctl enable --now docker
|
|
'
|
|
|
|
# Step 2: Clone the praxis repo inside the CT (D-029).
|
|
# Clone to /opt/praxis (persistent across container restarts).
|
|
log "cloning praxis repo (ref=${VERSION}) into CT"
|
|
pct exec "$vmid" -- sh -c "
|
|
set -e
|
|
mkdir -p /opt/praxis
|
|
cd /opt/praxis
|
|
git clone --depth 1 --branch '${VERSION}' '${CLONE_URL}' . 2>&1 || {
|
|
# If the specific branch doesn't exist, fall back to main
|
|
log 'falling back to main branch'
|
|
git clone --depth 1 '${CLONE_URL}' . 2>&1
|
|
}
|
|
"
|
|
|
|
# Step 3: Write the env file from lxc.environment (passed via the CT's env).
|
|
# The lxc.environment vars are available inside the CT's environment.
|
|
# install-service.sh writes /etc/praxis/server.env from these.
|
|
log "running install-service inside CT"
|
|
pct exec "$vmid" -- sh -c '
|
|
set -e
|
|
cd /opt/praxis
|
|
sh scripts/install-service.sh
|
|
'
|
|
|
|
log "praxis installed and started in CT ${vmid}"
|
|
exit 0 |