#!/usr/bin/env bash # # Project-Good – Installer für selfhostbare Lebensmittel-Lagerverwaltung. # Installiert bei Bedarf Docker und startet den kompletten Stack via Docker Compose. # # Nutzung: # ./install.sh interaktiv (fragt Admin-Passwort etc.) # ./install.sh --yes nicht-interaktiv (erzeugt Zufalls-Admin-Passwort) # set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ENV_FILE="$SCRIPT_DIR/.env" ASSUME_YES=0 [[ "${1:-}" == "--yes" || "${1:-}" == "-y" ]] && ASSUME_YES=1 info() { printf '\033[0;32m==>\033[0m %s\n' "$*"; } warn() { printf '\033[0;33m[!]\033[0m %s\n' "$*"; } error() { printf '\033[0;31m[x]\033[0m %s\n' "$*" >&2; } rand() { LC_ALL=C tr -dc 'A-Za-z0-9' /dev/null 2>&1; then SUDO="sudo" else SUDO="" fi # --- Paketinstallation (paketmanager-unabhängig) ------------------------------ pkg_install() { local pkg="$1" if command -v apt-get >/dev/null 2>&1; then $SUDO apt-get update -y && $SUDO apt-get install -y "$pkg" elif command -v dnf >/dev/null 2>&1; then $SUDO dnf install -y "$pkg" elif command -v yum >/dev/null 2>&1; then $SUDO yum install -y "$pkg" elif command -v apk >/dev/null 2>&1; then $SUDO apk add --no-cache "$pkg" elif command -v pacman >/dev/null 2>&1; then $SUDO pacman -Sy --noconfirm "$pkg" elif command -v zypper >/dev/null 2>&1; then $SUDO zypper install -y "$pkg" else return 1 fi } # --- curl sicherstellen (wird für die Docker-Installation gebraucht) ---------- ensure_curl() { if command -v curl >/dev/null 2>&1; then return 0 fi warn "curl ist nicht installiert – wird jetzt automatisch installiert …" if ! pkg_install curl; then error "curl konnte nicht installiert werden (kein bekannter Paketmanager gefunden). Bitte curl manuell installieren und erneut ausführen." exit 1 fi command -v curl >/dev/null 2>&1 || { error "curl-Installation fehlgeschlagen."; exit 1; } info "curl installiert." } # --- Docker prüfen / installieren --------------------------------------------- ensure_docker() { if command -v docker >/dev/null 2>&1; then info "Docker gefunden: $(docker --version)" else warn "Docker ist nicht installiert." if [[ "$ASSUME_YES" -eq 1 ]]; then reply="j" else read -r -p "Soll Docker jetzt automatisch installiert werden? [J/n] " reply reply="${reply:-j}" fi case "$reply" in [JjYy]*) ensure_curl info "Installiere Docker über get.docker.com …" curl -fsSL https://get.docker.com | sh ;; *) error "Docker wird benötigt. Bitte manuell installieren und erneut ausführen." exit 1 ;; esac fi # docker compose (v2) oder docker-compose (v1) ermitteln if docker compose version >/dev/null 2>&1; then COMPOSE="docker compose" elif command -v docker-compose >/dev/null 2>&1; then COMPOSE="docker-compose" else error "Docker Compose wurde nicht gefunden. Bitte Docker Compose v2 installieren." exit 1 fi info "Verwende: $COMPOSE" if ! docker info >/dev/null 2>&1; then error "Docker-Daemon nicht erreichbar. Läuft Docker? Ggf. 'sudo' nötig oder Nutzer zur 'docker'-Gruppe hinzufügen." exit 1 fi } # --- .env erzeugen ------------------------------------------------------------ create_env() { if [[ -f "$ENV_FILE" ]]; then info ".env existiert bereits – bestehende Konfiguration wird verwendet." return fi info "Erzeuge Konfiguration (.env) …" local web_port="8080" local admin_user="admin" local admin_pass admin_pass="$(rand 16)" if [[ "$ASSUME_YES" -eq 0 ]]; then read -r -p "Port für die Web-UI [8080]: " input; web_port="${input:-8080}" read -r -p "Admin-Benutzername [admin]: " input; admin_user="${input:-admin}" read -r -s -p "Admin-Passwort [leer = zufällig generieren]: " input; echo [[ -n "$input" ]] && admin_pass="$input" fi cat > "$ENV_FILE" <:${web_port})" echo " Admin-Login: ${admin_user}" if [[ -n "${GENERATED_ADMIN_PASS:-}" ]]; then echo " Admin-Passwort: ${GENERATED_ADMIN_PASS}" warn "Bitte dieses Passwort notieren – es wird nicht erneut angezeigt." else echo " Admin-Passwort: (wie in .env gesetzt)" fi echo echo " Logs: ( cd $SCRIPT_DIR && $COMPOSE logs -f )" echo " Stoppen: ( cd $SCRIPT_DIR && $COMPOSE down )" } main "$@"