From 5fda27794d16c3de079e5a703b4e0c93fa93c3fb Mon Sep 17 00:00:00 2001 From: Keith Solomon Date: Mon, 20 Jul 2026 20:37:02 -0500 Subject: [PATCH] feat: add Proxmox LXC deployment files - Add deploy/proxmox-lxc-setup.sh to configure the frontend inside a Debian/Ubuntu LXC. - Add deploy/thermopro-frontend.service systemd unit. - Add deploy/README.md with Proxmox CT creation, file transfer, setup, proxy, and update steps. - Update frontend README.md to point to the deployment guide. --- frontend/README.md | 10 +- frontend/deploy/README.md | 136 +++++++++++++++++++++ frontend/deploy/proxmox-lxc-setup.sh | 64 ++++++++++ frontend/deploy/thermopro-frontend.service | 20 +++ 4 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 frontend/deploy/README.md create mode 100644 frontend/deploy/proxmox-lxc-setup.sh create mode 100644 frontend/deploy/thermopro-frontend.service diff --git a/frontend/README.md b/frontend/README.md index 88f85dc..2b7dffb 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -66,4 +66,12 @@ Then open `http://localhost:5000`. ## Deployment -Serve the app behind a reverse proxy (e.g. Caddy or Nginx) in an LXC. The backend continues polling the CYD as long as it can reach the device. +See `deploy/README.md` for step-by-step Proxmox LXC deployment instructions. + +For a quick local test: + +```bash +cd frontend +pip install --target vendor -r requirements.txt +CYD_BASE_URL=http://192.168.2.55 python app.py +``` diff --git a/frontend/deploy/README.md b/frontend/deploy/README.md new file mode 100644 index 0000000..c78fec6 --- /dev/null +++ b/frontend/deploy/README.md @@ -0,0 +1,136 @@ +# Deploying the Frontend to a Proxmox LXC Container + +This folder contains everything you need to run the ThermoPro CYD frontend inside an unprivileged Proxmox LXC container. + +## Overview + +1. Create a Debian 12 (or Ubuntu 22.04/24.04) LXC container in Proxmox. +2. Copy the `frontend/` directory into the container. +3. Run `deploy/proxmox-lxc-setup.sh` inside the container. +4. The container starts the Flask/Waitress app as a systemd service on port 5000. +5. Put the container behind a reverse proxy (Caddy/Nginx) for HTTPS and a friendly URL. + +## Container specs (suggested) + +- **OS template:** Debian 12 Standard (or Ubuntu 22.04/24.04 Standard) +- **Cores:** 1 +- **Memory:** 512 MB +- **Root disk:** 4 GB +- **Network:** DHCP or static IP on your LAN + +## One-time setup + +### 1. Create the LXC + +In the Proxmox web UI: + +- Click **Create CT**. +- Choose a Debian 12 template (download from the UI if needed). +- Set hostname, password/SSH key, storage, network, etc. +- Finish and start the container. + +Or via the Proxmox shell: + +```bash +pct create 300 local:vztmpl/debian-12-standard_12.x-amd64.tar.zst \ + --hostname thermopro-frontend \ + --cores 1 \ + --memory 512 \ + --swap 0 \ + --rootfs local-lvm:4 \ + --net0 name=eth0,bridge=vmbr0,ip=dhcp \ + --ostype debian \ + --unprivileged 1 +pct start 300 +``` + +### 2. Copy the frontend into the container + +From your development machine or the Proxmox host: + +```bash +# From the repo root +cd /path/to/ThermoPro-CYD +tar -czf /tmp/frontend.tar.gz frontend/ + +# Push it into the container +pct push 300 /tmp/frontend.tar.gz /tmp/frontend.tar.gz + +# Extract it +pct exec 300 -- mkdir -p /opt +pct exec 300 -- tar -xzf /tmp/frontend.tar.gz -C /opt +``` + +### 3. Run the setup script inside the container + +```bash +pct exec 300 -- bash /opt/frontend/deploy/proxmox-lxc-setup.sh +``` + +This installs Python dependencies into `vendor/`, creates the `thermopro` user, sets up the systemd service, and starts it. + +### 4. Find the container IP + +```bash +pct exec 300 -- ip -4 addr show eth0 +``` + +Visit `http://:5000`. + +## Configuration + +Edit the service file to point at your CYD and tune behavior: + +```bash +pct exec 300 -- nano /etc/systemd/system/thermopro-frontend.service +``` + +Key environment variables: + +| Variable | Default | Description | +|----------|---------|-------------| +| `CYD_BASE_URL` | `http://192.168.2.55` | Base URL of the CYD bridge | +| `POLL_INTERVAL` | `5` | Seconds between backend polls of the CYD | +| `DATABASE_PATH` | `/data/thermopro.db` | SQLite path (persistent mount) | + +After editing: + +```bash +pct exec 300 -- systemctl daemon-reload +pct exec 300 -- systemctl restart thermopro-frontend +``` + +## Reverse proxy / HTTPS (recommended) + +Use Caddy or Nginx on the Proxmox host, another container, or your router to expose the app on a friendly URL. Example Caddyfile: + +``` +bbq.example.com { + reverse_proxy http://:5000 +} +``` + +## Updating the app + +To push a new version: + +```bash +# Re-tar the frontend folder and push it into the container +tar -czf /tmp/frontend.tar.gz frontend/ +pct push 300 /tmp/frontend.tar.gz /tmp/frontend.tar.gz + +# Extract over the install directory and restart +pct exec 300 -- bash -c "tar -xzf /tmp/frontend.tar.gz -C /opt && chown -R thermopro:thermopro /opt/frontend && systemctl restart thermopro-frontend" +``` + +## Persistent data + +By default the SQLite database is written to `/data/thermopro.db` inside the container. Proxmox backups include the container root disk, so the database is preserved. If you prefer to store it on the host, add a bind mount in the Proxmox container config: + +```bash +# On the Proxmox host +mkdir -p /var/lib/thermopro-data +pct set 300 -mp0 /var/lib/thermopro-data,mp=/data +``` + +Then restart the container. diff --git a/frontend/deploy/proxmox-lxc-setup.sh b/frontend/deploy/proxmox-lxc-setup.sh new file mode 100644 index 0000000..ff36da4 --- /dev/null +++ b/frontend/deploy/proxmox-lxc-setup.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +# Run this script inside a freshly created Proxmox LXC container +# (Debian 12 or Ubuntu 22.04/24.04) to install and configure the +# ThermoPro CYD frontend. + +set -euo pipefail + +INSTALL_DIR="/opt/thermopro-frontend" +DATA_DIR="/data" +SERVICE_NAME="thermopro-frontend" + +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root (e.g. inside the LXC container)" >&2 + exit 1 +fi + +echo "=== Updating packages ===" +apt-get update +apt-get upgrade -y + +echo "=== Installing Python tooling ===" +apt-get install -y python3 python3-pip git curl + +echo "=== Creating application user ===" +useradd -r -s /bin/false -d "${INSTALL_DIR}" thermopro || true + +echo "=== Creating data directory ===" +mkdir -p "${DATA_DIR}" +chown thermopro:thermopro "${DATA_DIR}" + +if [[ ! -d "${INSTALL_DIR}" ]]; then + echo "ERROR: ${INSTALL_DIR} does not exist." + echo "Copy the frontend/ folder into the container at ${INSTALL_DIR} first." + echo "Example from Proxmox host:" + echo " pct push /path/to/frontend.tar.gz /tmp/frontend.tar.gz" + echo " pct exec -- tar -xzf /tmp/frontend.tar.gz -C /opt" + exit 1 +fi + +cd "${INSTALL_DIR}" + +echo "=== Installing Python dependencies into vendor/ ===" +pip3 install --target vendor --upgrade -r requirements.txt + +echo "=== Setting ownership ===" +chown -R thermopro:thermopro "${INSTALL_DIR}" + +echo "=== Installing systemd service ===" +cp "${INSTALL_DIR}/deploy/thermopro-frontend.service" /etc/systemd/system/ +systemctl daemon-reload +systemctl enable "${SERVICE_NAME}" +systemctl start "${SERVICE_NAME}" + +echo "=== Waiting for service to start ===" +sleep 2 +systemctl status "${SERVICE_NAME}" --no-pager + +echo "" +echo "=== Installation complete ===" +echo "The frontend should now be running on http://:5000" +echo "" +echo "To check logs: journalctl -u ${SERVICE_NAME} -f" +echo "To edit config: nano /etc/systemd/system/${SERVICE_NAME}.service" +echo "Then reload: systemctl daemon-reload && systemctl restart ${SERVICE_NAME}" diff --git a/frontend/deploy/thermopro-frontend.service b/frontend/deploy/thermopro-frontend.service new file mode 100644 index 0000000..0f21ddd --- /dev/null +++ b/frontend/deploy/thermopro-frontend.service @@ -0,0 +1,20 @@ +[Unit] +Description=ThermoPro CYD Frontend +After=network.target + +[Service] +Type=simple +User=thermopro +Group=thermopro +WorkingDirectory=/opt/thermopro-frontend +Environment=CYD_BASE_URL=http://192.168.2.55 +Environment=POLL_INTERVAL=5 +Environment=DATABASE_PATH=/data/thermopro.db +Environment=PYTHONDONTWRITEBYTECODE=1 +Environment=PYTHONUNBUFFERED=1 +ExecStart=/usr/bin/python3 /opt/thermopro-frontend/app.py +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target