Mein Discourse ist ausgefallen. Zertifikatsproblem?

Hallo @WesPenre :slight_smile:

Der Fehler sollte weiter oben liegen, als Ihr Screenshot zeigt. Könnten Sie bitte Ihr vollständiges Log hier einfügen, damit die Leute sehen können, was das Problem sein könnte?

Kann mir bitte jemand sagen, wie ich ein Fehlerprotokoll erstellen kann, wenn ich mich nicht bei Discourse anmelden kann? Kann ich es in WinSCP finden? Wenn ja, was ist das Verzeichnis und der Name des Protokolls?

Ist das alles? Es ist die Startdatei:

#!/usr/bin/env bash

usage () {
  echo "Verwendung: launcher COMMAND CONFIG [--skip-prereqs] [--docker-args STRING]"
  echo "Befehle:"
  echo "    start:       Einen Container starten/initialisieren"
  echo "    stop:        Einen laufenden Container stoppen"
  echo "    restart:     Einen Container neu starten"
  echo "    destroy:     Einen Container stoppen und entfernen"
  echo "    enter:       Eine Shell öffnen, um Befehle im Container auszuführen"
  echo "    logs:        Die Docker-Logs eines Containers anzeigen"
  echo "    bootstrap:   Einen Container für die Konfiguration basierend auf einer Vorlage initialisieren"
  echo "    run:         Den angegebenen Befehl mit der Konfiguration im Kontext des zuletzt initialisierten Images ausführen"
  echo "    rebuild:     Einen Container neu erstellen (alten zerstören, initialisieren, neuen starten)"
  echo "    cleanup:     Alle Container entfernen, die seit über 24 Stunden gestoppt sind"
  echo "    start-cmd:   Den Docker-Befehl generieren, der zum Starten des Containers verwendet wird"
  echo
  echo "Optionen:"
  echo "    --skip-prereqs             Keine Überprüfung der Voraussetzungen für den Launcher"
  echo "    --docker-args              Zusätzliche Argumente, die beim Ausführen von Docker übergeben werden sollen"
  echo "    --skip-mac-address         Keine MAC-Adresse zuweisen"
  echo "    --run-image                Das Image überschreiben, das zum Ausführen des Containers verwendet wird"
  exit 1
}

# für potenzielle spätere Neuausführung
SAVED_ARGV=("$@")

command=$1
config=$2

# user_args_argv wird einmal zugewiesen, wenn der Argumentvektor analysiert wird.
user_args_argv=""
# user_args ist veränderbar: Sein Wert kann sich ändern, wenn Vorlagen analysiert werden.
# Obermenge von user_args_argv.
user_args=""

user_run_image=""

if [[ $command == "run" ]]; then
  run_command=$3
fi

while [ ${#} -gt 0 ]; do
  case "${1}" in
  --debug)
    DEBUG="1"
    ;;
  --skip-prereqs)
    SKIP_PREREQS="1"
    ;;
  --skip-mac-address)
    SKIP_MAC_ADDRESS="1"
    ;;
  --docker-args)
    user_args_argv="$2"
    user_args="$user_args_argv"
    shift
    ;;
  --run-image)
    user_run_image="$2"
    shift
    ;;
  esac

  shift 1
done

if [ -z "$command" -o -z "$config" -a "$command" != "cleanup" ]; then
  usage
fi

# Docker mag keine Großbuchstaben, Leerzeichen oder Sonderzeichen nicht. Fange dies jetzt ab, bevor wir alles aufbauen und es dann herausfinden.
re='[[:upper:]/ !@#$%^&*()+~`=]'
if [[ $config =~ $re ]];
  then
    echo
    echo "FEHLER: Der Konfigurationsname '$config' darf keine Großbuchstaben, Leerzeichen oder Sonderzeichen enthalten. Korrigieren Sie den Konfigurationsnamen und führen Sie $0 erneut aus."
    echo
    exit 1
fi

cd "$(dirname "$0")"

