The panel now fronts user domains with HAProxy 3.4 LTS (official performance
packages) instead of Traefik: about 100 MB of RSS and 200 MB of disk saved for
a feature set that never used more than Host routing on :80 and SNI passthrough
on :443.
- hpx: publish the proxy configuration as immutable GENERATIONS. Every domain
mutation renders the whole set from the DB, validates it with the pinned
`haproxy -c`, and only then repoints the `current` symlink, so a rejected
candidate leaves the running proxy untouched and a stale domain can never
survive into a later generation. Routing is carried by two map files
(Host -> backend, SNI -> backend): per-domain frontend rules cannot work from
a second file because HAProxy rejects duplicate section names since 3.3 and
attaches bare directives to the section opened last.
- mgr: republish and reload (SIGUSR2, i.e. `systemctl reload`) after every
domain change, so a change takes effect without dropping established HTTP or
TLS connections. Rollback semantics (DB first, then publish) are unchanged.
- cfg,db: `net.traefik` is renamed to `net.haproxy` with identical values. A
pre-rename config.yaml key and the legacy VPSMGR_TRAEFIK env var are still
read (new name wins), and schema migration v18 moves the settings mirror from
`traefik` to `haproxy`, keeping a newer value when both rows exist.
- 30-haproxy.sh: install the pinned branch from the vendor repository and
migrate a Traefik host in one run — install and validate HAProxy first, then
remove Traefik's binary, unit, service account and dynamic rules (only its
config file is kept, inert). No fallback keeps both proxies alive.
- upgrade-haproxy.sh: follow the pinned branch to its newest patch, with a
configuration check and a graceful reload; `install.sh --update` runs it.
- tests: generation publish/rollback, map rendering, config-key and settings
migrations, plus real-binary tests (skipped unless
VPSMGR_TEST_HAPROXY_BIN is set) that run the generated configuration through
`haproxy -c` and start it in a network namespace.
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
- the publish job reads the tag's own message and uses it as the release
body: `git tag -a vX.Y.Z -m "..."` writes the notes shown on the release
page
- a lightweight tag carries no message, so the body falls back to
"fix some bugs"; GitHub still appends its auto-generated compare link
below whatever body is passed
- a signed tag's PGP block is stripped from the notes
- document the annotated-tag flow in docs/development.md
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
- new installs pull incus-base (Zabbly lts-7.0) which ships the same
incusd daemon without the QEMU/SPICE/Ceph VM stack (~240 MiB less
download, 500 MiB+ less disk)
- leave hosts that already carry the full `incus` package untouched
- uninstall --purge now also removes the full-incus VM dependencies,
guarded by an installed reverse-dependency check (never blanket autoremove)
- update the dev docs install snippet to incus-base
Generated with Codebuff 🤖
Co-Authored-By: Codebuff <noreply@codebuff.com>
- scripts/90-arch-image.sh: builds vpsmgr/arch-sshd from images:archlinux/
current; unlike other image scripts it always deletes and rebuilds (rolling),
records Archlinux<YYMM> in the image description, keeps the image slim and
deletes the base afterwards
- Register Arch Linux label + rolling-release blurb and a gray triangle icon
in the user panel reinstall dialog
- Docs (README, architecture, development, AGENTS) and image tests updated
Add scripts/80-debian-dev-image.sh, modeled on 50-image.sh: pulls
images:debian/13, installs the universal sshd/tooling set plus the dev
toolchain (python3 + pip + venv, git/sqlite3/ripgrep/jq/gh/sshpass, all
--no-install-recommends), Go 1.26.7 (arch-aware, sha256 from the dl JSON
API), nvm v0.40.7 + Node 24, cleans caches, and publishes
vpsmgr/debian-dev-sshd (base deleted).
- Symlink go/gofmt/node/npm/npx into /usr/local/bin: /etc/profile.d is
only read by login shells, so non-interactive ssh commands would miss
them; nvm's .bashrc hook already covered node
- Register the alias in imageLabels so the reinstall dialog shows
"Debian 13 dev"; extend collectManagedImages tests
- Optional: not part of install.sh, keeping small hosts lean
- Document the new image in docs/architecture.md, development.md and the
AGENTS.md image-build invariant
The panel now talks to Incus over its Unix socket REST API
(/var/lib/incus/unix.socket, group incus-admin) exclusively:
- internal/lx: exec moved from the `lxc` CLI to the API websocket
transport (Exec/ExecSH/RunInitScript); EnsureImage pulls a
remote-qualified fallback (images:debian/13) before Launch since the
API cannot auto-fetch it inside the create call; per-container df
probe in mgr/batch.go uses the same API path.
- cfg: config key renamed lxd.* -> incus.* (image, image_fallback,
pool, bridge, socket); DefaultSocket is the Debian-package path.
- mgr: container disk probe and image handling updated; comment sweep
from LXD to Incus.
- deps: add gorilla/websocket for the exec transport.
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>