منتدى Discourse الخاص بي معطل. مشكلة في الشهادة؟

مرحباً @WesPenre :slight_smile:
يجب أن يكون الخطأ أعلى مما تتضمنه لقطة الشاشة الخاصة بك. هل يمكنك لصق سجلاتك الكاملة هنا حتى يتمكن الأشخاص من رؤية المشكلة المحتملة؟

هل يمكن لأحد أن يخبرني بكيفية إنشاء سجل أخطاء إذا لم أتمكن من تسجيل الدخول إلى Discourse؟ هل يمكنني العثور عليه في WinSCP؟ إذا كان الأمر كذلك، فما هو الدليل واسم السجل؟

هل هذا هو؟ إنه ملف المشغل:

#!/usr/bin/env bash

usage () {
  echo "Usage: launcher COMMAND CONFIG [--skip-prereqs] [--docker-args STRING]"
  echo "الأوامر:"
  echo "    start:       بدء/تهيئة حاوية"
  echo "    stop:        إيقاف حاوية قيد التشغيل"
  echo "    restart:     إعادة تشغيل حاوية"
  echo "    destroy:     إيقاف وإزالة حاوية"
  echo "    enter:       فتح غلاف لتنفيذ الأوامر داخل الحاوية"
  echo "    logs:        عرض سجلات Docker للحاوية"
  echo "    bootstrap:   تهيئة حاوية للإعداد بناءً على قالب"
  echo "    run:         تنفيذ الأمر المعطى مع الإعداد في سياق آخر صورة تم تهيئتها"
  echo "    rebuild:     إعادة بناء حاوية (إزالة القديمة، تهيئة، بدء جديدة)"
  echo "    cleanup:     إزالة جميع الحاويات التي توقفت عن العمل لأكثر من 24 ساعة"
  echo "    start-cmd:   توليد أمر docker المستخدم لبدء الحاوية"
  echo
  echo "الخيارات:"
  echo "    --skip-prereqs             عدم التحقق من المتطلبات المسبقة للمشغل"
  echo "    --docker-args              حجج إضافية لتمريرها عند تشغيل docker"
  echo "    --skip-mac-address         عدم تعيين عنوان MAC"
  echo "    --run-image                تجاوز الصورة المستخدمة لتشغيل الحاوية"
  exit 1
}

# للعودة المحتملة للتنفيذ لاحقًا
SAVED_ARGV=("$@")

command=$1
config=$2

# يتم تعيين user_args_argv مرة واحدة عند تحليل متجه الوسيطات.
user_args_argv=""
# user_args قابل للتغيير: قد تتغير قيمته عند تحليل القوالب.
# مجموعة فرعية من 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 الأحرف الكبيرة أو المسافات أو الأحرف الخاصة، لنلتقط ذلك الآن قبل بناء كل شيء ثم اكتشافه
re='[[:upper:]/ !@#$%^&*()+~`=]'
if [[ $config =~ $re ]];
  then
    echo
    echo "ERROR: اسم الإعداد '$config' لا يجب أن يحتوي على أحرف كبيرة أو مسافات أو أحرف خاصة. صحح اسم الإعداد وأعد تشغيل $0."
    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

# من 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 غير مثبت، ستحتاج إلى تثبيت Docker لتشغيل المشغل"
  echo "راجع https://docs.docker.com/installation/"
  exit 1
}

pull_image() {
  # أضف محاولة إعادة واحدة لتجاوز أخطاء TLS في dockerhub
  $docker_path pull $image || $docker_path pull $image
}

