diff --git a/README.md b/README.md index 73b453d..ce02490 100644 --- a/README.md +++ b/README.md @@ -142,26 +142,24 @@ busbar-designer/ ## Deploy to a home server -Three supported paths — pick one. Full docs in [`deploy/README.md`](deploy/README.md). +### Recommended: manual LXC + `install.sh` -### Option A — Proxmox VE (one-liner from the PVE host) +1. **Create LXC in Proxmox web UI** — Debian 12 standard template, unprivileged, 4 cores / 8 GB RAM / 32 GB disk, network DHCP. Enable `Features → nesting=1`. +2. **Inside the LXC** (`pct enter ` from the host): + ```bash + REPO_URL=https://gitea.example.com/me/busbar-designer.git \ + bash -c "$(curl -fsSL https://gitea.example.com/me/busbar-designer/raw/branch/main/deploy/install.sh)" + ``` +3. Open `http://:5000` from any device on your LAN. +Update after `git push` to your Gitea: ```bash -bash -c "$(curl -fsSL https://gitea.local/me/busbar-designer/raw/branch/main/deploy/proxmox-lxc.sh)" +pct exec -- bash /opt/busbar-designer/deploy/update.sh ``` -Creates a Debian 12 LXC and installs the service inside. Whiptail prompts for container ID, hostname, disk/CPU/RAM, network, repo URL, branch. Defaults to 4 GB disk, 2 cores, 1 GB RAM, dhcp. +See [`deploy/README.md`](deploy/README.md) for backup/restore, troubleshooting, and what `install.sh` actually installs. -### Option B — Inside an existing Debian/Ubuntu (LXC, VM, bare) - -```bash -REPO_URL=https://gitea.local/me/busbar-designer.git \ -bash -c "$(curl -fsSL https://gitea.local/me/busbar-designer/raw/branch/main/deploy/install.sh)" -``` - -Sets up the venv, installs deps, drops a systemd unit, starts the service. Update with `bash /opt/busbar-designer/deploy/update.sh`. - -### Option C — Docker +### Alternative: Docker ```bash git clone busbar-designer && cd busbar-designer @@ -169,7 +167,7 @@ mkdir -p data docker compose up -d --build ``` -The `data/` folder is mounted into the container at `/app/data` so the SQLite DB survives `docker compose down`. +`data/` is bind-mounted at `/app/data` so the SQLite DB survives `docker compose down`. ### Reverse proxy (optional) diff --git a/deploy/README.md b/deploy/README.md index 4364e07..e58f945 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -1,111 +1,65 @@ # Deploy -Three scripts here, plus the systemd unit. +Two scripts here, plus the systemd unit. | File | Where it runs | What it does | |-------------------------------|--------------------------------|---------------------------------------------------------------------------| -| `proxmox-lxc.sh` | **Proxmox VE host** as root | Creates an unprivileged Debian 12 LXC, then runs `install.sh` inside it. | -| `install.sh` | **inside** an LXC/VM/server | Clones the repo, sets up Python venv, installs deps, starts systemd unit. | -| `update.sh` | **inside** the LXC/VM/server | `git pull` + refresh Python deps + `systemctl restart`. | +| `install.sh` | inside a Debian/Ubuntu host | Clones the repo, sets up Python venv, installs deps, starts systemd unit. | +| `update.sh` | inside the LXC/VM/server | `git pull` + refresh Python deps + `systemctl restart`. | | `busbar-designer.service` | systemd | Unit file template; install.sh substitutes paths/user/port. | -All scripts are idempotent (safe to re-run) and use only stdlib + Debian-shipped tools (`pct`, `pveam`, `whiptail`, `git`, `python3`). No external dependencies. +Both scripts are idempotent (safe to re-run) and use only stdlib + Debian-shipped tools. + +> Want to create the LXC and provision it in one go? See the manual walk-through in the main `README.md` (Quick start / Deploy section). The earlier `proxmox-lxc.sh` whiptail helper was removed — the Proxmox web UI + this `install.sh` are simpler and easier to debug. --- -## Step 0 — push to your Gitea (one time) +## Push to your Gitea (one time) ```bash -# on your laptop, in this repo -git remote add gitea https://gitea.local/me/busbar-designer.git +git remote add gitea https://gitea.example.com/me/busbar-designer.git git push gitea main ``` -If your Gitea uses a self-signed cert, set `GIT_SSL_NO_VERIFY=1` everywhere (or install the cert into the system trust store). +If your Gitea uses a self-signed cert, set `GIT_SSL_NO_VERIFY=1` (or install the CA into the system trust store). --- -## Path A — Proxmox VE host (recommended) - -One-liner from the Proxmox shell: +## Inside a Debian / Ubuntu host (LXC, VM, bare) ```bash -bash -c "$(curl -fsSL https://gitea.local/me/busbar-designer/raw/branch/main/deploy/proxmox-lxc.sh)" +REPO_URL=https://gitea.example.com/me/busbar-designer.git \ +bash -c "$(curl -fsSL https://gitea.example.com/me/busbar-designer/raw/branch/main/deploy/install.sh)" ``` -(Substitute `https://gitea.local/me/busbar-designer/raw/branch/main/deploy/proxmox-lxc.sh` with your repo's raw URL. Gitea's raw URL format is `https://///raw/branch//`.) +Defaults: `/opt/busbar-designer`, user `busbar`, port `5000`. Override with `INSTALL_DIR`, `SVC_USER`, `PORT`. -You'll get whiptail prompts for: - -- Container ID (defaults to next available) -- Hostname (`busbar-designer`) -- Disk size (4 GB), cores (2), RAM (1024 MB) -- Storage pool, network bridge, IP (`dhcp` or `1.2.3.4/24,gw=1.2.3.1`) -- Repo URL & branch -- Skip TLS verify? (yes if your Gitea uses self-signed certs) - -The script will: - -1. Download Debian 12 template if missing. -2. Create the LXC, start it. -3. Inside the LXC: clone the repo, install everything, enable systemd. -4. Print the URL + root password + management commands. - -To skip prompts (CI / scripted re-deploys): - -```bash -CTID=210 HOSTNAME=busbar DISK_SIZE=4 CORES=2 RAM=1024 \ -BRIDGE=vmbr0 IP=dhcp STORAGE=local-lvm \ -REPO_URL=https://gitea.local/me/busbar-designer.git BRANCH=main \ -bash deploy/proxmox-lxc.sh -``` +What it installs: +- Debian packages: `git python3 python3-venv libgl1 libglu1-mesa libxrender1 libxext6 libsm6 libgomp1 openscad xvfb` +- Python venv with `build123d`, `Flask`, `ezdxf`, `gunicorn` +- systemd unit (substituted with your paths/user/port) --- -## Path B — inside an existing LXC / VM / bare server - -Already have a Debian 12 / Ubuntu 22.04 / 24.04 host? Just run the installer: - -```bash -REPO_URL=https://gitea.local/me/busbar-designer.git \ -bash -c "$(curl -fsSL https://gitea.local/me/busbar-designer/raw/branch/main/deploy/install.sh)" -``` - -Defaults to `/opt/busbar-designer`, user `busbar`, port `5000`. Override with `INSTALL_DIR`, `SVC_USER`, `PORT`. - ---- - -## Updating +## Updating after `git push` From the Proxmox host: - ```bash pct exec 210 -- bash /opt/busbar-designer/deploy/update.sh ``` -From inside the LXC: - +Or SSH in and: ```bash sudo bash /opt/busbar-designer/deploy/update.sh ``` -The updater does `git fetch + reset --hard` on the tracked branch, refreshes Python deps, restarts the service. - -### Optional: auto-deploy via Gitea webhook - -In your Gitea repo → **Settings → Webhooks → Add Webhook (Gitea)**: - -- URL: `http://:5050/hook` (you'd need to add a tiny webhook listener; not built-in) -- Trigger: `Push` -- Branch filter: `main` - -Out of the box there's no webhook endpoint — the simplest path is a cron `*/5 * * * * root bash /opt/busbar-designer/deploy/update.sh` if you want polling, or just SSH and re-run `update.sh` after each push. +Does `git fetch + reset --hard` on the tracked branch, refreshes Python deps, restarts the service. --- ## Backup & restore -Everything user-generated lives in `/opt/busbar-designer/data/busbar.db` (SQLite, single file). +All user data lives in `/opt/busbar-designer/data/busbar.db` (SQLite, single file). ```bash # Backup (from Proxmox host) @@ -116,7 +70,7 @@ cat busbar-backup-2026-05-24.db | pct exec 210 -- bash -c \ 'systemctl stop busbar-designer && cat > /opt/busbar-designer/data/busbar.db && chown busbar:busbar /opt/busbar-designer/data/busbar.db && systemctl start busbar-designer' ``` -Or via Proxmox's own LXC backup (`vzdump`) which captures the whole rootfs. +Or use Proxmox's own LXC backup (`vzdump`) which captures the whole rootfs (slower, captures everything). --- @@ -124,8 +78,8 @@ Or via Proxmox's own LXC backup (`vzdump`) which captures the whole rootfs. | Symptom | Fix | |--------------------------------------------------|---------------------------------------------------------------------------------------| -| `pveversion: command not found` | The Proxmox script is not running on a PVE host. Use `install.sh` directly inside the LXC. | -| Git clone fails with TLS error | Set `GIT_SSL_NO_VERIFY=1` env var, or install your Gitea CA cert into `/usr/local/share/ca-certificates`. | -| Service starts, then dies | `pct exec -- journalctl -u busbar-designer -n 100`. Usually the build123d wheel didn't install — Debian 12 ships Python 3.11 which is fine. | -| Browser shows 502 / can't connect | Check the LXC's IP with `pct exec -- ip a`. If using DHCP, the IP may have changed. | -| `pveam download` fails | Run `pveam update` on the host first. | +| Git clone fails with TLS error | Set `GIT_SSL_NO_VERIFY=1`, or install your Gitea CA cert into `/usr/local/share/ca-certificates`. | +| Service starts then dies | `journalctl -u busbar-designer -n 100`. Usually OCP wheel didn't install — check Python version. | +| `/api/holder/render` returns 500 | `which openscad`. If missing: `apt install -y openscad`. | +| Browser shows 502 / can't connect | Check IP with `hostname -I`. If DHCP, the IP may have changed. | +| Port 5000 already in use | Edit systemd unit: `Environment=PORT=5050` and `ExecStart=...--bind=0.0.0.0:5050`. | diff --git a/deploy/proxmox-lxc.sh b/deploy/proxmox-lxc.sh deleted file mode 100644 index 5d4e39f..0000000 --- a/deploy/proxmox-lxc.sh +++ /dev/null @@ -1,195 +0,0 @@ -#!/usr/bin/env bash -# proxmox-lxc.sh — create an unprivileged Debian 12 LXC on a Proxmox VE host -# and install Busbar Designer into it. Inspired by the community-scripts style. -# -# Run on the Proxmox host as root, e.g.: -# -# bash -c "$(curl -fsSL https://gitea.local/me/busbar-designer/raw/branch/main/deploy/proxmox-lxc.sh)" -# -# Interactive whiptail prompts; or pre-set everything via env to skip prompts: -# -# REPO_URL=https://gitea.local/me/busbar-designer.git \ -# CTID=210 HOSTNAME=busbar DISK_SIZE=4 CORES=2 RAM=1024 \ -# BRIDGE=vmbr0 IP=dhcp STORAGE=local-lvm \ -# bash proxmox-lxc.sh - -set -euo pipefail - -# ---- colors ---------------------------------------------------------------- -GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m' -BLUE='\033[0;34m'; BOLD='\033[1m'; NC='\033[0m' -log() { echo -e "${GREEN}▸${NC} $*"; } -warn() { echo -e "${YELLOW}!${NC} $*"; } -die() { echo -e "${RED}✗ $*${NC}" >&2; exit 1; } - -banner() { - cat <<'EOF' - - ____ _ ____ _ - | __ ) _ _ ___| |__ __ _ _ __ | _ \ ___ ___(_) __ _ _ __ ___ _ __ - | _ \| | | / __| '_ \ / _` | '__| | | | |/ _ \/ __| |/ _` | '_ \ / _ \ '__| - | |_) | |_| \__ \ |_) | (_| | | | |_| | __/\__ \ | (_| | | | | __/ | - |____/ \__,_|___/_.__/ \__,_|_| |____/ \___||___/_|\__, |_| |_|\___|_| - |___/ - Proxmox VE LXC installer - -EOF -} - -# ---- preflight ------------------------------------------------------------- -[[ $EUID -eq 0 ]] || die "Run as root on the Proxmox host." -command -v pveversion >/dev/null 2>&1 || die "pveversion not found — is this a Proxmox VE host?" -command -v pct >/dev/null 2>&1 || die "pct not found — Proxmox VE tools missing?" - -banner - -# ---- defaults -------------------------------------------------------------- -CTID_DEFAULT=$(pvesh get /cluster/nextid 2>/dev/null || echo "200") -CTID="${CTID:-$CTID_DEFAULT}" -HOSTNAME="${HOSTNAME:-busbar-designer}" -DISK_SIZE="${DISK_SIZE:-4}" -CORES="${CORES:-2}" -RAM="${RAM:-1024}" -SWAP="${SWAP:-512}" -BRIDGE="${BRIDGE:-vmbr0}" -IP="${IP:-dhcp}" -STORAGE="${STORAGE:-local-lvm}" -TEMPLATE_STORAGE="${TEMPLATE_STORAGE:-local}" -REPO_URL="${REPO_URL:-}" -BRANCH="${BRANCH:-main}" -GIT_SSL_NO_VERIFY="${GIT_SSL_NO_VERIFY:-0}" - -# ---- interactive prompts (whiptail) ---------------------------------------- -ask() { - local var="$1" prompt="$2" default="$3" h="${4:-8}" w="${5:-60}" - local val - if [[ -t 0 ]] && command -v whiptail >/dev/null 2>&1; then - val=$(whiptail --title "Busbar Designer" --inputbox "$prompt" "$h" "$w" "$default" \ - 3>&1 1>&2 2>&3) || die "Cancelled." - else - read -rp "$prompt [$default]: " val - val="${val:-$default}" - fi - printf -v "$var" '%s' "$val" -} - -yesno() { - local prompt="$1" default="${2:-no}" - if [[ -t 0 ]] && command -v whiptail >/dev/null 2>&1; then - if [[ "$default" == "yes" ]]; then - whiptail --title "Busbar Designer" --yesno "$prompt" 8 60 - else - whiptail --title "Busbar Designer" --yesno "$prompt" --defaultno 8 60 - fi - else - read -rp "$prompt [$default]: " val - [[ "${val:-$default}" =~ ^(y|yes)$ ]] - fi -} - -if [[ -z "$REPO_URL" ]] || [[ -t 0 ]]; then - ask CTID "Container ID" "$CTID" - ask HOSTNAME "Hostname" "$HOSTNAME" - ask DISK_SIZE "Root disk size (GB)" "$DISK_SIZE" - ask CORES "CPU cores" "$CORES" - ask RAM "RAM (MB)" "$RAM" - ask STORAGE "Storage pool for rootfs (e.g. local-lvm, local-zfs)" "$STORAGE" 8 70 - ask BRIDGE "Network bridge" "$BRIDGE" - ask IP "IP config: 'dhcp' or 'a.b.c.d/24,gw=a.b.c.1'" "$IP" 8 70 - ask REPO_URL "Git URL of busbar-designer repo (your Gitea / GitHub)" \ - "${REPO_URL:-https://gitea.local/me/busbar-designer.git}" 10 70 - ask BRANCH "Branch" "$BRANCH" - if yesno "Skip TLS verification for git? (only if your Gitea uses a self-signed cert)"; then - GIT_SSL_NO_VERIFY=1 - fi -fi - -[[ -n "$REPO_URL" ]] || die "REPO_URL is required." - -# ---- template -------------------------------------------------------------- -log "Looking for a Debian 12 template..." -TEMPLATE=$(pveam available --section system 2>/dev/null \ - | awk '/debian-12-standard/ {print $2}' | sort -r | head -n 1) -[[ -n "$TEMPLATE" ]] || die "Couldn't find debian-12-standard in 'pveam available'. Run 'pveam update' first." - -LOCAL_TEMPLATE="/var/lib/vz/template/cache/$TEMPLATE" -if [[ ! -f "$LOCAL_TEMPLATE" ]]; then - log "Downloading template $TEMPLATE..." - pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" -fi - -# ---- create LXC ------------------------------------------------------------ -if pct status "$CTID" >/dev/null 2>&1; then - die "Container $CTID already exists. Pick a different CTID." -fi - -PASSWORD="$(openssl rand -base64 12 | tr -d '/+=' | cut -c1-16)" - -if [[ "$IP" == "dhcp" ]]; then - NET="name=eth0,bridge=$BRIDGE,ip=dhcp" -else - NET="name=eth0,bridge=$BRIDGE,ip=$IP" -fi - -log "Creating LXC $CTID ($HOSTNAME)..." -pct create "$CTID" "$TEMPLATE_STORAGE:vztmpl/$TEMPLATE" \ - --hostname "$HOSTNAME" \ - --cores "$CORES" \ - --memory "$RAM" \ - --swap "$SWAP" \ - --rootfs "$STORAGE:$DISK_SIZE" \ - --net0 "$NET" \ - --password "$PASSWORD" \ - --features nesting=1 \ - --unprivileged 1 \ - --onboot 1 \ - --start 1 \ - --description "Busbar Designer · $REPO_URL ($BRANCH)" >/dev/null - -# ---- wait for network ------------------------------------------------------ -log "Waiting for network in CT $CTID..." -for i in {1..30}; do - if pct exec "$CTID" -- bash -c "getent hosts deb.debian.org >/dev/null" 2>/dev/null; then - break - fi - sleep 2 -done - -# ---- run installer inside the LXC ------------------------------------------ -log "Bootstrapping git + curl in the container..." -pct exec "$CTID" -- bash -c " - set -e - export DEBIAN_FRONTEND=noninteractive - apt-get update -qq - apt-get install -y -qq git ca-certificates curl -" || die "Failed to install bootstrap packages in CT." - -log "Cloning repo and running deploy/install.sh inside CT $CTID..." -pct exec "$CTID" -- bash -c " - set -e - ${GIT_SSL_NO_VERIFY:+export GIT_SSL_NO_VERIFY=true} - rm -rf /opt/busbar-designer - git clone --depth 1 -b '$BRANCH' '$REPO_URL' /opt/busbar-designer - REPO_URL='$REPO_URL' BRANCH='$BRANCH' \ - ${GIT_SSL_NO_VERIFY:+GIT_SSL_NO_VERIFY=1} \ - bash /opt/busbar-designer/deploy/install.sh -" || die "Installer failed. Inspect with: pct enter $CTID" - -# ---- report --------------------------------------------------------------- -IP_ADDR=$(pct exec "$CTID" -- bash -c "hostname -I | awk '{print \$1}'" 2>/dev/null || true) -[[ -n "$IP_ADDR" ]] || IP_ADDR="" - -echo -log "================================================================" -log " ${BOLD}✓ Busbar Designer LXC ready${NC}" -log "" -log " Container ID: $CTID" -log " Hostname: $HOSTNAME" -log " Root password: $PASSWORD" -log " URL: http://$IP_ADDR:5000" -log "" -log " Update: pct exec $CTID -- bash /opt/busbar-designer/deploy/update.sh" -log " Logs: pct exec $CTID -- journalctl -u busbar-designer -f" -log " Enter: pct enter $CTID" -log " Backup: pct exec $CTID -- cat /opt/busbar-designer/data/busbar.db > backup.db" -log "================================================================"