Prefix LXCs hotel-manage-*; group in Proxmox pool + tag
This commit is contained in:
parent
d052d0bddf
commit
4622cc3d45
3 changed files with 110 additions and 71 deletions
18
README.md
18
README.md
|
|
@ -1,4 +1,4 @@
|
||||||
# Proxmox Helpers — HNF Stack Installer
|
# Hotel Manage — Proxmox Stack Installer
|
||||||
|
|
||||||
tteck-style helper scripts that provision the stack onto a fresh Proxmox host —
|
tteck-style helper scripts that provision the stack onto a fresh Proxmox host —
|
||||||
no local copy of the repo required on the host.
|
no local copy of the repo required on the host.
|
||||||
|
|
@ -64,7 +64,7 @@ target. It then provisions the six foundation LXCs (postgres, auth, portal,
|
||||||
npm, management, noticeboard), health-checks each, and configures the NPM proxy
|
npm, management, noticeboard), health-checks each, and configures the NPM proxy
|
||||||
routes. (Leave the Forgejo token blank — the repos are public.)
|
routes. (Leave the Forgejo token blank — the repos are public.)
|
||||||
|
|
||||||
Secrets are written to `/root/hnf-credentials.txt` (chmod 600) — copy this
|
Secrets are written to `/root/hotel-manage-credentials.txt` (chmod 600) — copy this
|
||||||
offsite.
|
offsite.
|
||||||
|
|
||||||
## Add an app later
|
## Add an app later
|
||||||
|
|
@ -75,7 +75,7 @@ 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)
|
bash <(curl -fsSL https://git.pterois.co.uk/hotel-manage-stack/stack-init/raw/branch/main/add-app.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
Reads `/root/hnf-credentials.txt` for the shared secret and office IP,
|
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
|
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
|
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
|
to finish wiring it in. After that, ongoing updates flow through the management
|
||||||
|
|
@ -88,6 +88,18 @@ Same command on the new host. Only the wizard answers differ per site:
|
||||||
The internal `10.10.10.0/24` network and all service IPs are identical
|
The internal `10.10.10.0/24` network and all service IPs are identical
|
||||||
everywhere, so the repos are reused unchanged.
|
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
|
## Notes
|
||||||
|
|
||||||
- All repos are public, so no Forgejo token is needed to install or update.
|
- All repos are public, so no Forgejo token is needed to install or update.
|
||||||
|
|
|
||||||
40
add-app.sh
40
add-app.sh
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# ┌─────────────────────────────────────────────────────────────────────────┐
|
# ┌─────────────────────────────────────────────────────────────────────────┐
|
||||||
# │ HNF Manage — Add App LXC │
|
# │ Hotel Manage — Add App LXC │
|
||||||
# │ Provisions a single app container and wires it into the stack. │
|
# │ Provisions a single app container and wires it into the stack. │
|
||||||
# │ │
|
# │ │
|
||||||
# │ Usage: bash add-app.sh (or curl-bootstrap, see install/README.md) │
|
# │ Usage: bash add-app.sh (or curl-bootstrap, see install/README.md) │
|
||||||
|
|
@ -23,7 +23,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||||
|
|
||||||
# Load secrets from credentials file if present
|
# Load secrets from credentials file if present
|
||||||
CREDS_FILE=/root/hnf-credentials.txt
|
CREDS_FILE=/root/hotel-manage-credentials.txt
|
||||||
if [[ -f "$CREDS_FILE" ]]; then
|
if [[ -f "$CREDS_FILE" ]]; then
|
||||||
# shellcheck disable=SC1090
|
# shellcheck disable=SC1090
|
||||||
set -a; source <(grep -v '^#' "$CREDS_FILE" | grep '='); set +a
|
set -a; source <(grep -v '^#' "$CREDS_FILE" | grep '='); set +a
|
||||||
|
|
@ -104,12 +104,18 @@ fi
|
||||||
|
|
||||||
# ── Get mgmt public key ───────────────────────────────────────────────────────
|
# ── Get mgmt public key ───────────────────────────────────────────────────────
|
||||||
MGMT_PUBKEY=""
|
MGMT_PUBKEY=""
|
||||||
[[ -f /root/.ssh/hnf_management.pub ]] && MGMT_PUBKEY=$(cat /root/.ssh/hnf_management.pub)
|
[[ -f /root/.ssh/hotel-manage_deploy.pub ]] && MGMT_PUBKEY=$(cat /root/.ssh/hotel-manage_deploy.pub)
|
||||||
|
|
||||||
|
# ── Resource pool (created by install-stack.sh; reuse if present) ──────────────
|
||||||
|
POOL="hotel-manage"
|
||||||
|
POOL_OPT=""
|
||||||
|
pvesh get "/pools/${POOL}" &>/dev/null || pvesh create /pools --poolid "${POOL}" &>/dev/null || true
|
||||||
|
pvesh get "/pools/${POOL}" &>/dev/null && POOL_OPT="--pool ${POOL}"
|
||||||
|
|
||||||
# ── Create LXC ────────────────────────────────────────────────────────────────
|
# ── Create LXC ────────────────────────────────────────────────────────────────
|
||||||
msg_info "Creating LXC ${LXC_ID} (hnf-${APP_NAME} at 10.10.10.${LAST_OCTET})"
|
msg_info "Creating LXC ${LXC_ID} (hotel-manage-${APP_NAME} at 10.10.10.${LAST_OCTET})"
|
||||||
pct create "$LXC_ID" "$TEMPLATE" \
|
pct create "$LXC_ID" "$TEMPLATE" \
|
||||||
--hostname "hnf-${APP_NAME}" \
|
--hostname "hotel-manage-${APP_NAME}" \
|
||||||
--memory 512 \
|
--memory 512 \
|
||||||
--cores 1 \
|
--cores 1 \
|
||||||
--rootfs "${STORAGE}:8" \
|
--rootfs "${STORAGE}:8" \
|
||||||
|
|
@ -117,6 +123,8 @@ pct create "$LXC_ID" "$TEMPLATE" \
|
||||||
--features nesting=1 \
|
--features nesting=1 \
|
||||||
--unprivileged 0 \
|
--unprivileged 0 \
|
||||||
--onboot 1 \
|
--onboot 1 \
|
||||||
|
--tags "${POOL}" \
|
||||||
|
${POOL_OPT} \
|
||||||
--start 1 &>/dev/null
|
--start 1 &>/dev/null
|
||||||
sleep 5
|
sleep 5
|
||||||
msg_ok "LXC ${LXC_ID} created"
|
msg_ok "LXC ${LXC_ID} created"
|
||||||
|
|
@ -150,17 +158,17 @@ if [[ "$APP_DB" == "yes" ]]; then
|
||||||
msg_info "Creating database ${APP_DB_NAME}"
|
msg_info "Creating database ${APP_DB_NAME}"
|
||||||
# Run SQL via postgres LXC
|
# Run SQL via postgres LXC
|
||||||
pct exec 100 -- bash -c "
|
pct exec 100 -- bash -c "
|
||||||
docker exec hnf-postgres psql -U postgres -c \
|
docker exec hotel-manage-postgres psql -U postgres -c \
|
||||||
\"CREATE USER ${APP_DB_USER} WITH PASSWORD '${APP_DB_PASS}';\" 2>/dev/null || true
|
\"CREATE USER ${APP_DB_USER} WITH PASSWORD '${APP_DB_PASS}';\" 2>/dev/null || true
|
||||||
docker exec hnf-postgres psql -U postgres -c \
|
docker exec hotel-manage-postgres psql -U postgres -c \
|
||||||
\"CREATE DATABASE ${APP_DB_NAME} OWNER ${APP_DB_USER};\" 2>/dev/null || true
|
\"CREATE DATABASE ${APP_DB_NAME} OWNER ${APP_DB_USER};\" 2>/dev/null || true
|
||||||
docker exec hnf-postgres psql -U postgres -d ${APP_DB_NAME} -c \
|
docker exec hotel-manage-postgres psql -U postgres -d ${APP_DB_NAME} -c \
|
||||||
\"GRANT ALL ON SCHEMA public TO ${APP_DB_USER};\" 2>/dev/null || true
|
\"GRANT ALL ON SCHEMA public TO ${APP_DB_USER};\" 2>/dev/null || true
|
||||||
" &>/dev/null
|
" &>/dev/null
|
||||||
msg_ok "Database ${APP_DB_NAME} created"
|
msg_ok "Database ${APP_DB_NAME} created"
|
||||||
|
|
||||||
# Append DB creds to credentials file
|
# Append DB creds to credentials file
|
||||||
cat >> /root/hnf-credentials.txt <<EOF
|
cat >> /root/hotel-manage-credentials.txt <<EOF
|
||||||
|
|
||||||
# ${APP_NAME} DB
|
# ${APP_NAME} DB
|
||||||
${APP_NAME^^}_DB_PASS=${APP_DB_PASS}
|
${APP_NAME^^}_DB_PASS=${APP_DB_PASS}
|
||||||
|
|
@ -178,13 +186,13 @@ if [[ "$USE_FORGEJO" == "true" ]]; then
|
||||||
git clone -q '${FORGEJO_REPO}' /opt/${APP_NAME}
|
git clone -q '${FORGEJO_REPO}' /opt/${APP_NAME}
|
||||||
" &>/dev/null
|
" &>/dev/null
|
||||||
else
|
else
|
||||||
tmp=$(mktemp /tmp/hnf-app-XXXX.tar.gz)
|
tmp=$(mktemp /tmp/hotel-manage-app-XXXX.tar.gz)
|
||||||
tar czf "$tmp" -C "$(dirname "$LOCAL_SRC")" "$(basename "$LOCAL_SRC")" 2>/dev/null
|
tar czf "$tmp" -C "$(dirname "$LOCAL_SRC")" "$(basename "$LOCAL_SRC")" 2>/dev/null
|
||||||
pct push "$LXC_ID" "$tmp" /tmp/hnf-app.tar.gz 2>/dev/null
|
pct push "$LXC_ID" "$tmp" /tmp/hotel-manage-app.tar.gz 2>/dev/null
|
||||||
pct exec "$LXC_ID" -- bash -c "
|
pct exec "$LXC_ID" -- bash -c "
|
||||||
mkdir -p /opt && tar xzf /tmp/hnf-app.tar.gz -C /opt
|
mkdir -p /opt && tar xzf /tmp/hotel-manage-app.tar.gz -C /opt
|
||||||
mv /opt/$(basename "$LOCAL_SRC") /opt/${APP_NAME} 2>/dev/null || true
|
mv /opt/$(basename "$LOCAL_SRC") /opt/${APP_NAME} 2>/dev/null || true
|
||||||
rm -f /tmp/hnf-app.tar.gz
|
rm -f /tmp/hotel-manage-app.tar.gz
|
||||||
" &>/dev/null
|
" &>/dev/null
|
||||||
rm -f "$tmp"
|
rm -f "$tmp"
|
||||||
fi
|
fi
|
||||||
|
|
@ -192,7 +200,7 @@ msg_ok "App files deployed to /opt/${APP_NAME}"
|
||||||
|
|
||||||
# ── Write .env ────────────────────────────────────────────────────────────────
|
# ── Write .env ────────────────────────────────────────────────────────────────
|
||||||
msg_info "Writing .env"
|
msg_info "Writing .env"
|
||||||
ENV_TMP=$(mktemp /tmp/hnf-env-XXXX)
|
ENV_TMP=$(mktemp /tmp/hotel-manage-env-XXXX)
|
||||||
{
|
{
|
||||||
echo "NODE_ENV=production"
|
echo "NODE_ENV=production"
|
||||||
echo "APP_SLUG=${APP_NAME}"
|
echo "APP_SLUG=${APP_NAME}"
|
||||||
|
|
@ -209,7 +217,7 @@ msg_ok ".env written"
|
||||||
|
|
||||||
# ── Register app in auth service ──────────────────────────────────────────────
|
# ── Register app in auth service ──────────────────────────────────────────────
|
||||||
msg_warn "Remember to register '${APP_NAME}' in the auth service DB:"
|
msg_warn "Remember to register '${APP_NAME}' in the auth service DB:"
|
||||||
printf " docker exec hnf-auth-1 node -e \"\n"
|
printf " docker exec hotel-manage-auth-1 node -e \"\n"
|
||||||
printf " const db = require('./src/db.js');\n"
|
printf " const db = require('./src/db.js');\n"
|
||||||
printf " db.query(\\\"INSERT INTO apps (slug,name,base_path) VALUES ('%s','%s','%s') ON CONFLICT DO NOTHING\\\");\n" \
|
printf " db.query(\\\"INSERT INTO apps (slug,name,base_path) VALUES ('%s','%s','%s') ON CONFLICT DO NOTHING\\\");\n" \
|
||||||
"$APP_NAME" "$APP_NAME" "$APP_PATH"
|
"$APP_NAME" "$APP_NAME" "$APP_PATH"
|
||||||
|
|
@ -233,7 +241,7 @@ cat <<SUMMARY
|
||||||
3. Add to Uptime Kuma:
|
3. Add to Uptime Kuma:
|
||||||
http://10.10.10.${LAST_OCTET}:${APP_PORT}${APP_PATH}health
|
http://10.10.10.${LAST_OCTET}:${APP_PORT}${APP_PATH}health
|
||||||
4. Add Forgejo webhook:
|
4. Add Forgejo webhook:
|
||||||
http://10.10.10.105:9000/webhook (secret in /root/hnf-credentials.txt)
|
http://10.10.10.105:9000/webhook (secret in /root/hotel-manage-credentials.txt)
|
||||||
5. Add deploy entry to the management repo: updater/deploy-map.js:
|
5. Add deploy entry to the management repo: updater/deploy-map.js:
|
||||||
'${APP_NAME}': { host: '10.10.10.${LAST_OCTET}', path: '/opt/${APP_NAME}' }
|
'${APP_NAME}': { host: '10.10.10.${LAST_OCTET}', path: '/opt/${APP_NAME}' }
|
||||||
|
|
||||||
|
|
|
||||||
123
install-stack.sh
123
install-stack.sh
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# ┌─────────────────────────────────────────────────────────────────────────┐
|
# ┌─────────────────────────────────────────────────────────────────────────┐
|
||||||
# │ HNF Manage — Proxmox Stack Installer │
|
# │ Hotel Manage — Proxmox Stack Installer │
|
||||||
# │ Provisions: postgres · auth · portal · npm · management · noticeboard │
|
# │ Provisions: postgres · auth · portal · npm · management · noticeboard │
|
||||||
# │ │
|
# │ │
|
||||||
# │ Run on the Proxmox host shell: │
|
# │ Run on the Proxmox host shell: │
|
||||||
|
|
@ -97,35 +97,35 @@ ensure_template() {
|
||||||
|
|
||||||
# ── Collect site config ───────────────────────────────────────────────────────
|
# ── Collect site config ───────────────────────────────────────────────────────
|
||||||
collect_config() {
|
collect_config() {
|
||||||
SITE_NAME=$(whiptail --title "HNF Stack — Site Config" \
|
SITE_NAME=$(whiptail --title "Hotel Manage — Site Config" \
|
||||||
--inputbox "Site name:" 8 52 "Hotel Number Four" 3>&1 1>&2 2>&3) || exit 0
|
--inputbox "Site name:" 8 52 "Hotel Number Four" 3>&1 1>&2 2>&3) || exit 0
|
||||||
|
|
||||||
DOMAIN=$(whiptail --title "HNF Stack — Site Config" \
|
DOMAIN=$(whiptail --title "Hotel Manage — Site Config" \
|
||||||
--inputbox "Public domain (e.g. manage.hotelnumberfour.com):" 8 64 "manage.hotelnumberfour.com" \
|
--inputbox "Public domain (e.g. manage.hotelnumberfour.com):" 8 64 "manage.hotelnumberfour.com" \
|
||||||
3>&1 1>&2 2>&3) || exit 0
|
3>&1 1>&2 2>&3) || exit 0
|
||||||
|
|
||||||
NPM_LAN_IP=$(whiptail --title "HNF Stack — Site Config" \
|
NPM_LAN_IP=$(whiptail --title "Hotel Manage — Site Config" \
|
||||||
--inputbox "NPM LXC static LAN IP (from your hotel LAN pool):" 8 64 "10.4.0.50" \
|
--inputbox "NPM LXC static LAN IP (from your hotel LAN pool):" 8 64 "10.4.0.50" \
|
||||||
3>&1 1>&2 2>&3) || exit 0
|
3>&1 1>&2 2>&3) || exit 0
|
||||||
|
|
||||||
LAN_GW=$(whiptail --title "HNF Stack — Site Config" \
|
LAN_GW=$(whiptail --title "Hotel Manage — Site Config" \
|
||||||
--inputbox "LAN gateway IP:" 8 52 "10.4.0.1" 3>&1 1>&2 2>&3) || exit 0
|
--inputbox "LAN gateway IP:" 8 52 "10.4.0.1" 3>&1 1>&2 2>&3) || exit 0
|
||||||
|
|
||||||
OFFICE_IP=$(whiptail --title "HNF Stack — Site Config" \
|
OFFICE_IP=$(whiptail --title "Hotel Manage — Site Config" \
|
||||||
--inputbox \
|
--inputbox \
|
||||||
"Office IP / CIDR / DDNS hostname for offsite restriction.
|
"Office IP / CIDR / DDNS hostname for offsite restriction.
|
||||||
Examples: 203.0.113.5 10.4.0.0/22 hotel.dyndns.org
|
Examples: 203.0.113.5 10.4.0.0/22 hotel.dyndns.org
|
||||||
Type 'disabled' to allow access from anywhere:" \
|
Type 'disabled' to allow access from anywhere:" \
|
||||||
11 64 "disabled" 3>&1 1>&2 2>&3) || exit 0
|
11 64 "disabled" 3>&1 1>&2 2>&3) || exit 0
|
||||||
|
|
||||||
ADMIN_EMAIL=$(whiptail --title "HNF Stack — Admin Account" \
|
ADMIN_EMAIL=$(whiptail --title "Hotel Manage — Admin Account" \
|
||||||
--inputbox "Admin user email:" 8 52 "" 3>&1 1>&2 2>&3) || exit 0
|
--inputbox "Admin user email:" 8 52 "" 3>&1 1>&2 2>&3) || exit 0
|
||||||
|
|
||||||
ADMIN_PASS=$(whiptail --title "HNF Stack — Admin Account" \
|
ADMIN_PASS=$(whiptail --title "Hotel Manage — Admin Account" \
|
||||||
--passwordbox "Admin user password:" 8 52 3>&1 1>&2 2>&3) || exit 0
|
--passwordbox "Admin user password:" 8 52 3>&1 1>&2 2>&3) || exit 0
|
||||||
|
|
||||||
# Deploy source — per-service Forgejo repos (default) or a local copy on this host
|
# Deploy source — per-service Forgejo repos (default) or a local copy on this host
|
||||||
FORGEJO_BASE=$(whiptail --title "HNF Stack — Forgejo" \
|
FORGEJO_BASE=$(whiptail --title "Hotel Manage — Forgejo" \
|
||||||
--inputbox \
|
--inputbox \
|
||||||
"Forgejo org/base URL hosting the per-service repos.
|
"Forgejo org/base URL hosting the per-service repos.
|
||||||
Each service is cloned from <base>/<service>.git
|
Each service is cloned from <base>/<service>.git
|
||||||
|
|
@ -135,7 +135,7 @@ Example: https://git.pterois.co.uk/hotel-manage-stack" \
|
||||||
13 66 "https://git.pterois.co.uk/hotel-manage-stack" 3>&1 1>&2 2>&3) || exit 0
|
13 66 "https://git.pterois.co.uk/hotel-manage-stack" 3>&1 1>&2 2>&3) || exit 0
|
||||||
FORGEJO_BASE="${FORGEJO_BASE%/}"
|
FORGEJO_BASE="${FORGEJO_BASE%/}"
|
||||||
|
|
||||||
FORGEJO_TOKEN=$(whiptail --title "HNF Stack — Forgejo Token" \
|
FORGEJO_TOKEN=$(whiptail --title "Hotel Manage — Forgejo Token" \
|
||||||
--passwordbox \
|
--passwordbox \
|
||||||
"The repos are PUBLIC — leave this blank.
|
"The repos are PUBLIC — leave this blank.
|
||||||
|
|
||||||
|
|
@ -144,7 +144,7 @@ from Forgejo → Settings → Applications, scope read:repository,
|
||||||
which gets embedded in each LXC's git remote for the updater.)" \
|
which gets embedded in each LXC's git remote for the updater.)" \
|
||||||
12 66 3>&1 1>&2 2>&3) || exit 0
|
12 66 3>&1 1>&2 2>&3) || exit 0
|
||||||
|
|
||||||
if whiptail --title "HNF Stack — Deploy Source" --yesno \
|
if whiptail --title "Hotel Manage — Deploy Source" --yesno \
|
||||||
"Deploy services from Forgejo? (recommended)\n\nNo = copy from a local repo at ${REPO_ROOT}\n(only works if you already copied the repo to this host)" \
|
"Deploy services from Forgejo? (recommended)\n\nNo = copy from a local repo at ${REPO_ROOT}\n(only works if you already copied the repo to this host)" \
|
||||||
11 62; then
|
11 62; then
|
||||||
USE_FORGEJO=true
|
USE_FORGEJO=true
|
||||||
|
|
@ -152,24 +152,24 @@ which gets embedded in each LXC's git remote for the updater.)" \
|
||||||
USE_FORGEJO=false
|
USE_FORGEJO=false
|
||||||
fi
|
fi
|
||||||
|
|
||||||
BACKUP_REMOTE=$(whiptail --title "HNF Stack — Backup" \
|
BACKUP_REMOTE=$(whiptail --title "Hotel Manage — Backup" \
|
||||||
--inputbox \
|
--inputbox \
|
||||||
"Backup rsync target (leave blank to skip backup config).
|
"Backup rsync target (leave blank to skip backup config).
|
||||||
Example: backup@192.168.1.10:/backups/hnf" \
|
Example: backup@192.168.1.10:/backups/hotel-manage" \
|
||||||
10 64 "" 3>&1 1>&2 2>&3) || exit 0
|
10 64 "" 3>&1 1>&2 2>&3) || exit 0
|
||||||
|
|
||||||
# Confirm LXC allocation
|
# Confirm LXC allocation
|
||||||
whiptail --title "HNF Stack — Confirm" --yesno \
|
whiptail --title "Hotel Manage — Confirm" --yesno \
|
||||||
"LXCs to be created (storage: ${STORAGE}):
|
"LXCs to be created (storage: ${STORAGE}):
|
||||||
|
|
||||||
ID Hostname IP
|
ID Hostname IP
|
||||||
──────────────────────────────────────────
|
──────────────────────────────────────────
|
||||||
100 hnf-postgres 10.10.10.100
|
100 hotel-manage-postgres 10.10.10.100
|
||||||
101 hnf-auth 10.10.10.101
|
101 hotel-manage-auth 10.10.10.101
|
||||||
102 hnf-portal 10.10.10.102
|
102 hotel-manage-portal 10.10.10.102
|
||||||
103 hnf-npm 10.10.10.103 / ${NPM_LAN_IP} (dual-homed)
|
103 hotel-manage-npm 10.10.10.103 / ${NPM_LAN_IP} (dual-homed)
|
||||||
105 hnf-management 10.10.10.105
|
105 hotel-manage-management 10.10.10.105
|
||||||
112 hnf-noticeboard 10.10.10.112
|
112 hotel-manage-noticeboard 10.10.10.112
|
||||||
|
|
||||||
Domain: ${DOMAIN}
|
Domain: ${DOMAIN}
|
||||||
Admin: ${ADMIN_EMAIL}
|
Admin: ${ADMIN_EMAIL}
|
||||||
|
|
@ -187,8 +187,8 @@ gen_secrets() {
|
||||||
WEBHOOK_SECRET=$(openssl rand -hex 24)
|
WEBHOOK_SECRET=$(openssl rand -hex 24)
|
||||||
NPM_ADMIN_PASS=$(openssl rand -base64 12 | tr -dc 'a-zA-Z0-9' | head -c 12)
|
NPM_ADMIN_PASS=$(openssl rand -base64 12 | tr -dc 'a-zA-Z0-9' | head -c 12)
|
||||||
|
|
||||||
cat > /root/hnf-credentials.txt <<EOF
|
cat > /root/hotel-manage-credentials.txt <<EOF
|
||||||
# HNF Manage credentials — generated $(date '+%Y-%m-%d %H:%M')
|
# Hotel Manage credentials — generated $(date '+%Y-%m-%d %H:%M')
|
||||||
# !! KEEP THIS FILE SAFE — store a copy offsite !!
|
# !! KEEP THIS FILE SAFE — store a copy offsite !!
|
||||||
|
|
||||||
SITE_NAME=${SITE_NAME}
|
SITE_NAME=${SITE_NAME}
|
||||||
|
|
@ -211,22 +211,22 @@ FORGEJO_TOKEN=${FORGEJO_TOKEN}
|
||||||
|
|
||||||
BACKUP_REMOTE=${BACKUP_REMOTE}
|
BACKUP_REMOTE=${BACKUP_REMOTE}
|
||||||
EOF
|
EOF
|
||||||
chmod 600 /root/hnf-credentials.txt
|
chmod 600 /root/hotel-manage-credentials.txt
|
||||||
msg_ok "Secrets generated → /root/hnf-credentials.txt"
|
msg_ok "Secrets generated → /root/hotel-manage-credentials.txt"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ── SSH keypair for management → app LXCs ────────────────────────────────────
|
# ── SSH keypair for management → app LXCs ────────────────────────────────────
|
||||||
gen_mgmt_ssh_key() {
|
gen_mgmt_ssh_key() {
|
||||||
if [[ ! -f /root/.ssh/hnf_management ]]; then
|
if [[ ! -f /root/.ssh/hotel-manage_deploy ]]; then
|
||||||
msg_info "Generating management SSH keypair"
|
msg_info "Generating management SSH keypair"
|
||||||
mkdir -p /root/.ssh
|
mkdir -p /root/.ssh
|
||||||
ssh-keygen -t ed25519 -f /root/.ssh/hnf_management -N "" -C "hnf-management-deploy" &>/dev/null
|
ssh-keygen -t ed25519 -f /root/.ssh/hotel-manage_deploy -N "" -C "hotel-manage-management-deploy" &>/dev/null
|
||||||
msg_ok "SSH keypair generated → /root/.ssh/hnf_management"
|
msg_ok "SSH keypair generated → /root/.ssh/hotel-manage_deploy"
|
||||||
else
|
else
|
||||||
msg_ok "Using existing SSH keypair at /root/.ssh/hnf_management"
|
msg_ok "Using existing SSH keypair at /root/.ssh/hotel-manage_deploy"
|
||||||
fi
|
fi
|
||||||
MGMT_PUBKEY=$(cat /root/.ssh/hnf_management.pub)
|
MGMT_PUBKEY=$(cat /root/.ssh/hotel-manage_deploy.pub)
|
||||||
echo "${MGMT_PUBKEY}" >> /root/hnf-credentials.txt
|
echo "${MGMT_PUBKEY}" >> /root/hotel-manage-credentials.txt
|
||||||
}
|
}
|
||||||
|
|
||||||
# ── LXC lifecycle helpers ─────────────────────────────────────────────────────
|
# ── LXC lifecycle helpers ─────────────────────────────────────────────────────
|
||||||
|
|
@ -244,16 +244,30 @@ lxc_running() {
|
||||||
pct status "$1" 2>/dev/null | grep -q "running"
|
pct status "$1" 2>/dev/null | grep -q "running"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Group the stack in a Proxmox resource pool + tag for tidy UI organisation.
|
||||||
|
POOL="hotel-manage"
|
||||||
|
POOL_OPT=""
|
||||||
|
ensure_pool() {
|
||||||
|
if ! pvesh get "/pools/${POOL}" &>/dev/null; then
|
||||||
|
msg_info "Creating Proxmox resource pool '${POOL}'"
|
||||||
|
pvesh create /pools --poolid "${POOL}" --comment "Hotel Manage stack" &>/dev/null || true
|
||||||
|
pvesh get "/pools/${POOL}" &>/dev/null && msg_ok "Pool '${POOL}' ready" \
|
||||||
|
|| msg_warn "Could not create pool '${POOL}' — continuing without it"
|
||||||
|
fi
|
||||||
|
# Only pass --pool if it actually exists (else pct create would fail)
|
||||||
|
pvesh get "/pools/${POOL}" &>/dev/null && POOL_OPT="--pool ${POOL}"
|
||||||
|
}
|
||||||
|
|
||||||
create_lxc() {
|
create_lxc() {
|
||||||
local id=$1 ip=$2 name=$3 mem=${4:-512} cores=${5:-1}
|
local id=$1 ip=$2 name=$3 mem=${4:-512} cores=${5:-1}
|
||||||
if lxc_exists "$id"; then
|
if lxc_exists "$id"; then
|
||||||
msg_warn "LXC $id (hnf-${name}) already exists — skipping creation"
|
msg_warn "LXC $id (hotel-manage-${name}) already exists — skipping creation"
|
||||||
lxc_running "$id" || pct start "$id"
|
lxc_running "$id" || pct start "$id"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
local tmpl; tmpl=$(get_template)
|
local tmpl; tmpl=$(get_template)
|
||||||
pct create "$id" "$tmpl" \
|
pct create "$id" "$tmpl" \
|
||||||
--hostname "hnf-${name}" \
|
--hostname "hotel-manage-${name}" \
|
||||||
--memory "$mem" \
|
--memory "$mem" \
|
||||||
--cores "$cores" \
|
--cores "$cores" \
|
||||||
--rootfs "${STORAGE}:8" \
|
--rootfs "${STORAGE}:8" \
|
||||||
|
|
@ -261,6 +275,8 @@ create_lxc() {
|
||||||
--features nesting=1 \
|
--features nesting=1 \
|
||||||
--unprivileged 0 \
|
--unprivileged 0 \
|
||||||
--onboot 1 \
|
--onboot 1 \
|
||||||
|
--tags "${POOL}" \
|
||||||
|
${POOL_OPT} \
|
||||||
--start 1 &>/dev/null
|
--start 1 &>/dev/null
|
||||||
sleep 5 # let systemd start
|
sleep 5 # let systemd start
|
||||||
}
|
}
|
||||||
|
|
@ -268,13 +284,13 @@ create_lxc() {
|
||||||
create_npm_lxc() {
|
create_npm_lxc() {
|
||||||
local id=103
|
local id=103
|
||||||
if lxc_exists "$id"; then
|
if lxc_exists "$id"; then
|
||||||
msg_warn "LXC $id (hnf-npm) already exists — skipping creation"
|
msg_warn "LXC $id (hotel-manage-npm) already exists — skipping creation"
|
||||||
lxc_running "$id" || pct start "$id"
|
lxc_running "$id" || pct start "$id"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
local tmpl; tmpl=$(get_template)
|
local tmpl; tmpl=$(get_template)
|
||||||
pct create "$id" "$tmpl" \
|
pct create "$id" "$tmpl" \
|
||||||
--hostname "hnf-npm" \
|
--hostname "hotel-manage-npm" \
|
||||||
--memory 512 \
|
--memory 512 \
|
||||||
--cores 1 \
|
--cores 1 \
|
||||||
--rootfs "${STORAGE}:8" \
|
--rootfs "${STORAGE}:8" \
|
||||||
|
|
@ -283,6 +299,8 @@ create_npm_lxc() {
|
||||||
--features nesting=1 \
|
--features nesting=1 \
|
||||||
--unprivileged 0 \
|
--unprivileged 0 \
|
||||||
--onboot 1 \
|
--onboot 1 \
|
||||||
|
--tags "${POOL}" \
|
||||||
|
${POOL_OPT} \
|
||||||
--start 1 &>/dev/null
|
--start 1 &>/dev/null
|
||||||
sleep 5
|
sleep 5
|
||||||
}
|
}
|
||||||
|
|
@ -320,7 +338,7 @@ install_mgmt_key() {
|
||||||
push_file() {
|
push_file() {
|
||||||
# Write content to a temp file, push into LXC, remove temp
|
# Write content to a temp file, push into LXC, remove temp
|
||||||
local id=$1 dest=$2; shift 2
|
local id=$1 dest=$2; shift 2
|
||||||
local tmp; tmp=$(mktemp /tmp/hnf-push-XXXX)
|
local tmp; tmp=$(mktemp /tmp/hotel-manage-push-XXXX)
|
||||||
cat > "$tmp" # reads stdin
|
cat > "$tmp" # reads stdin
|
||||||
pct push "$id" "$tmp" "$dest" 2>/dev/null
|
pct push "$id" "$tmp" "$dest" 2>/dev/null
|
||||||
rm -f "$tmp"
|
rm -f "$tmp"
|
||||||
|
|
@ -329,14 +347,14 @@ push_file() {
|
||||||
push_dir() {
|
push_dir() {
|
||||||
# tar local dir → push tarball → extract in LXC at parent of dest
|
# tar local dir → push tarball → extract in LXC at parent of dest
|
||||||
local id=$1 src=$2 dest=$3
|
local id=$1 src=$2 dest=$3
|
||||||
local tmp; tmp=$(mktemp /tmp/hnf-dir-XXXX.tar.gz)
|
local tmp; tmp=$(mktemp /tmp/hotel-manage-dir-XXXX.tar.gz)
|
||||||
tar czf "$tmp" -C "$(dirname "$src")" "$(basename "$src")" 2>/dev/null
|
tar czf "$tmp" -C "$(dirname "$src")" "$(basename "$src")" 2>/dev/null
|
||||||
pct push "$id" "$tmp" /tmp/hnf-deploy.tar.gz 2>/dev/null
|
pct push "$id" "$tmp" /tmp/hotel-manage-deploy.tar.gz 2>/dev/null
|
||||||
pct exec "$id" -- bash -c "
|
pct exec "$id" -- bash -c "
|
||||||
mkdir -p '$(dirname "$dest")'
|
mkdir -p '$(dirname "$dest")'
|
||||||
tar xzf /tmp/hnf-deploy.tar.gz -C '$(dirname "$dest")'
|
tar xzf /tmp/hotel-manage-deploy.tar.gz -C '$(dirname "$dest")'
|
||||||
mv '$(dirname "$dest")/$(basename "$src")' '${dest}' 2>/dev/null || true
|
mv '$(dirname "$dest")/$(basename "$src")' '${dest}' 2>/dev/null || true
|
||||||
rm -f /tmp/hnf-deploy.tar.gz
|
rm -f /tmp/hotel-manage-deploy.tar.gz
|
||||||
" &>/dev/null
|
" &>/dev/null
|
||||||
rm -f "$tmp"
|
rm -f "$tmp"
|
||||||
}
|
}
|
||||||
|
|
@ -380,7 +398,7 @@ wait_healthy() {
|
||||||
wait_pg() {
|
wait_pg() {
|
||||||
local max=30 i=0
|
local max=30 i=0
|
||||||
while ! pct exec 100 -- bash -c \
|
while ! pct exec 100 -- bash -c \
|
||||||
"docker exec hnf-postgres pg_isready -U postgres" &>/dev/null; do
|
"docker exec hotel-manage-postgres pg_isready -U postgres" &>/dev/null; do
|
||||||
sleep 3; ((i++))
|
sleep 3; ((i++))
|
||||||
[[ $i -ge $max ]] && { msg_warn "Postgres not ready after 90s"; return 1; }
|
[[ $i -ge $max ]] && { msg_warn "Postgres not ready after 90s"; return 1; }
|
||||||
done
|
done
|
||||||
|
|
@ -407,7 +425,7 @@ deploy_postgres() {
|
||||||
push_file 100 /opt/postgres/docker-compose.yml <<'EOF'
|
push_file 100 /opt/postgres/docker-compose.yml <<'EOF'
|
||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
container_name: hnf-postgres
|
container_name: hotel-manage-postgres
|
||||||
image: postgres:16-alpine
|
image: postgres:16-alpine
|
||||||
environment:
|
environment:
|
||||||
- POSTGRES_USER=postgres
|
- POSTGRES_USER=postgres
|
||||||
|
|
@ -548,7 +566,7 @@ deploy_npm() {
|
||||||
push_file 103 /opt/npm/docker-compose.yml <<'EOF'
|
push_file 103 /opt/npm/docker-compose.yml <<'EOF'
|
||||||
services:
|
services:
|
||||||
npm:
|
npm:
|
||||||
container_name: hnf-npm
|
container_name: hotel-manage-npm
|
||||||
image: jc21/nginx-proxy-manager:latest
|
image: jc21/nginx-proxy-manager:latest
|
||||||
ports:
|
ports:
|
||||||
- "80:80"
|
- "80:80"
|
||||||
|
|
@ -591,8 +609,8 @@ deploy_management() {
|
||||||
|
|
||||||
# Copy the management SSH private key into management container
|
# Copy the management SSH private key into management container
|
||||||
pct exec 105 -- mkdir -p /root/.ssh
|
pct exec 105 -- mkdir -p /root/.ssh
|
||||||
pct push 105 /root/.ssh/hnf_management /root/.ssh/hnf_management &>/dev/null
|
pct push 105 /root/.ssh/hotel-manage_deploy /root/.ssh/hotel-manage_deploy &>/dev/null
|
||||||
pct exec 105 -- chmod 600 /root/.ssh/hnf_management
|
pct exec 105 -- chmod 600 /root/.ssh/hotel-manage_deploy
|
||||||
|
|
||||||
msg_info "Deploying management stack"
|
msg_info "Deploying management stack"
|
||||||
deploy_service 105 "management" "${REPO_ROOT}/management" /opt/management
|
deploy_service 105 "management" "${REPO_ROOT}/management" /opt/management
|
||||||
|
|
@ -742,7 +760,7 @@ print_summary() {
|
||||||
printf "\n${GN}"
|
printf "\n${GN}"
|
||||||
cat <<SUMMARY
|
cat <<SUMMARY
|
||||||
╔══════════════════════════════════════════════════════════════╗
|
╔══════════════════════════════════════════════════════════════╗
|
||||||
║ HNF Manage — Stack Deployed ║
|
║ Hotel Manage — Stack Deployed ║
|
||||||
╚══════════════════════════════════════════════════════════════╝
|
╚══════════════════════════════════════════════════════════════╝
|
||||||
SUMMARY
|
SUMMARY
|
||||||
printf "${CL}"
|
printf "${CL}"
|
||||||
|
|
@ -754,18 +772,18 @@ SUMMARY
|
||||||
|
|
||||||
── Services ──────────────────────────────────────────────────
|
── Services ──────────────────────────────────────────────────
|
||||||
LXC Hostname IP Port Status
|
LXC Hostname IP Port Status
|
||||||
100 hnf-postgres 10.10.10.100 5432 (internal only)
|
100 hotel-manage-postgres 10.10.10.100 5432 (internal only)
|
||||||
101 hnf-auth 10.10.10.101 3001 /api/auth/*
|
101 hotel-manage-auth 10.10.10.101 3001 /api/auth/*
|
||||||
102 hnf-portal 10.10.10.102 3000 /
|
102 hotel-manage-portal 10.10.10.102 3000 /
|
||||||
103 hnf-npm 10.10.10.3 80/443 entry point
|
103 hotel-manage-npm 10.10.10.3 80/443 entry point
|
||||||
(LAN) ${NPM_LAN_IP} 81 NPM admin
|
(LAN) ${NPM_LAN_IP} 81 NPM admin
|
||||||
105 hnf-management 10.10.10.105 3002 Uptime Kuma
|
105 hotel-manage-management 10.10.10.105 3002 Uptime Kuma
|
||||||
9000 Forgejo webhooks
|
9000 Forgejo webhooks
|
||||||
112 hnf-noticeboard 10.10.10.112 3080 /notices/
|
112 hotel-manage-noticeboard 10.10.10.112 3080 /notices/
|
||||||
|
|
||||||
── Credentials ───────────────────────────────────────────────
|
── Credentials ───────────────────────────────────────────────
|
||||||
Admin login: ${ADMIN_EMAIL}
|
Admin login: ${ADMIN_EMAIL}
|
||||||
Credentials: /root/hnf-credentials.txt (chmod 600)
|
Credentials: /root/hotel-manage-credentials.txt (chmod 600)
|
||||||
|
|
||||||
── Next steps ────────────────────────────────────────────────
|
── Next steps ────────────────────────────────────────────────
|
||||||
1. Point DNS: ${DOMAIN} → ${NPM_LAN_IP}
|
1. Point DNS: ${DOMAIN} → ${NPM_LAN_IP}
|
||||||
|
|
@ -800,6 +818,7 @@ check_vmbr1
|
||||||
collect_config
|
collect_config
|
||||||
gen_secrets
|
gen_secrets
|
||||||
gen_mgmt_ssh_key
|
gen_mgmt_ssh_key
|
||||||
|
ensure_pool
|
||||||
|
|
||||||
deploy_postgres
|
deploy_postgres
|
||||||
deploy_auth
|
deploy_auth
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue