Initial commit: Busbar Designer
Web tool for designing nickel/copper busbars over cylindrical-cell battery packs (21700, 18650) in hex holders. Flask + build123d backend exports STEP/DXF/SVG; vanilla JS frontend with live preview, multi-project SQLite persistence, snapshot history. Deploy scripts in deploy/ (proxmox-lxc.sh, install.sh, update.sh).
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env bash
|
||||
# install.sh — install Busbar Designer on Debian / Ubuntu.
|
||||
#
|
||||
# Runs inside an LXC, VM, or bare-metal host. Idempotent (safe to re-run).
|
||||
#
|
||||
# Required env:
|
||||
# REPO_URL Git URL of the busbar-designer repo
|
||||
# (e.g. https://gitea.local/me/busbar-designer.git)
|
||||
#
|
||||
# Optional env:
|
||||
# BRANCH git branch to track (default: main)
|
||||
# INSTALL_DIR install location (default: /opt/busbar-designer)
|
||||
# SVC_USER systemd service user (default: busbar)
|
||||
# PORT HTTP port (default: 5000)
|
||||
# GIT_SSL_NO_VERIFY=1 skip TLS verify for self-signed Gitea certs
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
REPO_URL="${REPO_URL:-}"
|
||||
BRANCH="${BRANCH:-main}"
|
||||
INSTALL_DIR="${INSTALL_DIR:-/opt/busbar-designer}"
|
||||
SVC_USER="${SVC_USER:-busbar}"
|
||||
PORT="${PORT:-5000}"
|
||||
|
||||
# ---- helpers ---------------------------------------------------------------
|
||||
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m'
|
||||
log() { echo -e "${GREEN}▸${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}!${NC} $*"; }
|
||||
die() { echo -e "${RED}✗ $*${NC}" >&2; exit 1; }
|
||||
|
||||
[[ $EUID -eq 0 ]] || die "Run as root (or via sudo)."
|
||||
[[ -n "$REPO_URL" ]] || die "REPO_URL is required (export REPO_URL=https://gitea.local/me/busbar-designer.git)"
|
||||
|
||||
if [[ "${GIT_SSL_NO_VERIFY:-0}" == "1" ]]; then
|
||||
warn "GIT_SSL_NO_VERIFY=1 — skipping TLS verification for git."
|
||||
export GIT_SSL_NO_VERIFY=true
|
||||
fi
|
||||
|
||||
# ---- system packages -------------------------------------------------------
|
||||
log "Installing system packages..."
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq \
|
||||
git ca-certificates curl \
|
||||
python3 python3-venv python3-pip \
|
||||
libgl1 libglu1-mesa libxrender1 libxext6 libsm6 libgomp1
|
||||
|
||||
# ---- service user ----------------------------------------------------------
|
||||
if ! id "$SVC_USER" >/dev/null 2>&1; then
|
||||
log "Creating service user '$SVC_USER'..."
|
||||
useradd --system --create-home --shell /usr/sbin/nologin "$SVC_USER"
|
||||
else
|
||||
log "Service user '$SVC_USER' already exists."
|
||||
fi
|
||||
|
||||
# ---- source tree -----------------------------------------------------------
|
||||
mkdir -p "$(dirname "$INSTALL_DIR")"
|
||||
|
||||
if [[ -d "$INSTALL_DIR/.git" ]]; then
|
||||
log "Updating existing checkout at $INSTALL_DIR..."
|
||||
chown -R "$SVC_USER:$SVC_USER" "$INSTALL_DIR"
|
||||
sudo -u "$SVC_USER" git -C "$INSTALL_DIR" remote set-url origin "$REPO_URL"
|
||||
sudo -u "$SVC_USER" git -C "$INSTALL_DIR" fetch --depth 1 origin "$BRANCH"
|
||||
sudo -u "$SVC_USER" git -C "$INSTALL_DIR" reset --hard "origin/$BRANCH"
|
||||
else
|
||||
log "Cloning $REPO_URL (branch $BRANCH) into $INSTALL_DIR..."
|
||||
rm -rf "$INSTALL_DIR"
|
||||
git clone --depth 1 --branch "$BRANCH" "$REPO_URL" "$INSTALL_DIR"
|
||||
chown -R "$SVC_USER:$SVC_USER" "$INSTALL_DIR"
|
||||
fi
|
||||
|
||||
# ---- virtualenv + python deps ---------------------------------------------
|
||||
if [[ ! -x "$INSTALL_DIR/.venv/bin/python" ]]; then
|
||||
log "Creating Python venv..."
|
||||
sudo -u "$SVC_USER" python3 -m venv "$INSTALL_DIR/.venv"
|
||||
fi
|
||||
|
||||
log "Installing Python dependencies (build123d pulls OpenCASCADE — may take a few minutes)..."
|
||||
sudo -u "$SVC_USER" "$INSTALL_DIR/.venv/bin/pip" install --quiet --upgrade pip
|
||||
sudo -u "$SVC_USER" "$INSTALL_DIR/.venv/bin/pip" install --quiet \
|
||||
-r "$INSTALL_DIR/requirements.txt" gunicorn
|
||||
|
||||
# ---- data dir (for SQLite) -------------------------------------------------
|
||||
sudo -u "$SVC_USER" mkdir -p "$INSTALL_DIR/data"
|
||||
|
||||
# ---- systemd unit ----------------------------------------------------------
|
||||
log "Installing systemd unit..."
|
||||
UNIT_SRC="$INSTALL_DIR/deploy/busbar-designer.service"
|
||||
UNIT_DST="/etc/systemd/system/busbar-designer.service"
|
||||
[[ -f "$UNIT_SRC" ]] || die "deploy/busbar-designer.service missing in the repo."
|
||||
|
||||
# Substitute paths / user / port into the unit.
|
||||
sed -e "s|/opt/busbar-designer|$INSTALL_DIR|g" \
|
||||
-e "s|User=busbar|User=$SVC_USER|g" \
|
||||
-e "s|Group=busbar|Group=$SVC_USER|g" \
|
||||
-e "s|--bind=0.0.0.0:5000|--bind=0.0.0.0:$PORT|g" \
|
||||
-e "s|Environment=PORT=5000|Environment=PORT=$PORT|g" \
|
||||
"$UNIT_SRC" > "$UNIT_DST"
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now busbar-designer
|
||||
sleep 2
|
||||
|
||||
if ! systemctl is-active --quiet busbar-designer; then
|
||||
warn "Service is not active. Last 30 log lines:"
|
||||
journalctl -u busbar-designer -n 30 --no-pager
|
||||
die "Service failed to start."
|
||||
fi
|
||||
|
||||
IP_ADDR=$(hostname -I 2>/dev/null | awk '{print $1}')
|
||||
[[ -n "$IP_ADDR" ]] || IP_ADDR="$(hostname)"
|
||||
|
||||
echo
|
||||
log "================================================================"
|
||||
log " ✓ Busbar Designer installed."
|
||||
log ""
|
||||
log " URL: http://$IP_ADDR:$PORT"
|
||||
log " Logs: journalctl -u busbar-designer -f"
|
||||
log " Update: sudo bash $INSTALL_DIR/deploy/update.sh"
|
||||
log " Backup: cp $INSTALL_DIR/data/busbar.db ..."
|
||||
log "================================================================"
|
||||
Reference in New Issue
Block a user