Files
playbull/deploy/install-homelab.sh
Mike 94b6cc3be9 Initial PlayBull release with Trilogy Hub integration.
Includes homelab deploy tooling, image position/zoom manifest persistence, and full trading/casino stack.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-02 08:31:36 +02:00

213 lines
8.0 KiB
Bash

#!/usr/bin/env bash
# PlayBull Homelab-Installer — Ziel: ~/bestewebsite/bestewebsite
# DuckDNS + playbull.service + Cloudflare Tunnel (cloudflared service install)
set -euo pipefail
if [[ "${EUID}" -ne 0 ]]; then
echo "Bitte als root ausfuehren: sudo bash deploy/install-homelab.sh" >&2
exit 1
fi
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
if [[ ! -f "${SCRIPT_DIR}/env.homelab" ]]; then
cp "${SCRIPT_DIR}/env.homelab.example" "${SCRIPT_DIR}/env.homelab"
echo "deploy/env.homelab erstellt — Token eintragen und erneut starten." >&2
exit 1
fi
# shellcheck source=/dev/null
source <(sed 's/\r$//' "${SCRIPT_DIR}/env.homelab")
APP_PORT="${APP_PORT:-3080}"
APP_DIR="${APP_DIR:-/home/gizzler/bestewebsite/bestewebsite}"
APP_DIR="${APP_DIR//$'\r'/}"
APP_USER="${APP_USER:-gizzler}"
APP_USER="${APP_USER//$'\r'/}"
DUCKDNS_DOMAIN="${DUCKDNS_DOMAIN//$'\r'/}"
DUCKDNS_TOKEN="${DUCKDNS_TOKEN//$'\r'/}"
APP_DOMAIN="${APP_DOMAIN:-trilogyhub.de}"
APP_DOMAIN="${APP_DOMAIN//$'\r'/}"
CLOUDFLARE_API_TOKEN="${CLOUDFLARE_API_TOKEN//$'\r'/}"
CLOUDFLARE_ZONE_ID="${CLOUDFLARE_ZONE_ID//$'\r'/}"
CLOUDFLARE_TUNNEL_TOKEN="${CLOUDFLARE_TUNNEL_TOKEN//$'\r'/}"
JWT_SECRET="${JWT_SECRET//$'\r'/}"
FINNHUB_API_KEY="${FINNHUB_API_KEY//$'\r'/}"
echo "==> PlayBull / Trilogy Hub Homelab Setup"
echo " Domain: ${APP_DOMAIN}"
echo " Port: ${APP_PORT}"
echo " Pfad: ${APP_DIR}"
echo ""
install_unit() {
local src="$1" dest="$2"
sed -e "s|__APP_DIR__|${APP_DIR}|g" \
-e "s|__APP_USER__|${APP_USER}|g" \
"${src}" > "${dest}"
}
need_pkg() { command -v "$1" >/dev/null 2>&1; }
if [[ "${SKIP_APT:-0}" != "1" ]] && command -v apt-get >/dev/null 2>&1; then
echo "==> Paketlisten aktualisieren..."
apt-get update -qq
PKGS=(curl ca-certificates rsync build-essential libvips-dev)
MISSING=()
for p in "${PKGS[@]}"; do need_pkg "$p" || MISSING+=("$p"); done
if ((${#MISSING[@]})); then
apt-get install -y "${MISSING[@]}"
fi
elif [[ "${SKIP_APT:-0}" != "1" ]] && command -v dnf >/dev/null 2>&1; then
dnf install -y curl ca-certificates rsync gcc-c++ make vips-devel
fi
if ! command -v cloudflared >/dev/null 2>&1; then
echo "==> cloudflared installieren"
ARCH="$(uname -m)"
case "${ARCH}" in
x86_64) CF_ARCH=amd64 ;;
aarch64|arm64) CF_ARCH=arm64 ;;
*) echo "Unsupported arch: ${ARCH}" >&2; exit 1 ;;
esac
curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${CF_ARCH}" \
-o /usr/local/bin/cloudflared
chmod +x /usr/local/bin/cloudflared
ln -sf /usr/local/bin/cloudflared /usr/bin/cloudflared
fi
if ! command -v node >/dev/null 2>&1 || [[ "$(node -p "process.versions.node.split('.')[0]")" -lt 24 ]]; then
echo "==> Node.js 24 installieren (NodeSource)"
if command -v apt-get >/dev/null 2>&1; then
curl -fsSL https://deb.nodesource.com/setup_24.x | bash -
apt-get install -y nodejs
else
dnf install -y nodejs
fi
fi
mkdir -p "${APP_DIR}" "${APP_DIR}/data" "${APP_DIR}/public/uploads"
if [[ "${REPO_ROOT}" != "${APP_DIR}" ]]; then
echo "==> Dateien nach ${APP_DIR} synchronisieren"
rsync -a --delete \
--exclude node_modules \
--exclude data \
--exclude .git \
--exclude server.js \
--exclude server.py \
--exclude start.bat \
"${REPO_ROOT}/" "${APP_DIR}/"
fi
chown -R "${APP_USER}:${APP_USER}" "${APP_DIR}" 2>/dev/null || true
chmod +x "${APP_DIR}/deploy/duckdns-update.sh" \
"${APP_DIR}/deploy/cloudflare-ddns-update.sh" \
"${APP_DIR}/deploy/finish-on-server.sh" \
"${APP_DIR}/deploy/sync-user.sh" 2>/dev/null || true
# ---- .env (nur ergaenzen, nicht ueberschreiben) ----
ENV_FILE="${APP_DIR}/.env"
touch "${ENV_FILE}"
grep -q '^PORT=' "${ENV_FILE}" 2>/dev/null \
&& sed -i "s/^PORT=.*/PORT=${APP_PORT}/" "${ENV_FILE}" \
|| echo "PORT=${APP_PORT}" >> "${ENV_FILE}"
grep -q '^TRUST_PROXY=' "${ENV_FILE}" 2>/dev/null || echo "TRUST_PROXY=1" >> "${ENV_FILE}"
grep -q '^START_BALANCE=' "${ENV_FILE}" 2>/dev/null || echo "START_BALANCE=10000" >> "${ENV_FILE}"
grep -q '^JWT_SECRET=' "${ENV_FILE}" 2>/dev/null || { [[ -n "${JWT_SECRET:-}" ]] && echo "JWT_SECRET=${JWT_SECRET}" >> "${ENV_FILE}"; }
grep -q '^FINNHUB_API_KEY=' "${ENV_FILE}" 2>/dev/null || { [[ -n "${FINNHUB_API_KEY:-}" ]] && echo "FINNHUB_API_KEY=${FINNHUB_API_KEY}" >> "${ENV_FILE}"; }
if [[ "${APP_USER}" == "root" ]]; then
bash -c "cd '${APP_DIR}' && npm install --omit=dev"
else
sudo -u "${APP_USER}" bash -c "cd '${APP_DIR}' && npm install --omit=dev"
fi
# ---- Alten bestewebsite-Service abloesen ----
if systemctl is-active --quiet bestewebsite.service 2>/dev/null; then
echo "==> bestewebsite.service stoppen (Migration zu playbull)"
systemctl stop bestewebsite.service
fi
systemctl disable bestewebsite.service 2>/dev/null || true
# ---- Cloudflare Tunnel (wie bestewebsite: cloudflared service install) ----
if [[ -n "${CLOUDFLARE_TUNNEL_TOKEN:-}" ]]; then
echo "==> Cloudflare Tunnel"
systemctl stop cloudflared-playbull.service 2>/dev/null || true
systemctl disable cloudflared-playbull.service 2>/dev/null || true
cloudflared service uninstall 2>/dev/null || true
cloudflared service install "${CLOUDFLARE_TUNNEL_TOKEN}"
systemctl enable cloudflared
systemctl restart cloudflared
echo " cloudflared gestartet."
else
echo ""
echo ">>> CLOUDFLARE_TUNNEL_TOKEN fehlt in deploy/env.homelab"
echo " Zero Trust → Tunnel → Public Hostname: ${APP_DOMAIN} -> http://127.0.0.1:${APP_PORT}"
echo ""
fi
# ---- Cloudflare Dynamic DNS (ersetzt DuckDNS) ----
echo "==> Cloudflare DDNS Timer"
install_unit "${APP_DIR}/deploy/systemd/cloudflare-ddns-update.service" /etc/systemd/system/cloudflare-ddns-update.service
cp "${APP_DIR}/deploy/systemd/cloudflare-ddns-update.timer" /etc/systemd/system/
chmod 600 "${APP_DIR}/deploy/env.homelab"
if [[ -n "${CLOUDFLARE_API_TOKEN:-}" && -n "${CLOUDFLARE_ZONE_ID:-}" ]]; then
"${APP_DIR}/deploy/cloudflare-ddns-update.sh" || echo " Cloudflare-DDNS fehlgeschlagen (API/Zone pruefen)"
else
echo " Cloudflare-DDNS uebersprungen (CLOUDFLARE_API_TOKEN oder ZONE_ID leer)"
fi
# ---- DuckDNS (legacy, optional) ----
if [[ -n "${DUCKDNS_TOKEN:-}" ]]; then
echo "==> DuckDNS (legacy)"
install_unit "${APP_DIR}/deploy/systemd/duckdns-update.service" /etc/systemd/system/duckdns-update.service
cp "${APP_DIR}/deploy/systemd/duckdns-update.timer" /etc/systemd/system/
"${APP_DIR}/deploy/duckdns-update.sh" || true
fi
# ---- playbull systemd ----
echo "==> playbull.service"
install_unit "${APP_DIR}/deploy/systemd/playbull.service" /etc/systemd/system/playbull.service
systemctl daemon-reload
if [[ -n "${CLOUDFLARE_API_TOKEN:-}" && -n "${CLOUDFLARE_ZONE_ID:-}" ]]; then
systemctl enable --now cloudflare-ddns-update.timer
systemctl start cloudflare-ddns-update.service || true
else
systemctl disable cloudflare-ddns-update.timer 2>/dev/null || true
fi
if [[ -n "${DUCKDNS_TOKEN:-}" ]]; then
systemctl enable --now duckdns-update.timer
systemctl start duckdns-update.service || true
else
systemctl disable duckdns-update.timer 2>/dev/null || true
fi
systemctl enable --now playbull.service
systemctl restart playbull.service
# ---- Optional Nginx ----
if [[ "${USE_NGINX_VHOST:-0}" == "1" ]]; then
echo "==> Nginx VHost (optional)"
if command -v apt-get >/dev/null 2>&1; then
apt-get install -y nginx certbot python3-certbot-nginx
fi
cp "${APP_DIR}/deploy/nginx/playbull.conf" /etc/nginx/sites-available/playbull
ln -sf /etc/nginx/sites-available/playbull /etc/nginx/sites-enabled/playbull
certbot --nginx -d "${APP_DOMAIN}" -d "www.${APP_DOMAIN}" --non-interactive --agree-tos -m "admin@${APP_DOMAIN}" || true
nginx -t && systemctl reload nginx
fi
echo ""
echo "=== Fertig ==="
echo "Pfad: ${APP_DIR}"
echo "Intern: http://127.0.0.1:${APP_PORT}"
echo "DuckDNS: ${DUCKDNS_DOMAIN:-(deaktiviert)}"
echo "Status: systemctl status playbull cloudflared cloudflare-ddns-update.timer"
if [[ -n "${CLOUDFLARE_TUNNEL_TOKEN:-}" ]]; then
echo "HTTPS: https://${APP_DOMAIN}"
fi
echo ""
echo "Hinweis: JWT_SECRET und FINNHUB_API_KEY in ${ENV_FILE} pruefen, dann:"
echo " sudo systemctl restart playbull"