Hit in production 2026-08-13: settings crash-looped with 'password authentication failed' after a routine --only settings redeploy. The settings Postgres role was only ever created once, in deploy_postgres()'s init SQL (fresh-volume-only) — so if CREDS_FILE's SETTINGS_DB_PASS ever drifted from the role's actual password, redeploying settings had no way to self-heal. Mirrors the CREATE-then-fallback pattern other apps' deploy functions use, but falls back to ALTER instead of swallowing the error, since CREATE failing because the role already exists doesn't fix a drifted password. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|---|---|---|
| docs | ||
| infrastructure | ||
| scripts | ||
| .gitignore | ||
| add-app.sh | ||
| install-stack.sh | ||
| README.md | ||
Hotel Manage — Proxmox Stack Installer
tteck-style helper scripts that provision the stack onto a fresh Proxmox host — no local copy of the repo required on the host.
Install vs. update — two separate paths
- Install (creating an LXC) runs on the Proxmox host, because
pctonly exists on the hypervisor. That's what these scripts are for. - Updates (git pull +
docker compose up --build) are driven from the management container over SSH — no hypervisor access needed. Push to a service repo → Forgejo webhook → management redeploys that LXC in place.
So the management container never creates LXCs; it only updates, monitors and backs up what these scripts provisioned.
Repo layout (Forgejo — org hotel-manage-stack)
All repos are public, grouped under the hotel-manage-stack org at
git.pterois.co.uk. Property-neutral names, since the stack deploys at multiple
hotels:
| Repo | Contents | Provisioned to |
|---|---|---|
stack-init |
Installer scripts + docs/ + infrastructure/ reference |
run on the Proxmox host |
auth |
central auth service | LXC 101 |
portal |
PWA portal shell | LXC 102 |
management |
updater + Kuma + backup | LXC 105 |
noticeboard |
starter app | LXC 112 |
kitchen, cashup, … |
one repo per app | added later |
Postgres (LXC 100) and NPM (LXC 103) have no repo — the installer generates their compose files inline (they carry secrets / are pure infra).
Repos live under the
hotel-manage-stackorg. TheFORGEJO_BASEdefault in the wizard ishttps://git.pterois.co.uk/hotel-manage-stack.
One-time host prep
Add the internal bridge to /etc/network/interfaces, then ifreload -a:
auto vmbr1
iface vmbr1 inet static
address 10.10.10.1/24
bridge-ports none
bridge-stp off
bridge-fd 0
The installer will offer to download the Ubuntu 22.04 template if missing.
Run the installer (foundation)
On the Proxmox host shell (as root). All repos are public, so no token needed:
bash <(curl -fsSL https://git.pterois.co.uk/hotel-manage-stack/stack-init/raw/branch/main/install-stack.sh)
The wizard collects site name, domain, NPM LAN IP/gateway, office IP for offsite restriction, admin credentials, the Forgejo base URL, and a backup target. It then provisions the six foundation LXCs (postgres, auth, portal, npm, management, noticeboard), health-checks each, and configures the NPM proxy routes. (Leave the Forgejo token blank — the repos are public.)
Secrets are written to /root/hotel-manage-credentials.txt (chmod 600) — copy this
offsite.
Add an app later
On the Proxmox host (again, because it creates an LXC):
bash <(curl -fsSL https://git.pterois.co.uk/hotel-manage-stack/stack-init/raw/branch/main/add-app.sh)
Reads /root/hotel-manage-credentials.txt for the shared secret and office IP,
provisions a new LXC, optionally creates a dedicated postgres DB, clones the
app repo, and prints the NPM route / Uptime Kuma / webhook / deploy-map lines
to finish wiring it in. After that, ongoing updates flow through the management
container automatically.
Replicating to another hotel
Same command on the new host. Only the wizard answers differ per site:
DOMAIN, NPM LAN IP + gateway (that site's LAN pool), and OFFICE_IP_CHECK.
The internal 10.10.10.0/24 network and all service IPs are identical
everywhere, so the repos are reused unchanged.
LXC organisation
Every LXC is created with:
- a
hotel-manage-<role>hostname (e.g.hotel-manage-postgres,hotel-manage-auth,hotel-manage-noticeboard), - membership of a Proxmox resource pool
hotel-manage, and - a tag
hotel-manage,
so the whole stack groups and filters together in the Proxmox UI and is easy to
tell apart from any other containers on the host. add-app.sh puts new app LXCs
in the same pool/tag.
Notes
- All repos are public, so no Forgejo token is needed to install or update. The wizard still accepts a token (used only if you later make the repos private again — it gets embedded in each LXC's git remote for the updater).
install-stack.shis idempotent-ish: existing LXCs are skipped (started if stopped) rather than recreated, so a re-run resumes a partial install.