check_prereqs() {

  if [ -z $docker_path ]; then
    install_docker
  fi

  # 1. هل يعمل خادم docker؟
  # نرسل stderr إلى /dev/null لأننا لا نهتم بالتحذيرات،
  # عادة ما يشتكي عن التبديل الذي لا يهم
  test=`$docker_path info 2> /dev/null`
  if [[ $? -ne 0 ]] ; then
    echo "لا يمكن الاتصال بخادم docker - تأكد من أنه يعمل ولديك صلاحية الوصول"
    exit 1
  fi

  # 2. هل يعمل سائق تخزين معتمد؟
  if ! $docker_path info 2> /dev/null | egrep -q 'Storage Driver: (btrfs|aufs|zfs|overlay2)$'; then
    echo "تثبيت Docker الخاص بك لا يستخدم سائق تخزين مدعوم. إذا واصلنا قد يكون لديك تثبيت معطل."
    echo "overlay2 هو سائق التخزين الموصى به، على الرغم من أن zfs و aufs قد تعمل أيضًا."
    echo "من المعروف أن سائقي التخزين الآخرين يسببون مشاكل."
    echo "يمكنك معرفة نظام الملفات الذي تستخدمه بتشغيل \"docker info\" والنظر في سطر 'Storage Driver'."
    echo
    echo "إذا كنت ترغب في المتابعة على أي حال باستخدام سائق التخزين غير المدعوم الحالي،"
    echo "اقرأ كود المصدر للمشغل واكتشف كيفية تجاوز هذا الفحص."
    exit 1
  fi

  # 3. هل تعمل إصدار docker الموصى به
  test=($($docker_path --version))  # الحصول على سلسلة إصدار docker
  test=${test[2]//,/}  # الحصول على الإصدار فقط وإزالة الفاصلة إذا وجدت

  # على الأقل الحد الأدنى من إصدار docker
  if compare_version "${docker_min_version}" "${test}"; then
    echo "ERROR: إصدار Docker ${test} غير مدعوم، يرجى الترقية إلى الأقل ${docker_min_version}، أو الموصى به ${docker_rec_version}"
    exit 1
  fi

  # توصية بإصدار أحدث من docker
  if compare_version "${docker_rec_version}" "${test}"; then
    echo "WARNING: إصدار Docker ${test} قديم، نوصي بالترقية إلى ${docker_rec_version} أو أحدث."
  fi

  arm=false
  case $(uname -m) in
    armv7l)
      echo "ERROR: arm 32-bit غير مدعوم. تحقق مما إذا كان عتادك يدعم arm64، وهو مدعوم بقدرة تجريبية."
      exit 1
      ;;
    aarch64 | arm64)
      echo "WARNING: دعم aarch64 تجريبي في الوقت الحالي. يرجى الإبلاغ عن أي مشاكل في https://meta.discourse.org/tag/arm"
      image="discourse/base:aarch64"
      arm=true
      ;;
    x86_64)
      echo "تم اكتشاف بنية x86_64."
      ;;
    *)
      echo "ERROR: تم اكتشاف بنية غير معروفة."
      exit 1
      ;;
  esac


  # 4. تم تنزيل صورة discourse docker
  test=`$docker_path images | awk '{print $1 ":" $2 }' | grep "$image"`

  # دعم arm التجريبي على علامة ثابتة، دائمًا اسحب
  if [ -z "$test" ] || [ $arm = true ]; then
    echo
    echo "WARNING: نحن على وشك البدء في تنزيل صورة Discourse الأساسية"
    echo "قد تستغرق هذه العملية من بضع دقائق إلى ساعة، اعتمادًا على سرعة شبكتك"
    echo
    echo "يرجى التحلي بالصبر"
    echo

    pull_image
  fi

  # استخدام صورة أقدم للاستقرار
  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. هل يعمل إصدار git الموصى به
  test=($($git_path --version))  # الحصول على سلسلة إصدار git
  test=${test[2]//,/}  # الحصول على الإصدار فقط وإزالة الفاصلة إذا وجدت

  # على الأقل الحد الأدنى من الإصدار
  if compare_version "${git_min_version}" "${test}"; then
    echo "ERROR: إصدار Git ${test} غير مدعوم، يرجى الترقية إلى الأقل ${git_min_version}، أو الموصى به ${git_rec_version}"
    exit 1
  fi

  # توصية بأفضل إصدار
  if compare_version "${git_rec_version}" "${test}"; then
    echo "WARNING: إصدار Git ${test} قديم، نوصي بالترقية إلى ${git_rec_version} أو أحدث."
  fi

  # التحقق من الحد الأدنى من إصدار النواة بسبب https://bugs.ruby-lang.org/issues/13885
  test=($(uname -r))

  # على الأقل الحد الأدنى من الإصدار
  if compare_version "${kernel_min_version}" "${test}"; then
    echo "ERROR: إصدار النواة ${test} غير مدعوم، يرجى الترقية إلى الأقل ${kernel_min_version}"
    exit 1
  fi

  # 6. القدرة على إرفاق stderr / out / tty
  test=`$docker_path run $user_args -i --rm -a stdout -a stderr $image echo working`
  if [[ "$test" =~ "working" ]] ; then : ; else
    echo "تثبيت Docker الخاص بك لا يعمل بشكل صحيح"
    echo
    echo "راجع: https://meta.discourse.org/t/docker-error-on-bootstrap/13657/18?u=sam"
    exit 1
  fi

  # 7. مساحة كافية للتهيئة على مجلد docker
  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 "لديك أقل من 5 جيجابايت من المساحة الحرة على القرص الذي يقع فيه $safe_folder. ستحتاج إلى مساحة أكثر للمتابعة"
    df -h $safe_folder
    echo
    if tty >/dev/null; then
      read -p "هل ترغب في محاولة استعادة المساحة عن طريق تنظيف صور وحاويات docker في النظام؟ (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 "إذا كانت عملية التنظيف ناجحة، يمكنك المحاولة مرة أخرى الآن"
      fi
    fi
    exit 1
  fi

  # 8. ملف تعريف الحاوية قابل للوصول وليس غير آمن (قابل للقراءة عالميًا)
  if [[ ! -e "$config_file" || ! -r "$config_file" ]]; then
    echo "ERROR: $config_file غير موجود أو غير قابل للقراءة."
    echo
    echo "الإعدادات المتاحة ( `cd containers && ls -dm *.yml | tr -s '\n' ' ' | awk '{ gsub(/\.yml/, ""); print }'`)"
    exit 1
  elif [[ "$(find $config_file -perm -004)" ]]; then
    echo "WARNING: ملف $config_file قابل للقراءة عالميًا. يمكنك تأمين هذا الملف بتشغيل: 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

    # نريد دائمًا ملف الإعداد الخاص بنا في النهاية حتى يأخذ الأولوية
    input="$input _FILE_SEPERATOR_ $config_data"

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

    input=STDIN.readlines.join
    # الافتراضي إلى UTF-8 لحسن عمل قاعدة البيانات
    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. يرجى التحقق من ملفات الإعداد containers/*.yml الخاصة بك."
      exit 1
    fi

    # التسميات
    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. يرجى التحقق من ملفات الإعداد containers/*.yml الخاصة بك."
      exit 1
    fi

    # التعرض
    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. يرجى التحقق من ملفات الإعداد 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 "تم اكتشاف مجموعة بيانات احتياطية قديمة لـ PostgreSQL تشغل $(du -hs /var/discourse/shared/standalone/postgres_data_old | awk '{print $1}')"
    read -p "هل ترغب في إزالتها؟ (y/N): " -n 1 -r && echo

    if [[ $REPLY =~ ^[Yy]$ ]]; then
      echo "إزالة مجموعة بيانات PostgreSQL القديمة في /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 لم يتم تشغيله !"
       echo "قد يساعد ./discourse-doctor في تشخيص المشكلة."
       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 "لا شيء للقيام به، تم بدء الحاوية بالفعل!"
       exit 0
     fi

     existing=`$docker_path ps -a | awk '{ print $1, $(NF) }' | grep " $config$" | awk '{ print $1 }'`
     if [ ! -z $existing ]
     then
       echo "بدء الحاوية الموجودة"
       (
         set -x
         $docker_path start $config
       )
       exit 0
     fi
   fi

   set_template_info
   set_volumes
   set_links
   set_run_image
   set_boot_command

   # الحصول على اسم المضيف والإعدادات من إعدادات الحاوية
   for envar in "${env[@]}"
   do
     if [[ $envar == DOCKER_USE_HOSTNAME* ]] || [[ $envar == DISCOURSE_HOSTNAME* ]]
     then
       # استخدام كمتغير بيئة
       eval $envar
     fi
   done

   (
     hostname=`hostname -s`
     # تجاوز اسم المضيف
     if [ "$DOCKER_USE_HOSTNAME" = "true" ]
     then
       hostname=$DISCOURSE_HOSTNAME
     else
       hostname=$hostname-$config
     fi

     # يجب أن نطبيع حتى نحتوي فقط على سلاسل مسموح بها، هذا أكثر شمولاً لكن دعنا نرى كيف يتعامل bash أولاً
     # hostname=`$docker_path run $user_args --rm $image ruby -e 'print ARGV[0].gsub(/[^a-zA-Z-]/, "-")' $hostname`
     # docker أضاف المزيد من قواعد اسم المضيف
     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

  # قد لا يكون base_image دائمًا discourse/base،
  # دعنا نتأكد من أننا نبني دائمًا من أحدث إصدار
  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
    # العودة إلى طريقة git pull هنا إذا لم يتم تثبيت `pups` بواسطة gem في الصورة الأساسية
    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"

  # رمز خروج سحري يشير إلى إعادة محاولة
  if [[ $BOOTSTRAP_EXITCODE -eq 77 ]]; then
    $docker_path rm "$CONTAINER_ID"
    exit 77
  elif [[ $BOOTSTRAP_EXITCODE -gt 0 ]]; then
    echo "فشلت التهيئة برمز خروج $BOOTSTRAP_EXITCODE"
    echo "** فشل التهيئة ** يرجى التمرير للأعلى والنظر في رسائل الخطأ السابقة، قد يكون هناك أكثر من واحد."
    echo "قد يساعد ./discourse-doctor في تشخيص المشكلة."

    if [[ -n "$DEBUG" ]]; then
      if $docker_path commit "$CONTAINER_ID" $local_discourse/$config-debug; then
        echo "** DEBUG ** الحفاظ على الصورة للتشخيص $local_discourse/$config-debug"
      else
        echo "** DEBUG ** فشل في تأكيد الحاوية $CONTAINER_ID للتشخيص"
      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 "فشل في تأكيد $CONTAINER_ID"
  $docker_path rm "$CONTAINER_ID"
}

case "$command" in
  bootstrap)
      run_bootstrap
      echo "تم التهيئة بنجاح، للبدء استخدم ./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 "ضمان أن المشغل محدث"

        git remote update

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

        if [ $LOCAL = $REMOTE ]; then
          echo "المشغل محدث"

        elif [ $LOCAL = $BASE ]; then
          echo "تحديث المشغل..."
          git pull || (echo 'فشل التحديث' && exit 1)

          echo "تم تحديث المشغل، إعادة البدء..."
          exec "$0" "${SAVED_ARGV[@]}"

        elif [ $REMOTE = $BASE ]; then
          echo "نسخة المشغل الخاصة بك متقدمة عن الأصل"

        else
          echo "المشغل انحرف عن المصدر، هذا متوقع فقط في وضع التطوير"
        fi

      fi

      set_existing_container

      if [ ! -z $existing ]
        then
          echo "إيقاف الحاوية القديمة"
          (
            set -x
            $docker_path stop -t 60 $config
          )
      fi

      run_bootstrap

      if [ ! -z $existing ]
        then
          echo "إزالة الحاوية القديمة"
          (
            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 لم يتم العثور عليه" && exit 0)
      exit 0
      ;;
esac

usage

لإغلاق هذا الأمر، كشف توجيه بسيط من مدير المشروع أنه كانت هناك مشكلة في MaxMind، وإلغاء التعليق عليها سمح بإكمال التمهيد بنجاح. :+1: