#!/usr/bin/env bash set -euo pipefail FEDEO_REF="${FEDEO_REF:-dev}" FEDEO_RAW_BASE_URL="${FEDEO_RAW_BASE_URL:-https://git.federspiel.tech/flfeders/FEDEO/raw/branch/${FEDEO_REF}}" FEDEO_DIR="${FEDEO_DIR:-/opt/fedeo}" SETUP_ARGS=("$@") FEDEO_USE_SUDO_DOCKER="${FEDEO_USE_SUDO_DOCKER:-false}" TTY_INPUT="${FEDEO_TTY_INPUT:-/dev/tty}" TTY_FD="" if { exec 3<"$TTY_INPUT"; } 2>/dev/null; then TTY_FD="3" fi SUDO="" if [[ "$(id -u)" -ne 0 ]]; then if command -v sudo >/dev/null 2>&1; then SUDO="sudo" fi fi usage() { cat <<'USAGE' FEDEO Selfhost Installer Typischer One-Liner: curl -fsSL https://git.federspiel.tech/flfeders/FEDEO/raw/branch/dev/scripts/selfhost-install.sh | bash Mit Optionen für den Setup-Assistenten: curl -fsSL https://git.federspiel.tech/flfeders/FEDEO/raw/branch/dev/scripts/selfhost-install.sh | bash -s -- --simple --start curl -fsSL https://git.federspiel.tech/flfeders/FEDEO/raw/branch/dev/scripts/selfhost-install.sh | bash -s -- --advanced Umgebung: FEDEO_DIR=/opt/fedeo FEDEO_REF=dev FEDEO_RAW_BASE_URL=https://git.federspiel.tech/flfeders/FEDEO/raw/branch/dev USAGE } read_interactive() { if [[ -n "$TTY_FD" ]]; then read -u "$TTY_FD" "$@" else read "$@" fi } yes_no() { local label="$1" local default_value="${2:-j}" local answer while true; do read_interactive -r -p "$label [$default_value]: " answer answer="${answer:-$default_value}" case "$answer" in y|Y|j|J|yes|Yes|ja|Ja) return 0 ;; n|N|no|No|nein|Nein) return 1 ;; *) echo "Bitte ja oder nein eingeben." ;; esac done } have() { command -v "$1" >/dev/null 2>&1 } install_base_packages() { local missing=() for binary in curl openssl; do if ! have "$binary"; then missing+=("$binary") fi done if [[ "${#missing[@]}" -eq 0 ]]; then return fi if ! have apt-get; then echo "Fehlende Programme: ${missing[*]}" >&2 echo "Bitte installiere sie manuell und starte den Installer erneut." >&2 exit 1 fi if [[ "$(id -u)" -ne 0 && -z "$SUDO" ]]; then echo "Fehlende Programme: ${missing[*]}" >&2 echo "Ohne root oder sudo kann der Installer sie nicht automatisch installieren." >&2 exit 1 fi echo "Installiere Basispakete: ${missing[*]}" $SUDO apt-get update $SUDO apt-get install -y ca-certificates curl openssl } ensure_docker() { if have docker && docker compose version >/dev/null 2>&1; then FEDEO_USE_SUDO_DOCKER="false" return fi if [[ -n "$SUDO" ]] && have docker && $SUDO docker compose version >/dev/null 2>&1; then FEDEO_USE_SUDO_DOCKER="true" return fi echo echo "Docker Engine mit Compose Plugin wurde nicht gefunden." if ! have curl; then echo "curl fehlt, Docker kann nicht automatisch installiert werden." >&2 exit 1 fi if yes_no "Docker jetzt über das offizielle Docker-Installationsscript installieren?" "j"; then if [[ "$(id -u)" -ne 0 && -z "$SUDO" ]]; then echo "Ohne root oder sudo kann Docker nicht automatisch installiert werden." >&2 exit 1 fi curl -fsSL https://get.docker.com | $SUDO sh else echo "Bitte Docker Engine inkl. Compose Plugin installieren und den Installer erneut starten." >&2 exit 1 fi if docker compose version >/dev/null 2>&1; then FEDEO_USE_SUDO_DOCKER="false" return fi if [[ -n "$SUDO" ]] && $SUDO docker compose version >/dev/null 2>&1; then FEDEO_USE_SUDO_DOCKER="true" return fi if ! docker compose version >/dev/null 2>&1; then echo "Docker Compose ist nach der Installation noch nicht verfügbar." >&2 echo "Melde dich ggf. neu an oder prüfe die Docker-Installation." >&2 exit 1 fi } download_file() { local source="$1" local target="$2" local temp_file="${target}.tmp" mkdir -p "$(dirname "$target")" curl -fsSL "$source" -o "$temp_file" mv "$temp_file" "$target" } download_selfhost_files() { echo echo "Zielverzeichnis: $FEDEO_DIR" echo "Quelle: $FEDEO_RAW_BASE_URL" if ! mkdir -p "$FEDEO_DIR/scripts" 2>/dev/null; then if [[ -z "$SUDO" ]]; then echo "Keine Schreibrechte für $FEDEO_DIR und sudo ist nicht verfügbar." >&2 exit 1 fi $SUDO mkdir -p "$FEDEO_DIR/scripts" $SUDO chown "$(id -u):$(id -g)" "$FEDEO_DIR" "$FEDEO_DIR/scripts" fi if [[ -d "$FEDEO_DIR/.git" ]]; then echo "Hinweis: In $FEDEO_DIR liegt noch ein alter Git-Checkout. Der Installer aktualisiert nur die Selfhost-Dateien und lässt Daten, .env und Checkout unangetastet." fi echo "Lade Selfhost-Dateien..." download_file "$FEDEO_RAW_BASE_URL/docker-compose.selfhost.yml" "$FEDEO_DIR/docker-compose.yml" download_file "$FEDEO_RAW_BASE_URL/.env.example" "$FEDEO_DIR/.env.example" download_file "$FEDEO_RAW_BASE_URL/scripts/selfhost-setup.sh" "$FEDEO_DIR/scripts/selfhost-setup.sh" chmod +x "$FEDEO_DIR/scripts/selfhost-setup.sh" } main() { if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then usage exit 0 fi cat <<'EOF' FEDEO Selfhost Installer Dieser Installer bringt die typische Serverstruktur mit: - prüft Basispakete - installiert Docker optional automatisch - lädt nur die Selfhost-Dateien nach /opt/fedeo - startet danach den geführten Selfhost-Assistenten EOF install_base_packages ensure_docker download_selfhost_files echo echo "Starte Selfhost-Assistent..." cd "$FEDEO_DIR" export FEDEO_USE_SUDO_DOCKER export FEDEO_TTY_INPUT="$TTY_INPUT" if [[ "$TTY_INPUT" == "/dev/tty" && -r "$TTY_INPUT" ]]; then exec bash scripts/selfhost-setup.sh "${SETUP_ARGS[@]}" <"$TTY_INPUT" fi exec bash scripts/selfhost-setup.sh "${SETUP_ARGS[@]}" } main "$@"