- FastAPI-Backend mit vollständiger ABS v2.x API-Kompatibilität - SQLAlchemy-Models: User, Library, LibraryItem, BookFile, Chapter, Podcast, PodcastEpisode, MediaProgress, Bookmark, PlaybackSession - Auth: JWT-Login (/login, /logout, /api/authorize) - Library + Items Endpoints inkl. camelCase ABS-Response-Format - HLS-Streaming via FFmpeg (POST /api/items/:id/play, Session-Sync) - Me/Progress Endpoints + Lesezeichen - User-Management + Server-Settings (Admin) - Library-Scanner (MP3/WAV Discovery, Hintergrund-Task) - File Watcher (watchdog, 30s Debounce) - Matching-Skelett (MusicBrainz, OpenLibrary, Google Books – Phase 5) - Docker-Setup: backend (Python 3.12+FFmpeg), frontend (React/Vite), nginx Reverse-Proxy auf Port 3000 - setup.sh: Installiert Docker auf Debian/Ubuntu, richtet .env ein Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
127 lines
6.0 KiB
Bash
127 lines
6.0 KiB
Bash
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
|
||
# ─────────────────────────────────────────────────────────────────────────────
|
||
# Audiolib – Setup-Skript
|
||
# Läuft auf Debian/Ubuntu-basierten Systemen (inkl. Proxmox LXC, Raspberry Pi)
|
||
# ─────────────────────────────────────────────────────────────────────────────
|
||
|
||
BOLD="\033[1m"
|
||
GREEN="\033[32m"
|
||
YELLOW="\033[33m"
|
||
RED="\033[31m"
|
||
RESET="\033[0m"
|
||
|
||
info() { echo -e "${GREEN}[OK]${RESET} $*"; }
|
||
warn() { echo -e "${YELLOW}[WARN]${RESET} $*"; }
|
||
error() { echo -e "${RED}[FEHLER]${RESET} $*" >&2; exit 1; }
|
||
header() { echo -e "\n${BOLD}$*${RESET}"; }
|
||
|
||
# ── Root-Check ────────────────────────────────────────────────────────────────
|
||
if [[ $EUID -ne 0 ]]; then
|
||
error "Bitte als root ausführen: sudo bash setup.sh"
|
||
fi
|
||
|
||
header "━━━ Audiolib Setup ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
||
# ── Docker installieren ───────────────────────────────────────────────────────
|
||
header "1/4 · Docker prüfen / installieren"
|
||
|
||
if command -v docker &>/dev/null; then
|
||
DOCKER_VERSION=$(docker --version | awk '{print $3}' | tr -d ',')
|
||
info "Docker bereits installiert: $DOCKER_VERSION"
|
||
else
|
||
warn "Docker nicht gefunden – installiere Docker..."
|
||
apt-get update -qq
|
||
apt-get install -y -qq ca-certificates curl gnupg lsb-release
|
||
|
||
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
|
||
|
||
DISTRO=$(lsb_release -si | tr '[:upper:]' '[:lower:]')
|
||
# Ubuntu-Basis (z.B. Mint) als ubuntu behandeln
|
||
[[ "$DISTRO" == "ubuntu" || "$DISTRO" == "linuxmint" ]] && DISTRO="ubuntu" || DISTRO="debian"
|
||
|
||
echo \
|
||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
|
||
https://download.docker.com/linux/${DISTRO} \
|
||
$(lsb_release -cs) 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 --now docker
|
||
info "Docker installiert: $(docker --version)"
|
||
fi
|
||
|
||
# ── Docker Compose prüfen ─────────────────────────────────────────────────────
|
||
if docker compose version &>/dev/null; then
|
||
info "Docker Compose Plugin verfügbar: $(docker compose version --short)"
|
||
elif command -v docker-compose &>/dev/null; then
|
||
warn "Altes docker-compose gefunden. Empfehle: apt install docker-compose-plugin"
|
||
# Alias damit der Rest des Skripts 'docker compose' nutzen kann
|
||
shopt -s expand_aliases
|
||
alias docker\ compose='docker-compose'
|
||
else
|
||
error "Docker Compose nicht gefunden. Bitte manuell installieren."
|
||
fi
|
||
|
||
# ── .env einrichten ───────────────────────────────────────────────────────────
|
||
header "2/4 · Konfiguration (.env)"
|
||
|
||
if [[ -f .env ]]; then
|
||
warn ".env existiert bereits – wird nicht überschrieben."
|
||
warn "Bitte manuell prüfen: nano .env"
|
||
else
|
||
cp .env.example .env
|
||
|
||
# Zufälligen JWT_SECRET generieren
|
||
JWT_SECRET=$(openssl rand -hex 32 2>/dev/null || cat /dev/urandom | tr -dc 'a-f0-9' | head -c 64)
|
||
sed -i "s|JWT_SECRET=change_me_in_production_use_a_long_random_string|JWT_SECRET=${JWT_SECRET}|" .env
|
||
|
||
info ".env angelegt mit zufälligem JWT_SECRET."
|
||
echo ""
|
||
echo -e " ${YELLOW}WICHTIG: Bitte jetzt .env öffnen und anpassen:${RESET}"
|
||
echo -e " ${BOLD}nano .env${RESET}"
|
||
echo ""
|
||
echo " Mindestens setzen:"
|
||
echo " ADMIN_PASSWORD=<sicheres_passwort>"
|
||
echo " AUDIOFILES_PATH=<pfad_zu_deinen_audiodateien>"
|
||
echo ""
|
||
fi
|
||
|
||
# ── Verzeichnisse anlegen ─────────────────────────────────────────────────────
|
||
header "3/4 · Verzeichnisse anlegen"
|
||
|
||
mkdir -p data/db data/covers data/hls_cache data/logs
|
||
info "data/-Verzeichnisse erstellt."
|
||
|
||
# audiofiles-Verzeichnis nur anlegen wenn AUDIOFILES_PATH auf ./audiofiles zeigt
|
||
if grep -q "^AUDIOFILES_PATH=\./audiofiles" .env 2>/dev/null; then
|
||
mkdir -p audiofiles
|
||
warn "audiofiles/ angelegt. Audiodateien dort ablegen oder AUDIOFILES_PATH in .env anpassen."
|
||
fi
|
||
|
||
# ── Berechtigungen ────────────────────────────────────────────────────────────
|
||
# Docker läuft normalerweise als root im Container, data-Ordner für alle beschreibbar
|
||
chmod -R 777 data/ 2>/dev/null || true
|
||
|
||
# ── Fertig ────────────────────────────────────────────────────────────────────
|
||
header "4/4 · Bereit zum Starten"
|
||
|
||
echo ""
|
||
echo -e "${BOLD}Setup abgeschlossen.${RESET} Nächste Schritte:"
|
||
echo ""
|
||
echo -e " 1. ${YELLOW}nano .env${RESET} ← ADMIN_PASSWORD und AUDIOFILES_PATH setzen"
|
||
echo ""
|
||
echo -e " 2. ${BOLD}docker compose up -d --build${RESET}"
|
||
echo ""
|
||
echo -e " 3. Audiobookshelf-App öffnen → Server-URL:"
|
||
echo -e " ${BOLD}http://$(hostname -I | awk '{print $1}'):3000${RESET}"
|
||
echo ""
|
||
echo -e " Logs anzeigen: ${BOLD}docker compose logs -f backend${RESET}"
|
||
echo -e " Stoppen: ${BOLD}docker compose down${RESET}"
|
||
echo ""
|