#!/usr/bin/env bash set -euo pipefail # ──────────────────────────────────────────────────────────────────────────────── # Steuerkram – Installationsscript # # Ablauf: # 1. Root-Check – bricht ab, wenn nicht als root ausgeführt # 2. Verzeichnis-Abfrage – fragt nach dem Zielpfad, schlägt /opt/Steuerkram vor # 3. Distribution erkennen – liest /etc/os-release, unterstützt Debian/Ubuntu, # Fedora, RHEL/CentOS/Alma/Rocky, Arch, openSUSE, Alpine # 4. Asahi Linux erkennen – prüft VARIANT_ID, PRETTY_NAME und den Kernel-String # (uname -r | grep asahi) # 5. git + curl installieren – per distributionseigenem Paketmanager # 6. Docker installieren: # - Asahi Linux → verlinktes Gist-Script (siliconuy) # - Debian/Ubuntu → offizielles get.docker.com-Script # - Fedora/RHEL → Docker-CE-Repo via dnf config-manager # - Arch/openSUSE/Alpine → jeweiliger Paketmanager # 7. Docker Compose prüfen – Plugin oder Standalone, installiert bei Bedarf nach # 8. Docker-Dienst – systemctl enable --now docker # 9. Repository klonen – git clone nach dem gewählten Pfad # (oder git pull falls bereits vorhanden) # 10. .env anlegen – kopiert .env.example → .env (wenn noch nicht vorhanden) # 11. Abschluss-Hinweis – zeigt den genauen Pfad zur .env und welche Werte # geändert werden müssen # ──────────────────────────────────────────────────────────────────────────────── REPO_URL="https://codeberg.org/fds2610/Steuerkram.git" DEFAULT_INSTALL_DIR="/opt/Steuerkram" # ── Farben ────────────────────────────────────────────────────────────────────── RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BOLD='\033[1m' NC='\033[0m' info() { echo -e "${GREEN}[INFO]${NC} $*"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } error() { echo -e "${RED}[FEHLER]${NC} $*" >&2; exit 1; } heading() { echo -e "\n${BOLD}$*${NC}"; } # ── Root-Check ────────────────────────────────────────────────────────────────── if [[ $EUID -ne 0 ]]; then error "Dieses Script muss als root ausgeführt werden (sudo $0)." fi # ── Installationsverzeichnis ──────────────────────────────────────────────────── heading "Steuerkram – Installation" echo "" read -r -p "Installationsverzeichnis [${DEFAULT_INSTALL_DIR}]: " INSTALL_DIR INSTALL_DIR="${INSTALL_DIR:-$DEFAULT_INSTALL_DIR}" info "Installiere nach: ${INSTALL_DIR}" # ── Distribution erkennen ─────────────────────────────────────────────────────── heading "Distribution erkennen" detect_distro() { if [[ -f /etc/os-release ]]; then # shellcheck source=/dev/null source /etc/os-release echo "${ID,,}" elif command -v lsb_release &>/dev/null; then lsb_release -si | tr '[:upper:]' '[:lower:]' else error "Konnte die Distribution nicht ermitteln." fi } DISTRO="$(detect_distro)" info "Erkannte Distribution: ${DISTRO}" # Asahi Linux erkennen (Fedora-Basis auf Apple-Silicon) IS_ASAHI=false if [[ -f /etc/os-release ]]; then source /etc/os-release if grep -qi "asahi" <<< "${VARIANT_ID:-}${VARIANT:-}${ID_LIKE:-}${PRETTY_NAME:-}"; then IS_ASAHI=true fi fi # Alternativ: Kernel-String prüfen if uname -r | grep -qi "asahi"; then IS_ASAHI=true fi if [[ "$IS_ASAHI" == "true" ]]; then info "Asahi Linux erkannt." fi # ── Paketmanager & Basis-Pakete ───────────────────────────────────────────────── heading "Basis-Pakete installieren (git, curl)" install_base_packages() { case "$DISTRO" in debian|ubuntu|linuxmint|pop|elementary|kali|raspbian) apt-get update -qq apt-get install -y git curl ;; fedora|asahi) dnf install -y git curl ;; centos|rhel|almalinux|rocky) dnf install -y git curl || yum install -y git curl ;; arch|manjaro|endeavouros|garuda) pacman -Sy --noconfirm git curl ;; opensuse*|sles) zypper install -y git curl ;; alpine) apk add --no-cache git curl ;; *) warn "Unbekannte Distribution '${DISTRO}'. Versuche apt-get …" apt-get update -qq && apt-get install -y git curl || \ error "Paketinstallation fehlgeschlagen. Bitte git und curl manuell installieren." ;; esac } install_base_packages info "git und curl installiert." # ── Docker installieren ───────────────────────────────────────────────────────── heading "Docker installieren" if command -v docker &>/dev/null; then info "Docker ist bereits installiert: $(docker --version)" DOCKER_INSTALLED=true else DOCKER_INSTALLED=false fi install_docker() { if [[ "$IS_ASAHI" == "true" ]]; then # Asahi Linux: spezielles Installations-Script (kein x86-Docker-Repo verfügbar) info "Asahi Linux: verwende Community-Script für Docker auf ARM64/Asahi …" curl -fsSL https://gist.githubusercontent.com/siliconuy/e86617aca69b6b21d705fd745346b222/raw \ -o /tmp/install-docker-asahi.sh bash /tmp/install-docker-asahi.sh rm -f /tmp/install-docker-asahi.sh else case "$DISTRO" in debian|ubuntu|linuxmint|pop|elementary|kali|raspbian) # Offizielles Docker-Script curl -fsSL https://get.docker.com -o /tmp/get-docker.sh sh /tmp/get-docker.sh rm -f /tmp/get-docker.sh ;; fedora) dnf install -y dnf-plugins-core dnf config-manager --add-repo \ https://download.docker.com/linux/fedora/docker-ce.repo dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin ;; centos|rhel|almalinux|rocky) dnf install -y dnf-plugins-core dnf config-manager --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin ;; arch|manjaro|endeavouros|garuda) pacman -Sy --noconfirm docker docker-compose ;; opensuse*|sles) zypper install -y docker docker-compose ;; alpine) apk add --no-cache docker docker-compose ;; *) warn "Docker-Installation für '${DISTRO}' nicht bekannt. Versuche offizielles Script …" curl -fsSL https://get.docker.com -o /tmp/get-docker.sh sh /tmp/get-docker.sh rm -f /tmp/get-docker.sh ;; esac fi } if [[ "$DOCKER_INSTALLED" == "false" ]]; then install_docker info "Docker installiert: $(docker --version)" fi # ── Docker Compose prüfen ─────────────────────────────────────────────────────── heading "Docker Compose prüfen" if docker compose version &>/dev/null 2>&1; then info "Docker Compose (Plugin) verfügbar: $(docker compose version)" elif command -v docker-compose &>/dev/null; then info "docker-compose (standalone) verfügbar: $(docker-compose --version)" else warn "Docker Compose nicht gefunden – versuche nachzuinstallieren …" case "$DISTRO" in debian|ubuntu|linuxmint|pop|elementary|kali|raspbian) apt-get install -y docker-compose-plugin || \ apt-get install -y docker-compose ;; fedora|centos|rhel|almalinux|rocky) dnf install -y docker-compose-plugin || \ dnf install -y docker-compose ;; arch|manjaro|endeavouros|garuda) pacman -Sy --noconfirm docker-compose ;; opensuse*|sles) zypper install -y docker-compose ;; alpine) apk add --no-cache docker-compose ;; esac info "Docker Compose installiert." fi # ── Docker-Dienst starten & aktivieren ───────────────────────────────────────── heading "Docker-Dienst aktivieren" if command -v systemctl &>/dev/null; then systemctl enable --now docker info "Docker-Dienst gestartet und für Autostart aktiviert." fi # ── Repository klonen ─────────────────────────────────────────────────────────── heading "Repository klonen" if [[ -d "${INSTALL_DIR}/.git" ]]; then info "Repository existiert bereits in ${INSTALL_DIR} – führe git pull aus." git -C "${INSTALL_DIR}" pull else if [[ -d "${INSTALL_DIR}" ]] && [[ -n "$(ls -A "${INSTALL_DIR}" 2>/dev/null)" ]]; then error "Verzeichnis ${INSTALL_DIR} existiert und ist nicht leer. Bitte ein leeres Verzeichnis wählen." fi mkdir -p "${INSTALL_DIR}" git clone "${REPO_URL}" "${INSTALL_DIR}" info "Repository geklont nach ${INSTALL_DIR}." fi # ── .env anlegen ──────────────────────────────────────────────────────────────── heading ".env einrichten" ENV_FILE="${INSTALL_DIR}/.env" ENV_EXAMPLE="${INSTALL_DIR}/.env.example" if [[ ! -f "${ENV_FILE}" ]]; then if [[ -f "${ENV_EXAMPLE}" ]]; then cp "${ENV_EXAMPLE}" "${ENV_FILE}" info ".env aus .env.example erstellt." else warn ".env.example nicht gefunden – .env muss manuell angelegt werden." fi else info ".env existiert bereits und wird nicht überschrieben." fi # ── systemd-Service anpassen ──────────────────────────────────────────────────── heading "systemd-Service konfigurieren" SERVICE_FILE="${INSTALL_DIR}/steuerkram.service" if [[ -f "${SERVICE_FILE}" ]]; then if [[ "${INSTALL_DIR}" != "${DEFAULT_INSTALL_DIR}" ]]; then sed -i "s|WorkingDirectory=.*|WorkingDirectory=${INSTALL_DIR}|" "${SERVICE_FILE}" info "WorkingDirectory in steuerkram.service auf '${INSTALL_DIR}' gesetzt." else info "Installationsverzeichnis ist Standard – keine Anpassung der Service-Datei nötig." fi else warn "steuerkram.service nicht gefunden in ${INSTALL_DIR} – bitte WorkingDirectory manuell prüfen." fi # ── Abschluss-Hinweis ─────────────────────────────────────────────────────────── echo "" echo -e "${BOLD}════════════════════════════════════════════════════════════════${NC}" echo -e "${GREEN}${BOLD} Installation abgeschlossen!${NC}" echo -e "${BOLD}════════════════════════════════════════════════════════════════${NC}" echo "" echo -e "${YELLOW}${BOLD}Wichtig: Bitte passe jetzt die Konfigurationsdatei an:${NC}" echo "" echo -e " ${BOLD}${ENV_FILE}${NC}" echo "" echo " Folgende Werte sollten geändert werden:" echo " DB_PASS – Datenbankpasswort" echo " APP_SECRET – Zufälliger geheimer Schlüssel (für Sessions)" echo "" echo " Danach die Anwendung starten:" echo -e " ${BOLD}cd ${INSTALL_DIR} && docker compose up -d${NC}" echo "" echo -e "${YELLOW}${BOLD}Erster Login:${NC}" echo " Beim ersten Aufruf der Anwendung im Browser wird automatisch" echo " die Ersteinrichtung angezeigt – dort den ersten Benutzer anlegen." echo ""