feat: nexus LXC template — Host-Mode-Runner + Deploy-as-Code (Skeleton bis Stack-Entscheidung)
This commit is contained in:
+121
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env bash
|
||||
# nexus — Family Knowledge Hub deployed via a self-hosted Gitea Actions runner
|
||||
#
|
||||
# Creates an unprivileged Debian 12 LXC that:
|
||||
# - installs Node.js + a Gitea act_runner in HOST mode (no Docker, no inbound port)
|
||||
# - prepares /opt/nexus/current as the live copy and a (placeholder) nexus.service
|
||||
# - lets the repo's .gitea/workflows/ci.yml and deploy.yml build, test & deploy
|
||||
# on every push (deploy-as-code; the runner polls Gitea outbound)
|
||||
#
|
||||
# NOTE: The nexus tech stack is not yet decided (nexus-hub Project Brief, open
|
||||
# point 2). This template provisions the stable parts: runner, user, dirs,
|
||||
# sudoers, service skeleton. The stack-introducing SDD card extends the
|
||||
# RUNTIME section of install/nexus-install.sh and replaces the service unit.
|
||||
#
|
||||
# Run on a Proxmox VE host:
|
||||
# bash -c "$(curl -fsSL https://gitea.luki-net.org/luki-net/proxmox-scripts/raw/branch/main/ct/nexus.sh)"
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
APP="nexus"
|
||||
APP_DESCRIPTION="nexus (Family Knowledge Hub) deployed via a self-hosted Gitea Actions runner (deploy-as-code)"
|
||||
APP_PORT="${APP_PORT:-8080}"
|
||||
|
||||
LIB_URL="${LIB_URL:-https://gitea.luki-net.org/luki-net/proxmox-scripts/raw/branch/main/lib}"
|
||||
INSTALL_SCRIPT_URL="${INSTALL_SCRIPT_URL:-https://gitea.luki-net.org/luki-net/proxmox-scripts/raw/branch/main/install/nexus-install.sh}"
|
||||
|
||||
# LXC defaults (CI builds + future API/worker need headroom; DBs live elsewhere)
|
||||
DEFAULT_HOSTNAME="nexus"
|
||||
DEFAULT_DISK="40"
|
||||
DEFAULT_CORES="4"
|
||||
DEFAULT_RAM="8192"
|
||||
|
||||
# App / runner defaults (all overridable via env)
|
||||
DEFAULT_GITEA_INSTANCE_URL="https://gitea.luki-net.org"
|
||||
DEFAULT_REPO_URL="https://gitea.luki-net.org/l.kirchner/nexus-hub.git"
|
||||
DEFAULT_NODE_MAJOR="22"
|
||||
DEFAULT_RUNNER_VERSION="0.2.13"
|
||||
DEFAULT_RUNNER_LABELS="nexus:host"
|
||||
|
||||
source <(curl -fsSL "$LIB_URL/build.func")
|
||||
|
||||
# ── app-specific prompts (host TTY; each skipped if the var is preset) ───────
|
||||
prompt_app_config() {
|
||||
echo
|
||||
echo "── App / runner configuration ───────────────────────────────"
|
||||
if [[ -z "${GITEA_INSTANCE_URL:-}" ]]; then
|
||||
read -rp "Gitea instance URL [$DEFAULT_GITEA_INSTANCE_URL]: " GITEA_INSTANCE_URL
|
||||
GITEA_INSTANCE_URL="${GITEA_INSTANCE_URL:-$DEFAULT_GITEA_INSTANCE_URL}"
|
||||
fi
|
||||
# Repo → Settings → Actions → Runners → "Create new runner" gives this token.
|
||||
if [[ -z "${RUNNER_TOKEN:-}" ]]; then
|
||||
read -rsp "Gitea runner registration token: " RUNNER_TOKEN; echo
|
||||
fi
|
||||
[[ -n "${RUNNER_TOKEN:-}" ]] || { msg_err "RUNNER_TOKEN is required (Repo → Settings → Actions → Runners)"; exit 1; }
|
||||
if [[ -z "${REPO_URL:-}" ]]; then
|
||||
read -rp "nexus repo URL (informational) [$DEFAULT_REPO_URL]: " REPO_URL
|
||||
REPO_URL="${REPO_URL:-$DEFAULT_REPO_URL}"
|
||||
fi
|
||||
|
||||
NODE_MAJOR="${NODE_MAJOR:-$DEFAULT_NODE_MAJOR}"
|
||||
RUNNER_VERSION="${RUNNER_VERSION:-$DEFAULT_RUNNER_VERSION}"
|
||||
RUNNER_LABELS="${RUNNER_LABELS:-$DEFAULT_RUNNER_LABELS}"
|
||||
RUNNER_NAME="${RUNNER_NAME:-$CT_HOSTNAME}"
|
||||
|
||||
echo " → instance: $GITEA_INSTANCE_URL"
|
||||
echo " → runner: $RUNNER_NAME labels: $RUNNER_LABELS (act_runner $RUNNER_VERSION, host mode)"
|
||||
echo " → node: $NODE_MAJOR app port: $APP_PORT"
|
||||
}
|
||||
|
||||
# ── push gathered config into the container for the installer to consume ─────
|
||||
push_app_config() {
|
||||
msg_info "Pushing deploy config into container..."
|
||||
local tmpf; tmpf=$(mktemp)
|
||||
cat >"$tmpf" <<EOF
|
||||
GITEA_INSTANCE_URL='$GITEA_INSTANCE_URL'
|
||||
RUNNER_TOKEN='$RUNNER_TOKEN'
|
||||
RUNNER_NAME='$RUNNER_NAME'
|
||||
RUNNER_LABELS='$RUNNER_LABELS'
|
||||
RUNNER_VERSION='$RUNNER_VERSION'
|
||||
REPO_URL='$REPO_URL'
|
||||
APP_PORT='$APP_PORT'
|
||||
NODE_MAJOR='$NODE_MAJOR'
|
||||
EOF
|
||||
pct push "$CTID" "$tmpf" /root/nexus.deploy.env --perms 600
|
||||
rm -f "$tmpf"
|
||||
}
|
||||
|
||||
# ── trailing summary ──────────────────────────────────────────────────────────
|
||||
print_app_summary() {
|
||||
local runner_state
|
||||
runner_state=$(pct exec "$CTID" -- systemctl is-active nexus-runner.service 2>/dev/null | tr -d '\r\n')
|
||||
cat <<EOF
|
||||
nexus API: http://$IP_CT:$APP_PORT (live after the first deploy;
|
||||
service unit is a skeleton until the stack-introducing card lands)
|
||||
→ point your existing reverse proxy at this address when ready
|
||||
|
||||
Gitea Actions runner: $RUNNER_NAME [$RUNNER_LABELS] — $runner_state
|
||||
Instance: $GITEA_INSTANCE_URL
|
||||
Mode: host (no Docker, outbound poll — no inbound port)
|
||||
Verify: $GITEA_INSTANCE_URL → repo/Settings → Actions → Runners
|
||||
|
||||
Deploy-as-code — already in the nexus-hub repo:
|
||||
.gitea/workflows/ci.yml (runs-on: ${RUNNER_LABELS%%:*})
|
||||
.gitea/workflows/deploy.yml (runs-on: ${RUNNER_LABELS%%:*}, manual until stack lands)
|
||||
|
||||
Logs: pct exec $CTID -- journalctl -u nexus -u nexus-runner -f
|
||||
Notes file: /root/nexus.credentials (inside the LXC)
|
||||
EOF
|
||||
}
|
||||
|
||||
# ── orchestrate (custom: inject app config + standard bootstrap) ─────────────
|
||||
trap _on_error ERR
|
||||
preflight_pve
|
||||
show_header "$APP" "$APP_DESCRIPTION"
|
||||
prompt_lxc_config
|
||||
prompt_app_config
|
||||
resolve_debian_template
|
||||
create_lxc
|
||||
push_app_config
|
||||
bootstrap_install_script "$INSTALL_SCRIPT_URL"
|
||||
print_summary
|
||||
Reference in New Issue
Block a user