Files
playwish/install/install-server.sh
99admandClaude Opus 5.5 fc15f2b933 Umbenennung: Audiofy heißt jetzt Playwish
Name, Seitentitel, Dienste (playwish-web, playwish-controller), Dienst-Benutzer
(playwish), Pfade (/opt/playwish, /usr/local/src/playwish), Vorlagen und
Repository-Adresse. „Audiofy“ war bereits von mehreren Produkten belegt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 20:27:59 +01:00

171 lines
8.1 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# Playwish – Installation der Rolle "Server": Website für Gäste, Admin-Bereich, Player-API.
#
# install/install-server.sh Neuinstallation (fragt alles Nötige ab)
# install/install-server.sh --update nur Code, Python-Umgebung und Dienst aktualisieren
#
# Voraussetzungen: Debian 12+ (oder abgeleitet), eine (Sub-)Domain, deren A/AAAA-Record
# auf diesen Rechner zeigt, und offene Ports 80/443 (auch in einer Cloud-Firewall).
set -euo pipefail
source "$(dirname "$0")/lib.sh"
UPDATE=0
for arg in "$@"; do
case "$arg" in
--update) UPDATE=1 ;;
-h|--help) sed -n '2,9p' "$0"; exit 0 ;;
*) abbruch "Unbekannte Option: $arg" ;;
esac
done
ENV_DATEI="$PLAYWISH_DIR/.env"
export PLAYWISH_DIR PLAYWISH_USER
export APP_PORT="${APP_PORT:-8000}"
schritt "Playwish-Server: $([ $UPDATE = 1 ] && echo Update || echo Neuinstallation)"
pruefe_system
if [ $UPDATE = 1 ] && ! $SUDO test -f "$ENV_DATEI"; then
abbruch "Keine bestehende Installation in $PLAYWISH_DIR gefunden – ohne --update ausführen."
fi
# ------------------------------------------------------------------ Abfragen
if [ $UPDATE = 0 ]; then
schritt "Angaben"
frage DOMAIN "Domain der Website (z. B. musik.example.org)"
[ -n "$DOMAIN" ] || abbruch "Ohne Domain geht es nicht (HTTPS über Let's Encrypt)."
frage ACME_EMAIL "E-Mail für Let's Encrypt (Ablaufwarnungen)"
info "Spotify-App (developer.spotify.com): Redirect-URI http://127.0.0.1:8888/callback eintragen."
frage SPOTIFY_CLIENT_ID "Spotify Client ID"
frage_geheim SPOTIFY_CLIENT_SECRET "Spotify Client Secret (verdeckt)"
frage PLAYLIST "Grund-Playlist (Link oder ID, später im Admin änderbar)"
PLAYLIST_ID="$(sed -E 's#.*playlist[/:]([A-Za-z0-9]{22}).*#\1#' <<<"$PLAYLIST")"
if [ -n "$PLAYLIST_ID" ] && ! [[ "$PLAYLIST_ID" =~ ^[A-Za-z0-9]{22}$ ]]; then
warnung "Das sieht nicht nach einer Playlist aus – bitte später im Admin-Bereich eintragen."
PLAYLIST_ID=""
fi
# alle Ports, auf denen SSH lauscht, plus den der aktuellen Sitzung – damit sich niemand aussperrt
SSH_PORTS="$( { ${SUDO} sshd -T 2>/dev/null | awk '/^port /{print $2}'; [ -n "${SSH_CONNECTION:-}" ] && awk '{print $4}' <<<"$SSH_CONNECTION"; } | sort -un | tr '\n' ' ')"
SSH_PORTS="${SSH_PORTS:-22}"
SSH_PORT="${SSH_PORTS%% *}" # für fail2ban: erster Port
ja_nein "Firewall (ufw) einrichten? Erlaubt SSH (Port ${SSH_PORTS% }), 80 und 443" j && FIREWALL=1 || FIREWALL=0
ja_nein "fail2ban für SSH einrichten?" j && FAIL2BAN=1 || FAIL2BAN=0
ja_nein "Automatische Sicherheitsupdates aktivieren?" j && AUTOUPDATE=1 || AUTOUPDATE=0
export DOMAIN ACME_EMAIL SSH_PORT
fi
# ------------------------------------------------------------------ Pakete
schritt "Pakete"
$SUDO apt-get update -qq
PAKETE=(python3-venv sqlite3 caddy curl)
if [ $UPDATE = 0 ]; then
[ $FIREWALL = 1 ] && PAKETE+=(ufw)
[ $FAIL2BAN = 1 ] && PAKETE+=(fail2ban python3-systemd)
[ $AUTOUPDATE = 1 ] && PAKETE+=(unattended-upgrades)
fi
pakete "${PAKETE[@]}"
# ------------------------------------------------------------------ Benutzer, Ordner, Code
schritt "Dienst-Benutzer, Ordner und Code"
dienst_benutzer
$SUDO install -d -o root -g "$PLAYWISH_USER" -m 750 "$PLAYWISH_DIR"
$SUDO install -d -o "$PLAYWISH_USER" -g "$PLAYWISH_USER" -m 700 "$PLAYWISH_DIR/data"
code_kopieren "$REPO/server" "$PLAYWISH_DIR/app"
$SUDO install -o root -g "$PLAYWISH_USER" -m 640 "$REPO/player/auth.py" "$PLAYWISH_DIR/app/auth.py"
venv_einrichten "$PLAYWISH_DIR/app/requirements.txt"
info "Code in $PLAYWISH_DIR/app, Python-Umgebung in $PLAYWISH_DIR/.venv"
# ------------------------------------------------------------------ Konfiguration
schritt "Konfiguration ($ENV_DATEI)"
$SUDO test -f "$ENV_DATEI" || $SUDO install -o "$PLAYWISH_USER" -g "$PLAYWISH_USER" -m 600 /dev/null "$ENV_DATEI"
VERWALTUNG=("${ALS_DIENST[@]}" "$PLAYWISH_DIR/.venv/bin/python" "$PLAYWISH_DIR/app/verwaltung.py")
"${VERWALTUNG[@]}" geheimnisse --env "$ENV_DATEI" | sed 's/^/ /'
if [ $UPDATE = 0 ]; then
env_setzen "$ENV_DATEI" DB_PATH "$PLAYWISH_DIR/data/playwish.db"
env_setzen "$ENV_DATEI" PUBLIC_URL "https://$DOMAIN"
env_setzen "$ENV_DATEI" SPOTIFY_CLIENT_ID "$SPOTIFY_CLIENT_ID"
env_setzen "$ENV_DATEI" SPOTIFY_CLIENT_SECRET "$SPOTIFY_CLIENT_SECRET"
[ -n "$PLAYLIST_ID" ] && env_setzen "$ENV_DATEI" SPOTIFY_PLAYLIST_ID "$PLAYLIST_ID"
unset SPOTIFY_CLIENT_SECRET
schritt "Spotify-Login für die Suche"
info "Öffne gleich die angezeigte Adresse im Browser, melde dich an und füge danach die"
info "Adresse aus der Adresszeile (http://127.0.0.1:8888/callback?...) hier ein."
if ja_nein "Jetzt anmelden?" j; then
"${ALS_DIENST[@]}" "$PLAYWISH_DIR/.venv/bin/python" "$PLAYWISH_DIR/app/auth.py" --profil server --env "$ENV_DATEI" \
|| warnung "Login fehlgeschlagen – später nachholen (siehe README)."
fi
schritt "Admin-Passwort"
"${VERWALTUNG[@]}" passwort --env "$ENV_DATEI" || warnung "Kein Passwort gesetzt – später nachholen (siehe README)."
if ja_nein "Cloudflare Turnstile (Bot-Schutz für Login und Wünsche) einrichten?" n; then
"${VERWALTUNG[@]}" turnstile --env "$ENV_DATEI" || warnung "Turnstile nicht eingerichtet."
fi
fi
# ------------------------------------------------------------------ Dienst
schritt "Dienst playwish-web"
vorlage playwish-web.service /etc/systemd/system/playwish-web.service
$SUDO systemctl daemon-reload
$SUDO systemctl enable playwish-web >/dev/null 2>&1
$SUDO systemctl restart playwish-web
sleep 3
systemctl is-active --quiet playwish-web || abbruch "playwish-web läuft nicht – siehe: journalctl -u playwish-web"
curl -fsS "http://127.0.0.1:$APP_PORT/healthz" >/dev/null && info "playwish-web läuft"
# ------------------------------------------------------------------ Caddy & Schutz (nur Neuinstallation)
if [ $UPDATE = 0 ]; then
schritt "Caddy (HTTPS)"
if $SUDO grep -q "Playwish" /etc/caddy/Caddyfile 2>/dev/null || $SUDO grep -q "/usr/share/caddy" /etc/caddy/Caddyfile 2>/dev/null; then
vorlage Caddyfile /etc/caddy/Caddyfile
$SUDO caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile >/dev/null 2>&1 || abbruch "Caddyfile ungültig"
$SUDO systemctl enable caddy >/dev/null 2>&1
$SUDO systemctl reload-or-restart caddy
info "Caddy holt das Zertifikat für $DOMAIN (dauert ein paar Sekunden)."
else
warnung "/etc/caddy/Caddyfile enthält schon eine eigene Konfiguration – nicht verändert."
warnung "Bitte einen Block für $DOMAIN mit 'reverse_proxy 127.0.0.1:$APP_PORT' ergänzen (Vorlage: install/vorlagen/Caddyfile)."
fi
if [ $FIREWALL = 1 ]; then
schritt "Firewall (ufw)"
$SUDO ufw default deny incoming >/dev/null
$SUDO ufw default allow outgoing >/dev/null
for p in $SSH_PORTS; do $SUDO ufw allow "$p/tcp" comment "SSH" >/dev/null; done
$SUDO ufw allow 80/tcp comment "HTTP (Caddy/ACME)" >/dev/null
$SUDO ufw allow 443/tcp comment "HTTPS (Caddy)" >/dev/null
$SUDO ufw --force enable >/dev/null
info "ufw aktiv: SSH ${SSH_PORTS% }, 80, 443"
fi
if [ $FAIL2BAN = 1 ]; then
schritt "fail2ban"
vorlage fail2ban-playwish.conf /etc/fail2ban/jail.d/playwish.conf
$SUDO systemctl enable fail2ban >/dev/null 2>&1
$SUDO systemctl restart fail2ban
info "SSH-Schutz auf Port $SSH_PORT aktiv"
fi
if [ $AUTOUPDATE = 1 ]; then
schritt "Automatische Sicherheitsupdates"
vorlage 20auto-upgrades /etc/apt/apt.conf.d/20auto-upgrades
info "aktiviert"
fi
schritt "Logs begrenzen"
$SUDO install -d /etc/systemd/journald.conf.d
vorlage journald-10-playwish.conf /etc/systemd/journald.conf.d/10-playwish.conf
$SUDO systemctl restart systemd-journald
info "journald max. 200 MB"
fi
# ------------------------------------------------------------------ Zusammenfassung
schritt "Fertig"
URL="$(env_wert "$ENV_DATEI" PUBLIC_URL)"
info "Website: $URL (Gäste nur mit Einladungslink/QR-Code)"
info "Admin: $URL/admin"
info "Logs: journalctl -u playwish-web -f"
if [ $UPDATE = 0 ]; then
info ""
info "Für die Player-Installation brauchst du:"
info " Server-Adresse: $URL"
info " Player-Token: sudo -u $PLAYWISH_USER grep PLAYER_API_TOKEN $ENV_DATEI"
info "Gastzugang ist anfangs aus – im Admin unter „Gäste“ einschalten."
fi