Files
ha-performance-fix/setup-guacamole-lxc.sh
T

208 lines
6.3 KiB
Bash

#!/bin/bash
# =====================================================================
# Apache Guacamole LXC Setup for Proxmox (Docker-based)
# =====================================================================
# Migrates Guacamole from a Home Assistant add-on to a dedicated
# LXC container on Proxmox. Guacamole was using 25% CPU and 9% RAM
# inside the HAOS VM — this frees those resources.
#
# Run this script on the Proxmox host (HAL-HOST / 10.0.0.240) as root.
#
# Network:
# - Proxmox host: 10.0.0.240
# - HAOS VM: 10.0.0.55
# - OPNsense: 10.0.0.254
# - AdGuard LXC: 10.0.0.224 (CT 120)
# - Guacamole LXC: 10.0.0.225 (CT 121)
# - NPM LXC: 10.0.0.226 (CT 122)
# =====================================================================
set -euo pipefail
# --- Configuration ---
CT_ID="121"
CT_NAME="guacamole"
CT_IP="10.0.0.225/24"
CT_GW="10.0.0.254"
CT_STORAGE="local-lvm"
CT_TEMPLATE="local:vztmpl/debian-12-standard_12.12-1_amd64.tar.zst"
CT_MEMORY=1024
CT_SWAP=256
CT_CORES=2
CT_DISK="8"
BRIDGE="vmbr0"
GUAC_DB_PASSWORD="$(openssl rand -hex 16 2>/dev/null || echo "ChangeMe_$(date +%s)")"
echo "============================================"
echo " Apache Guacamole LXC Setup"
echo " Container ID: ${CT_ID}"
echo " IP Address: ${CT_IP}"
echo "============================================"
# --- Check if template exists ---
if ! pveam list local | grep -q "debian-12-standard"; then
echo "[1/8] Downloading Debian 12 template..."
pveam download local debian-12-standard_12.12-1_amd64.tar.zst
else
echo "[1/8] Debian 12 template already available"
fi
# --- Create the container ---
echo "[2/8] Creating LXC container ${CT_ID}..."
pct create "${CT_ID}" "${CT_TEMPLATE}" \
--hostname "${CT_NAME}" \
--memory "${CT_MEMORY}" \
--swap "${CT_SWAP}" \
--cores "${CT_CORES}" \
--rootfs "${CT_STORAGE}:${CT_DISK}" \
--net0 "name=eth0,bridge=${BRIDGE},ip=${CT_IP},gw=${CT_GW},firewall=0" \
--nameserver "10.0.0.224" \
--onboot 1 \
--start 1 \
--unprivileged 1 \
--features "nesting=1,keyctl=1" \
--startup "order=3,up=15"
echo "[3/8] Waiting for container to start..."
sleep 5
# --- Install Docker inside the container ---
echo "[4/8] Installing Docker..."
pct exec "${CT_ID}" -- bash -c '
apt-get update -qq
apt-get install -y -qq ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" > /etc/apt/sources.list.d/docker.list
apt-get update -qq
apt-get install -y -qq docker-ce docker-ce-cli containerd.io docker-compose-plugin
systemctl enable docker
systemctl start docker
'
# --- Create Docker Compose config ---
echo "[5/8] Creating Guacamole Docker Compose configuration..."
pct exec "${CT_ID}" -- bash -c "
mkdir -p /opt/guacamole
cat > /opt/guacamole/docker-compose.yml << DCEOF
services:
guacd:
image: guacamole/guacd:latest
container_name: guacd
restart: unless-stopped
networks:
- guac-net
postgres:
image: postgres:15-alpine
container_name: guac-postgres
restart: unless-stopped
environment:
POSTGRES_DB: guacamole_db
POSTGRES_USER: guacamole_user
POSTGRES_PASSWORD: ${GUAC_DB_PASSWORD}
volumes:
- postgres-data:/var/lib/postgresql/data
- /opt/guacamole/initdb:/docker-entrypoint-initdb.d
networks:
- guac-net
guacamole:
image: guacamole/guacamole:latest
container_name: guacamole
restart: unless-stopped
depends_on:
- guacd
- postgres
environment:
GUACD_HOSTNAME: guacd
POSTGRESQL_HOSTNAME: postgres
POSTGRESQL_DATABASE: guacamole_db
POSTGRESQL_USER: guacamole_user
POSTGRESQL_PASSWORD: ${GUAC_DB_PASSWORD}
ports:
- '8080:8080'
networks:
- guac-net
networks:
guac-net:
driver: bridge
volumes:
postgres-data:
DCEOF
"
# --- Generate the database init script ---
echo "[6/8] Generating database initialisation schema..."
pct exec "${CT_ID}" -- bash -c '
mkdir -p /opt/guacamole/initdb
docker pull guacamole/guacamole:latest -q
docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --postgresql > /opt/guacamole/initdb/001-init.sql
echo "Database schema extracted successfully"
'
# --- Start the stack ---
echo "[7/8] Starting Guacamole stack..."
pct exec "${CT_ID}" -- bash -c '
cd /opt/guacamole
docker compose up -d
echo "Waiting for services to initialise..."
sleep 15
docker compose ps
'
# --- Create systemd service for auto-start ---
echo "[8/8] Creating systemd service for auto-start..."
pct exec "${CT_ID}" -- bash -c '
cat > /etc/systemd/system/guacamole.service << "SVCEOF"
[Unit]
Description=Apache Guacamole Docker Stack
Requires=docker.service
After=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/guacamole
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
TimeoutStartSec=120
[Install]
WantedBy=multi-user.target
SVCEOF
systemctl daemon-reload
systemctl enable guacamole.service
'
CT_IP_CLEAN=$(echo "${CT_IP}" | cut -d'/' -f1)
echo ""
echo "============================================"
echo " Apache Guacamole LXC setup complete!"
echo "============================================"
echo ""
echo " Web UI: http://${CT_IP_CLEAN}:8080/guacamole/"
echo " Default: guacadmin / guacadmin (CHANGE IMMEDIATELY)"
echo " DB Pass: ${GUAC_DB_PASSWORD}"
echo ""
echo " MIGRATION STEPS:"
echo " 1. Login at http://${CT_IP_CLEAN}:8080/guacamole/"
echo " 2. Change admin password immediately"
echo " 3. Re-create RDP connections (Settings > Connections)"
echo " 4. Set up NPM proxy (10.0.0.226):"
echo " guac.hideawaygaming.com.au -> http://${CT_IP_CLEAN}:8080"
echo " Enable WebSocket support (critical for RDP)"
echo " 5. Test all RDP connections"
echo " 6. Stop HA Guacamole add-on"
echo ""
echo " Docker management:"
echo " pct exec ${CT_ID} -- docker compose -f /opt/guacamole/docker-compose.yml logs -f"
echo " pct exec ${CT_ID} -- docker compose -f /opt/guacamole/docker-compose.yml restart"
echo "============================================"