73e4fc005e
Server UI gains Update on stack cards, ComfyUI Models tab with workflow scan and downloads, and centralized comfyui_config. Model catalog and download scripts move from stacks/comfyui to server-ui so ComfyUI stays a minimal Docker wrapper for easier image updates.
92 lines
2.9 KiB
Bash
Executable File
92 lines
2.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
STACK_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
|
INSTALL_DIR="/opt/server-ui"
|
|
SERVICE_NAME="server-ui.service"
|
|
UI_PORT=8091
|
|
CONTROL_PLANE_ENV="/opt/control-plane/.env"
|
|
|
|
if [[ "${EUID}" -ne 0 ]]; then
|
|
echo "Run as root: sudo ${SCRIPT_DIR}/install.sh"
|
|
exit 1
|
|
fi
|
|
|
|
free_ui_port() {
|
|
pkill -f "stacks/server-ui/.venv/bin/python app.py" 2>/dev/null || true
|
|
pkill -f "SERVER_UI_PORT=18091" 2>/dev/null || true
|
|
local pids
|
|
pids="$(ss -tlnp "sport = :${UI_PORT}" 2>/dev/null | grep -oP 'pid=\K[0-9]+' | sort -u || true)"
|
|
for pid in ${pids}; do
|
|
local cmd
|
|
cmd="$(ps -p "${pid}" -o cmd= 2>/dev/null || true)"
|
|
if [[ "${cmd}" == *"stacks/server-ui"* ]]; then
|
|
echo "Stopping stale dev server-ui on :${UI_PORT} (pid ${pid})"
|
|
kill "${pid}" 2>/dev/null || true
|
|
fi
|
|
done
|
|
sleep 1
|
|
}
|
|
|
|
# Disable Docker deployment if switching to native
|
|
if [[ -f "${STACK_DIR}/docker-compose.yml" ]]; then
|
|
(cd "${STACK_DIR}" && docker compose --profile server-ui down 2>/dev/null) || true
|
|
fi
|
|
|
|
echo "=== Server UI — install (native / systemd) ==="
|
|
|
|
bash "${SCRIPT_DIR}/setup-control-plane-env.sh"
|
|
|
|
apt-get update -qq
|
|
apt-get install -y python3-venv python3-pip
|
|
|
|
mkdir -p "${INSTALL_DIR}"
|
|
|
|
rsync -a --delete \
|
|
--exclude '.venv' \
|
|
--exclude '.env' \
|
|
--exclude '__pycache__' \
|
|
"${STACK_DIR}/" "${INSTALL_DIR}/"
|
|
|
|
install -m 644 "$(dirname "${STACK_DIR}")/control-plane/env_loader.py" "${INSTALL_DIR}/env_loader.py"
|
|
|
|
python3 -m venv "${INSTALL_DIR}/.venv"
|
|
"${INSTALL_DIR}/.venv/bin/pip" install --upgrade pip -q
|
|
"${INSTALL_DIR}/.venv/bin/pip" install -r "${INSTALL_DIR}/requirements.txt" -q
|
|
|
|
install -m 644 "${INSTALL_DIR}/server-ui.service" "/etc/systemd/system/${SERVICE_NAME}"
|
|
systemctl daemon-reload
|
|
systemctl enable "${SERVICE_NAME}"
|
|
|
|
free_ui_port
|
|
systemctl restart "${SERVICE_NAME}"
|
|
sleep 2
|
|
|
|
LAN_IP="$(hostname -I 2>/dev/null | awk '{print $1}')"
|
|
API_KEY_VAL="$(grep '^API_KEY=' "${CONTROL_PLANE_ENV}" | cut -d= -f2- || true)"
|
|
|
|
echo ""
|
|
echo "Installed to ${INSTALL_DIR}"
|
|
echo "Service: $(systemctl is-active "${SERVICE_NAME}" 2>/dev/null || echo unknown)"
|
|
echo "Env: ${CONTROL_PLANE_ENV}"
|
|
|
|
# shellcheck source=print-api-key-instructions.sh
|
|
source "${SCRIPT_DIR}/print-api-key-instructions.sh"
|
|
print_api_key_instructions "${CONTROL_PLANE_ENV}" "${UI_PORT}"
|
|
|
|
if [[ -n "${API_KEY_VAL}" ]]; then
|
|
HEALTH="$(curl -sf "http://127.0.0.1:${UI_PORT}/api/gpu-fan/health" -H "X-API-Key: ${API_KEY_VAL}" 2>/dev/null || echo '{"ok":false}')"
|
|
echo "GPU Fan proxy health: ${HEALTH}"
|
|
if ! echo "${HEALTH}" | grep -q '"ok":true'; then
|
|
echo "WARN: gpu-fan agent may be down — run: sudo ${STACK_DIR%/server-ui}/gpu-fan/scripts/install.sh"
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
echo "Logs:"
|
|
echo " journalctl -u ${SERVICE_NAME} -f"
|
|
echo ""
|
|
echo "Unified installer (gpu-fan + server-ui):"
|
|
echo " sudo ${SCRIPT_DIR}/install-control-plane.sh"
|