pups_version='v1.0.3'
docker_min_version='17.03.1'
docker_rec_version='17.06.2'
git_min_version='1.8.0'
git_rec_version='1.8.0'
kernel_min_version='4.4.0'

config_file=containers/"$config".yml
cidbootstrap=cids/"$config"_bootstrap.cid
local_discourse=local_discourse
image="discourse/base:2.0.20230217-0055"
image_stable="discourse/base:2.0.20230116-0051"
docker_path=`which docker.io 2> /dev/null || which docker`
git_path=`which git`

if [ "${SUPERVISED}" = "true" ]; then
  restart_policy="--restart=no"
  attach_on_start="-a"
  attach_on_run="-a stdout -a stderr"
else
  attach_on_run="-d"
fi

if [ -n "$DOCKER_HOST" ]; then
  docker_ip=`sed -e 's/^tcp:\/\/(.*):.*$/\1/' <<< "$DOCKER_HOST"`
elif [ -x "$(which ip 2>/dev/null)" ]; then
  docker_ip=`ip addr show docker0 | \
                  grep 'inet ' | \
                  awk '{ split($2,a,"/"); print a[1] }';`
else
  docker_ip=`ifconfig | \
                  grep -B1 "inet addr" | \
                  awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' | \
                  grep docker0 | \
                  awk -F: '{ print $3 }';`
fi

# Aus https://stackoverflow.com/a/44660519/702738
compare_version() {
    if [[ $1 == $2 ]]; then
        return 1
    fi
    local IFS=.
    local i a=(${1%%[^0-9.]*}) b=(${2%%[^0-9.]*})
    local arem=${1#${1%%[^0-9.]*}} brem=${2#${2%%[^0-9.]*}}
    for ((i=0; i<${#a[@]} || i<${#b[@]}; i++)); do
        if ((10#${a[i]:-0} < 10#${b[i]:-0})); then
            return 1
        elif ((10#${a[i]:-0} > 10#${b[i]:-0})); then
            return 0
        fi
    done
    if [ "$arem" '<' "$brem" ]; then
        return 1
    elif [ "$arem" '>' "$brem" ]; then
        return 0
    fi
    return 1
}

fatal () {
  echo -e "\n$1\n"
  exit "${2:-1}"
}

install_docker() {
  echo "Docker ist nicht installiert. Sie müssen Docker installieren, um den Launcher ausführen zu können."
  echo "Siehe https://docs.docker.com/installation/"
  exit 1
}

pull_image() {
  # Fügen Sie einen einzelnen Wiederholungsversuch hinzu, um Dockerhub-TLS-Fehler zu umgehen
  $docker_path pull $image || $docker_path pull $image
}

check_prereqs() {

  if [ -z $docker_path ]; then
    install_docker
  fi

  # 1. Läuft der Docker-Daemon?
  # Wir senden stderr nach /dev/null, da uns Warnungen nicht interessieren,
  # es beschwert sich normalerweise über Swap, was nicht wichtig ist
  test=`$docker_path info 2> /dev/null`
  if [[ $? -ne 0 ]] ; then
    echo "Keine Verbindung zum Docker-Daemon möglich – überprüfen Sie, ob er läuft und Sie Zugriff haben"
    exit 1
  fi

  # 2. Wird ein zugelassener Speicher-Treiber verwendet?
  if ! $docker_path info 2> /dev/null | egrep -q 'Storage Driver: (btrfs|aufs|zfs|overlay2)$'; then
    echo "Ihre Docker-Installation verwendet keinen unterstützten Speicher-Treiber. Wenn wir fortfahren, kann es zu einer fehlerhaften Installation kommen."
    echo "overlay2 ist der empfohlene Speicher-Treiber, obwohl zfs und aufs ebenfalls funktionieren können."
    echo "Andere Speicher-Treiber sind bekanntermaßen problematisch."
    echo "Sie können herausfinden, welches Dateisystem Sie verwenden, indem Sie \"docker info\" ausführen und die Zeile 'Storage Driver' prüfen."
    echo
    echo "Wenn Sie trotzdem mit Ihrem bestehenden, nicht unterstützten Speicher-Treiber fortfahren möchten,"
    echo "lesen Sie den Quellcode des Launchers und finden Sie heraus, wie Sie diese Prüfung umgehen können."
    exit 1
  fi

  # 3. Wird die empfohlene Docker-Version ausgeführt?
  test=($($docker_path --version))  # Docker-Versionszeichenfolge abrufen
  test=${test[2]//,/}  # Nur die Version abrufen und Komma entfernen, falls vorhanden

  # Mindestens die minimale Docker-Version
  if compare_version "${docker_min_version}" "${test}"; then
    echo "FEHLER: Docker-Version ${test} wird nicht unterstützt. Bitte aktualisieren Sie auf mindestens ${docker_min_version} oder empfohlen ${docker_rec_version}"
    exit 1
  fi

  # Neuere Docker-Version empfehlen
  if compare_version "${docker_rec_version}" "${test}"; then
    echo "WARNUNG: Docker-Version ${test} veraltet. Aktualisierung auf ${docker_rec_version} oder neuer empfohlen."
  fi

  arm=false
  case $(uname -m) in
    armv7l)
      echo "FEHLER: 32-Bit-Arm wird nicht unterstützt. Prüfen Sie, ob Ihre Hardware Arm64 unterstützt, was experimentell unterstützt wird."
      exit 1
      ;;
    aarch64 | arm64)
      echo "WARNUNG: Die Unterstützung für aarch64 ist derzeit experimentell. Bitte melden Sie Probleme unter https://meta.discourse.org/tag/arm"
      image="discourse/base:aarch64"
      arm=true
      ;;
    x86_64)
      echo "x86_64-Architektur erkannt."
      ;;
    *)
      echo "FEHLER: Unbekannte Architektur erkannt."
      exit 1
      ;;
  esac


  # 4. Discourse-Docker-Image heruntergeladen
  test=`$docker_path images | awk '{print $1 ":" $2 }' | grep "$image"`

  # Experimentelle Arm-Unterstützung verwendet ein festes Tag, immer pullen
  if [ -z "$test" ] || [ $arm = true ]; then
    echo
    echo "WARNUNG: Wir beginnen jetzt mit dem Herunterladen des Discourse-Basis-Images"
    echo "Dieser Vorgang kann je nach Ihrer Netzwerkgeschwindigkeit einige Minuten bis eine Stunde dauern"
    echo
    echo "Bitte haben Sie Geduld"
    echo

    pull_image
  fi

  # Für stabil eine ältere Image-Version verwenden
  version=$(cat $config_file | $docker_path run $user_args --rm -i -a stdout -a stdin $image ruby -e \
      "require 'yaml'; puts YAML.load(STDIN.readlines.join)['params']['version']")
  if [ "$version" = "stable" ]; then
    image=$image_stable
    pull_image
  fi

  # 5. Wird die empfohlene Git-Version ausgeführt?
  test=($($git_path --version))  # Git-Versionszeichenfolge abrufen
  test=${test[2]//,/}  # Nur die Version abrufen und Komma entfernen, falls vorhanden

  # Mindestens die Mindestversion
  if compare_version "${git_min_version}" "${test}"; then
    echo "FEHLER: Git-Version ${test} wird nicht unterstützt. Bitte aktualisieren Sie auf mindestens ${git_min_version} oder empfohlen ${git_rec_version}"
    exit 1
  fi

  Beste Version empfehlen
  if compare_version "${git_rec_version}" "${test}"; then
    echo "WARNUNG: Git-Version ${test} veraltet. Aktualisierung auf ${git_rec_version} oder neuer empfohlen."
  fi

  Mindestkernelversion aufgrund von https://bugs.ruby-lang.org/issues/13885 prüfen
  test=($(uname -r))

  # Mindestens die Mindestversion
  if compare_version "${kernel_min_version}" "${test}"; then
    echo "FEHLER: Kernel-Version ${test} wird nicht unterstützt. Bitte aktualisieren Sie auf mindestens ${kernel_min_version}"
    exit 1
  fi

  # 6. Kann stderr / stdout / tty angehängt werden?
  test=`$docker_path run $user_args -i --rm -a stdout -a stderr $image echo working`
  if [[ "$test" =~ "working" ]] ; then : ; else
    echo "Ihre Docker-Installation funktioniert nicht ordnungsgemäß"
    echo
    echo "Siehe: https://meta.discourse.org/t/docker-error-on-bootstrap/13657/18?u=sam"
    exit 1
  fi

  # 7. Ausreichend Platz für das Bootstrap im Docker-Ordner
  folder=`$docker_path info --format '{{.DockerRootDir}}'`
  safe_folder=${folder:-/var/lib/docker}
  if [[ -d $safe_folder && $(stat -f --format="%a*%S" $safe_folder)/1024**3 -lt 5 ]] ; then
    echo "Sie haben weniger als 5 GB freien Speicherplatz auf der Festplatte, auf der sich $safe_folder befindet. Sie benötigen mehr Platz, um fortzufahren."
    df -h $safe_folder
    echo
    if tty >/dev/null; then
      read -p "Möchten Sie versuchen, Platz durch Bereinigen von Docker-Images und Containern im System freizugeben? (y/N)" -n 1 -r
      echo
      if [[ $REPLY =~ ^[Yy]$ ]]
      then
        $docker_path container prune --force --filter until=24h >/dev/null
        $docker_path image prune --all --force --filter until=24h >/dev/null
        echo "Wenn die Bereinigung erfolgreich war, können Sie es jetzt erneut versuchen."
      fi
    fi
    exit 1
  fi

  # 8. Container-Definitionsdatei ist zugänglich und nicht unsicher (weltlesbar)
  if [[ ! -e "$config_file" || ! -r "$config_file" ]]; then
    echo "FEHLER: $config_file existiert nicht oder ist nicht lesbar."
    echo
    echo "Verfügbare Konfigurationen ( `cd containers && ls -dm *.yml | tr -s '\n' ' ' | awk '{ gsub(/\.yml/, ""); print }'`)"
    exit 1
  elif [[ "$(find $config_file -perm -004)" ]]; then
    echo "WARNUNG: Die Datei $config_file ist weltlesbar. Sie können diese Datei sichern, indem Sie ausführen: chmod o-rwx $config_file"
  fi
}


if [ -z "$SKIP_PREREQS" ] && [ "$command" != "cleanup" ]; then
  check_prereqs
fi

set_volumes() {
  volumes=`cat $config_file | $docker_path run $user_args --rm -i -a stdout -a stdin $image ruby -e \
        "require 'yaml'; puts YAML.load(STDIN.readlines.join)['volumes'].map{|v| '-v ' << v['volume']['host'] << ':' << v['volume']['guest'] << ' '}.join"`
}

set_links() {
    links=`cat $config_file | $docker_path run $user_args --rm -i -a stdout -a stdin $image ruby -e \
        "require 'yaml'; puts YAML.load(STDIN.readlines.join)['links'].map{|l| '--link ' << l['link']['name'] << ':' << l['link']['alias'] << ' '}.join"`
}

find_templates() {
    local templates=`cat $1 | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \
      "require 'yaml'; puts YAML.load(STDIN.readlines.join)['templates']"`

    local arrTemplates=${templates// / }

    if [ ! -z "$templates" ]; then
      echo $templates
    else
      echo ""
    fi
}

set_template_info() {
    templates=$(find_templates $config_file)

    arrTemplates=(${templates// / })
    config_data=$(cat $config_file)

    input="hack: true"

    for template in "${arrTemplates[@]}"
    do
      [ ! -z $template ] && {
        input="$input _FILE_SEPERATOR_ $(cat $template)"
      }
    done

    # Wir möchten unsere Konfigurationsdatei immer zuletzt haben, damit sie Vorrang hat
    input="$input _FILE_SEPERATOR_ $config_data"

    read -r -d '' env_ruby << 'RUBY'
    require 'yaml'

    input=STDIN.readlines.join
    # Standardmäßig UTF-8 für die Datenbank
    env = {'LANG' => 'en_US.UTF-8'}
    input.split('_FILE_SEPERATOR_').each do |yml|
       yml.strip!
       begin
         env.merge!(YAML.load(yml)['env'] || {})
       rescue Psych::SyntaxError => e
        puts e
        puts "*ERROR."
       rescue => e
        puts yml
        p e
       end
    end
    env.each{|k,v| puts "*ERROR." if v.is_a?(Hash)}
    puts env.map{|k,v| "-e\n#{k}=#{v}" }.join("\n")
RUBY

    tmp_input_file=$(mktemp)

    echo "$input" > "$tmp_input_file"
    raw=`exec cat "$tmp_input_file" | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e "$env_ruby"`

    rm -f "$tmp_input_file"

    env=()
    ok=1
    while read i; do
      if [ "$i" == "*ERROR." ]; then
        ok=0
      elif [ -n "$i" ]; then
        env[${#env[@]}]="${i//\{\{config\}\}/${config}}"
      fi
    done <<< "$raw"

    if [ "$ok" -ne 1 ]; then
      echo "${env[@]}"
      echo "YAML-Syntaxfehler. Bitte überprüfen Sie Ihre Konfigurationsdateien containers/*.yml."
      exit 1
    fi

    # Labels
    read -r -d '' labels_ruby << 'RUBY'
    require 'yaml'

    input=STDIN.readlines.join
    labels = {}
    input.split('_FILE_SEPERATOR_').each do |yml|
       yml.strip!
       begin
         labels.merge!(YAML.load(yml)['labels'] || {})
       rescue Psych::SyntaxError => e
        puts e
        puts "*ERROR."
       rescue => e
        puts yml
        p e
       end
    end
    puts labels.map{|k,v| "-l\n#{k}=#{v}" }.join("\n")
RUBY

    tmp_input_file=$(mktemp)

    echo "$input" > "$tmp_input_file"
    raw=`exec cat "$tmp_input_file" | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e "$labels_ruby"`

    rm -f "$tmp_input_file"

    labels=()
    ok=1
    while read i; do
      if [ "$i" == "*ERROR." ]; then
        ok=0
      elif [ -n "$i" ]; then
        labels[${#labels[@]}]=$(echo $i | sed s/{{config}}/${config}/g)
      fi
    done <<< "$raw"

    if [ "$ok" -ne 1 ]; then
      echo "${labels[@]}"
      echo "YAML-Syntaxfehler. Bitte überprüfen Sie Ihre Konfigurationsdateien containers/*.yml."
      exit 1
    fi

    # Exponieren
    read -r -d '' ports_ruby << 'RUBY'
    require 'yaml'

    input=STDIN.readlines.join
    ports = []
    input.split('_FILE_SEPERATOR_').each do |yml|
       yml.strip!
       begin
         ports += (YAML.load(yml)['expose'] || [])
       rescue Psych::SyntaxError => e
        puts e
        puts "*ERROR."
       rescue => e
        puts yml
        p e
       end
    end
    puts ports.map { |p| p.to_s.include?(':') ? "-p\n#{p}" : "--expose\n#{p}" }.join("\n")
RUBY

    tmp_input_file=$(mktemp)

    echo "$input" > "$tmp_input_file"
    raw=`exec cat "$tmp_input_file" | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e "$ports_ruby"`

    rm -f "$tmp_input_file"

    ports=()
    ok=1
    while read i; do
      if [ "$i" == "*ERROR." ]; then
        ok=0
      elif [ -n "$i" ]; then
        ports[${#ports[@]}]=$i
      fi
    done <<< "$raw"

    if [ "$ok" -ne 1 ]; then
      echo "${ports[@]}"
      echo "YAML-Syntaxfehler. Bitte überprüfen Sie Ihre Konfigurationsdateien containers/*.yml."
      exit 1
    fi

   merge_user_args
}

if [ -z $docker_path ]; then
  install_docker
fi

[ "$command" == "cleanup" ] && {
  $docker_path container prune --filter until=1h
  $docker_path image prune --all --filter until=1h

  if [ -d /var/discourse/shared/standalone/postgres_data_old ]; then
    echo
    echo "Altes PostgreSQL-Backup-Datencluster erkannt, das $(du -hs /var/discourse/shared/standalone/postgres_data_old | awk '{print $1}') belegt"
    read -p "Möchten Sie es entfernen? (y/N): " -n 1 -r && echo

    if [[ $REPLY =~ ^[Yy]$ ]]; then
      echo "Entferne altes PostgreSQL-Datencluster unter /var/discourse/shared/standalone/postgres_data_old..."
      rm -rf /var/discourse/shared/standalone/postgres_data_old*
    else
      exit 1
    fi
  fi

  exit 0
}

docker_version=($($docker_path --version))
docker_version=${test[2]//,/}
restart_policy=${restart_policy:---restart=always}

set_existing_container(){
  existing=`$docker_path ps -a | awk '{ print $1, $(NF) }' | grep " $config$" | awk '{ print $1 }'`
}

run_stop() {

  set_existing_container

  if [ ! -z $existing ]
     then
       (
        set -x
        $docker_path stop -t 30 $config
       )
     else
       echo "$config wurde nicht gestartet!"
       echo "./discourse-doctor kann helfen, das Problem zu diagnostizieren."
       exit 1
  fi
}

set_run_image() {
  run_image=`cat $config_file | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \
    "require 'yaml'; puts YAML.load(STDIN.readlines.join)['run_image']"`

  if [ -n "$user_run_image" ]; then
    run_image=$user_run_image
  elif [ -z "$run_image" ]; then
    run_image="$local_discourse/$config"
  fi
}

set_boot_command() {
  boot_command=`cat $config_file | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \
    "require 'yaml'; puts YAML.load(STDIN.readlines.join)['boot_command']"`

  if [ -z "$boot_command" ]; then

    no_boot_command=`cat $config_file | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \
      "require 'yaml'; puts YAML.load(STDIN.readlines.join)['no_boot_command']"`

    if [ -z "$no_boot_command" ]; then
      boot_command="/sbin/boot"
    fi
  fi
}

merge_user_args() {
  local docker_args

  docker_args=`cat $config_file | $docker_path run $user_args --rm -i -a stdout -a stdin $image ruby -e \
          "require 'yaml'; puts YAML.load(STDIN.readlines.join)['docker_args']"`

  if [[ -n "$docker_args" ]]; then
    user_args="$user_args_argv $docker_args"
  fi
}

run_start() {

   if [ -z "$START_CMD_ONLY" ]
   then
     existing=`$docker_path ps | awk '{ print $1, $(NF) }' | grep " $config$" | awk '{ print $1 }'`
     echo $existing
     if [ ! -z $existing ]
     then
       echo "Nichts zu tun, Ihr Container wurde bereits gestartet!"
       exit 0
     fi

     existing=`$docker_path ps -a | awk '{ print $1, $(NF) }' | grep " $config$" | awk '{ print $1 }'`
     if [ ! -z $existing ]
     then
       echo "Starte vorhandenen Container"
       (
         set -x
         $docker_path start $config
       )
       exit 0
     fi
   fi

   set_template_info
   set_volumes
   set_links
   set_run_image
   set_boot_command

   # Hostname und Einstellungen aus der Container-Konfiguration abrufen
   for envar in "${env[@]}"
   do
     if [[ $envar == DOCKER_USE_HOSTNAME* ]] || [[ $envar == DISCOURSE_HOSTNAME* ]]
     then
       # Als Umgebungsvariable verwenden
       eval $envar
     fi
   done

   (
     hostname=`hostname -s`
     # Hostname überschreiben
     if [ "$DOCKER_USE_HOSTNAME" = "true" ]
     then
       hostname=$DISCOURSE_HOSTNAME
     else
       hostname=$hostname-$config
     fi

     # Wir müssen normalisieren, damit wir nur zulässige Zeichenketten haben. Dies ist umfassender, aber schauen wir uns zuerst an, wie Bash damit umgeht.
     # hostname=`$docker_path run $user_args --rm $image ruby -e 'print ARGV[0].gsub(/[^a-zA-Z-]/, "-")' $hostname`
     # Docker hat weitere Hostname-Regeln hinzugefügt
     hostname=${hostname//_/-}


     if [ -z "$SKIP_MAC_ADDRESS" ] ; then
      mac_address="--mac-address $($docker_path run $user_args -i --rm -a stdout -a stderr $image /bin/sh -c "echo $hostname | md5sum | sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/'")"
     fi

     if [ ! -z "$START_CMD_ONLY" ] ; then
       docker_path="true"
     fi

     set -x

     $docker_path run --shm-size=512m $links $attach_on_run $restart_policy "${env[@]}" "${labels[@]}" -h "$hostname" \
        -e DOCKER_HOST_IP="$docker_ip" --name $config -t "${ports[@]}" $volumes $mac_address $user_args \
        $run_image $boot_command

   )
   exit 0

}

run_run() {
  set_template_info
  set_volumes
  set_links
  set_run_image

  unset ERR
  (exec $docker_path run --rm --shm-size=512m $user_args $links "${env[@]}" -e DOCKER_HOST_IP="$docker_ip" -i -a stdin -a stdout -a stderr $volumes $run_image \
    /bin/bash -c "$run_command") || ERR=$?

  if [[ $ERR > 0 ]]; then
    exit 1
  fi
}

run_bootstrap() {
  set_template_info

  base_image=`cat $config_file | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \
    "require 'yaml'; puts YAML.load(STDIN.readlines.join)['base_image']"`

  update_pups=`cat $config_file | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \
    "require 'yaml'; puts YAML.load(STDIN.readlines.join)['update_pups']"`

  if [[ ! X"" = X"$base_image" ]]; then
    image=$base_image
  fi

  # Das base_image ist nicht immer discourse/base,
  # stellen wir sicher, dass wir immer vom neuesten bauen
  pull_image

  set_volumes
  set_links

  if $docker_path run $user_args --rm -i $image gem which pups; then
    pups_command="/usr/local/bin/pups --stdin"
  else
    # Fallback auf Git-Pull-Methode, falls `pups` nicht durch gem im Basis-Image installiert wurde
    pups_command="cd /pups &&"
    if [[ ! "false" =  $update_pups ]]; then
      pups_command="$pups_command git pull && git checkout $pups_version &&"
    fi
    pups_command="$pups_command /pups/bin/pups --stdin"
  fi

  echo $pups_command

  declare -i BOOTSTRAP_EXITCODE
  rm -f $cidbootstrap

  echo "$input" | $docker_path run --shm-size=512m $user_args $links "${env[@]}" -e DOCKER_HOST_IP="$docker_ip" --cidfile "$cidbootstrap" -i -a stdin -a stdout -a stderr $volumes $image \
    /bin/bash -c "$pups_command"
  BOOTSTRAP_EXITCODE=$?

  CONTAINER_ID=$(cat "$cidbootstrap")
  rm -f "$cidbootstrap"

  # Magischer Exit-Code, der einen Wiederholungsversuch anzeigt
  if [[ $BOOTSTRAP_EXITCODE -eq 77 ]]; then
    $docker_path rm "$CONTAINER_ID"
    exit 77
  elif [[ $BOOTSTRAP_EXITCODE -gt 0 ]]; then
    echo "Bootstrap fehlgeschlagen mit Exit-Code $BOOTSTRAP_EXITCODE"
    echo "** BOOTSTRAP FEHLGESCHLAGEN ** Bitte scrollen Sie nach oben und suchen Sie nach früheren Fehlermeldungen. Es kann mehr als eine geben."
    echo "./discourse-doctor kann helfen, das Problem zu diagnostizieren."

    if [[ -n "$DEBUG" ]]; then
      if $docker_path commit "$CONTAINER_ID" $local_discourse/$config-debug; then
        echo "** DEBUG ** Bild für Diagnosen beibehalten: $local_discourse/$config-debug"
      else
        echo "** DEBUG ** Fehler beim Committen des Containers $CONTAINER_ID für Diagnosen"
      fi
    fi

    $docker_path rm "$CONTAINER_ID"
    exit 1
  fi

  sleep 5

  $docker_path commit \
    -c "LABEL org.opencontainers.image.created=\"$(TZ=UTC date -Iseconds)\"" \
    "$CONTAINER_ID" \
    $local_discourse/$config || fatal "FEHLER BEIM COMMITTEN VON $CONTAINER_ID"
  $docker_path rm "$CONTAINER_ID"
}

case "$command" in
  bootstrap)
      run_bootstrap
      echo "Erfolgreich initialisiert. Zum Starten verwenden Sie ./launcher start $config"
      exit 0
      ;;

  run)
      run_run
      exit 0
      ;;

  enter)
      exec $docker_path exec -it $config /bin/bash --login
      ;;

  stop)
      run_stop
      exit 0
      ;;

  logs)

      $docker_path logs $config
      exit 0
      ;;

  restart)
      run_stop
      run_start
      exit 0
      ;;

  start-cmd)
    START_CMD_ONLY="1"
    run_start
    exit 0;
    ;;

  start)
      run_start
      exit 0
      ;;

  rebuild)
      if [ "$(git symbolic-ref --short HEAD)" == "master" ]; then
        git branch -m master main
        git fetch origin
        git branch -u origin/main main
        git remote set-head origin -a
      fi

      if [ "$(git symbolic-ref --short HEAD)" == "main" ]; then
        echo "Stelle sicher, dass der Launcher auf dem neuesten Stand ist"

        git remote update

        LOCAL=$(git rev-parse HEAD)
        REMOTE=$(git rev-parse @{u})
        BASE=$(git merge-base HEAD @{u})

        if [ $LOCAL = $REMOTE ]; then
          echo "Launcher ist auf dem neuesten Stand"

        elif [ $LOCAL = $BASE ]; then
          echo "Launcher wird aktualisiert..."
          git pull || (echo 'Fehler beim Aktualisieren' && exit 1)

          echo "Launcher aktualisiert, wird neu gestartet..."
          exec "$0" "${SAVED_ARGV[@]}"

        elif [ $REMOTE = $BASE ]; then
          echo "Ihre Version des Launchers ist vor der Origin-Version"

        else
          echo "Der Launcher hat divergierende Quellen. Dies wird nur im Dev-Modus erwartet."
        fi

      fi

      set_existing_container

      if [ ! -z $existing ]
        then
          echo "Alten Container stoppen"
          (
            set -x
            $docker_path stop -t 60 $config
          )
      fi

      run_bootstrap

      if [ ! -z $existing ]
        then
          echo "Alten Container entfernen"
          (
            set -x
            $docker_path rm $config
          )
      fi

      run_start
      exit 0
      ;;


  destroy)
      (set -x; $docker_path stop -t 10 $config && $docker_path rm $config) || (echo "$config wurde nicht gefunden" && exit 0)
      exit 0
      ;;
esac

usage

Um das abzuschließen, hat eine kleine Hilfestellung durch PM ergeben, dass es sich um ein Maxmind-Problem handelte und das Auskommentieren dieses Problems den Bootstrap erfolgreich abschließen ließ. :+1: