فشل الترقية: مخرج "before-server" الخاص بـ Nginx مفقود... discourse_docker غير متوافق مع إصدار Discourse المختار

لدي خادم Discourse ينتج عنه ./launcher rebuild app ما يلي:

FAILED
--------------------
Pups::ExecError: grep -q 'outlets/before-server' /etc/nginx/conf.d/discourse.conf || ( >&2 echo 'The "before-server" Nginx outlet is missing. This version of discourse_docker is not compatible with the chosen Discourse version.' ; exit 1 ) failed with return #<Process::Status: pid 300 exit 1>
Location of failure: /usr/local/lib/ruby/gems/3.3.0/gems/pups-1.3.0/lib/pups/exec_command.rb:131:in `spawn'
exec failed with the params {"cmd"=>["cp $home/config/nginx.sample.conf /etc/nginx/conf.d/discourse.conf", "rm /etc/nginx/sites-enabled/default", "mkdir -p /var/nginx/cache", "grep -q 'outlets/before-server' /etc/nginx/conf.d/discourse.conf || ( >&2 echo 'The \\\"before-server\\\" Nginx outlet is missing. This version of discourse_docker is not compatible with the chosen Discourse version.' ; exit 1 )", "grep -q 'outlets/server' /etc/nginx/conf.d/discourse.conf || ( >&2 echo 'The \\\"server\\\" Nginx outlet is missing. This version of discourse_docker is not compatible with the chosen Discourse version.' ; exit 1 )", "grep -q 'outlets/discourse' /etc/nginx/conf.d/discourse.conf || ( >&2 echo 'The \\\"discourse\\\" Nginx outlet is missing. This version of discourse_docker is not compatible with the chosen Discourse version.' ; exit 1 )", "mkdir -p /etc/nginx/conf.d/outlets/before-server", "touch /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf", "touch /etc/nginx/conf.d/outlets/before-server/30-ratelimited.conf", "mkdir -p /etc/nginx/conf.d/outlets/server", "touch /etc/nginx/conf.d/outlets/server/10-http.conf", "touch /etc/nginx/conf.d/outlets/server/20-https.conf", "touch /etc/nginx/conf.d/outlets/server/30-offline-page.conf", "mkdir -p /etc/nginx/conf.d/outlets/discourse", "touch /etc/nginx/conf.d/outlets/discourse/20-https.conf", "touch /etc/nginx/conf.d/outlets/discourse/30-ratelimited.conf"]}
bootstrap failed with exit code 1
** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one.
./discourse-doctor may help diagnose the problem.
727ce99bf07d8a65ba26b70f4515a2b6dab493ca00f436098de95e70604b6d6b

الكود محدث:

git status
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

لقد حاولت تشغيل ./discourse-doctor ولكن نتج عنه نفس الخطأ.

الخادم المعني يعمل بنظام Ubuntu:

cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=24.04
DISTRIB_CODENAME=noble
DISTRIB_DESCRIPTION="Ubuntu 24.04.2 LTS"

مع أحدث Docker:

apt info docker-ce
Package: docker-ce
Version: 5:28.3.2-1~ubuntu.24.04~noble
Priority: optional
Section: admin
Maintainer: Docker <support@docker.com>
Installed-Size: 90.1 MB
Pre-Depends: init-system-helpers (>= 1.54~)
Depends: containerd.io (>= 1.6.24), docker-ce-cli, iptables, libc6 (>= 2.34), libsystemd0
Recommends: apparmor, ca-certificates, docker-ce-rootless-extras, git, pigz, procps, xz-utils
Suggests: cgroupfs-mount | cgroup-lite, kmod
Conflicts: docker (< 1.5~), docker-engine, docker.io
Replaces: docker-ce-cli (< 5:28.0.0), docker-engine
Homepage: https://www.docker.com
Download-Size: 19.6 MB
APT-Manual-Installed: yes
APT-Sources: https://download.docker.com/linux/ubuntu noble/stable amd64 Packages
Description: Docker: the open-source application container engine
 Docker is a product for you to build, ship and run any application as a
 lightweight container
 .
 Docker containers are both hardware-agnostic and platform-agnostic. This means
 they can run anywhere, from your laptop to the largest cloud compute instance and
 everything in between - and they don't require you to use a particular
 language, framework or packaging system. That makes them great building blocks
 for deploying and scaling web apps, databases, and backend services without
 depending on a particular stack or provider.

N: There are 34 additional records. Please use the '-a' switch to see them.

هل لدى أي شخص أي اقتراحات؟ هل أحتاج إلى تعديل تكوين Nginx يدويًا في الحاوية قيد التشغيل لتجاوز هذا أم شيء من هذا القبيل؟

لقد حاولت الرجوع إلى إصدار أقدم من قاعدة كود docker_manager إلى الإصدار قبل آخر تثبيت في 10 يوليو 2025:

su - discourse
cd /var/discourse/
./launcher enter app
su - discourse
cd /var/www/discourse/plugins/docker_manager
git checkout d91016c
exit
exit
./launcher rebuild app

لكن ذلك لم يحدث فرقًا.

لقد أجريت إعادة بناء للتو دون أي مشاكل. هل توجد أخطاء أخرى أعلى مما أدرجته؟

ماذا يُظهر الأمر free -h؟

إنها ليست مشكلة مساحة قرص:

df -h
نظام الملفات      الحجم  المستخدم  المتاح  الاستخدام%  مركب على
tmpfs           588M  1.1M  587M   1% /run
/dev/sda2       118G   79G   34G  71% /
tmpfs           2.9G     0  2.9G   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           588M   12K  588M   1% /run/user/1001

الخادم لا يحتوي على أي مساحة تبديل (swap) ولكنه يحتوي على 6 جيجابايت من ذاكرة الوصول العشوائي (RAM):

free -h
               الإجمالي        المستخدم        المتاح      مشترك  المخزن المؤقت/الذاكرة المخبأة   المتاح
الذاكرة:           5.7Gi       793Mi       1.2Gi       1.0Mi       4.1Gi       5.0Gi
التبديل:             0B          0B          0B

هل تعتقد أن هناك حاجة لقرص تبديل؟

فيما يلي محتويات تكوين Nginx (/etc/nginx/conf.d/discourse.conf) في الحاوية، لم يكن هناك أي إشارة إلى outlets/before-server:

# أنواع MIME الإضافية التي ترغب في أن يتعامل معها nginx توضع هنا
types {
    text/csv csv;
}

upstream discourse { server 127.0.0.1:3000; }

proxy_cache_path /var/nginx/cache keys_zone=one:10m max_size=200m;

# انظر: https://meta.discourse.org/t/x/74060
proxy_buffer_size 8k;

# إذا كنت ستستخدم Puma، استخدم هذه:
#
# upstream discourse {
#   server unix:/var/www/discourse/tmp/sockets/puma.sock;
# }


# محاولة الحفاظ على البروتوكول، يجب أن يكون في سياق http
map $http_x_forwarded_proto $thescheme {
  default $scheme;
  https https;
}

log_format log_discourse '[$time_local] \"$http_host\" $remote_addr \"$request\" \"$http_user_agent\" \"$sent_http_x_discourse_route\" $status $bytes_sent \"$http_referer\" $upstream_response_time $request_time \"$sent_http_x_discourse_username\"';

limit_req_zone $binary_remote_addr zone=flood:10m rate=12r/s;
limit_req_zone $binary_remote_addr zone=bot:10m rate=200r/m;
limit_req_status 429;
limit_conn_zone $binary_remote_addr zone=connperip:10m;
limit_conn_status 429;
server {
  listen 80;
  return 301 https://discourse.example.org$request_uri;
}
server {


  access_log /var/log/nginx/access.log log_discourse;

  listen 443 ssl;
http2 on;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

ssl_certificate /shared/ssl/discourse.example.org.cer;
ssl_certificate /shared/ssl/discourse.example.org_ecc.cer;

ssl_certificate_key /shared/ssl/discourse.example.org.key;
      proxy_ignore_headers "Set-Cookie";
      proxy_hide_header "Set-Cookie";

      proxy_cache one;
      proxy_cache_key $uri;
      proxy_cache_valid 200 7d;
      proxy_cache_valid 404 1m;
      proxy_set_header Connection "";

      proxy_pass https://avatars.discourse.org/;
      break;
    }

    # نحتاج إلى تعطيل التخزين المؤقت لحافلة الرسائل
    location /message-bus/ {
      proxy_set_header X-Request-Start "t=${msec}";
      proxy_set_header Host $http_host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $thescheme;
      proxy_http_version 1.1;
      proxy_buffering off;
      proxy_pass http://discourse;
      break;
    }

    # هذا يعني أنه يتم محاولة كل ملف في public أولاً
    try_files $uri @discourse;
  }

  location /downloads/ {
    internal;
    alias $public/;
  }

  location @discourse {
add_header Strict-Transport-Security 'max-age=31536000'; # تذكر الشهادة لمدة عام وتصل تلقائيًا إلى HTTPS لهذا النطاق
limit_conn connperip 20;
  limit_req zone=flood burst=12 nodelay;
  limit_req zone=bot burst=100 nodelay;
    add_header Referrer-Policy 'no-referrer-when-downgrade';
    proxy_set_header Host $http_host;
    proxy_set_header X-Request-Start "t=${msec}";
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $thescheme;
    proxy_pass http://discourse;
  }

}

لذلك قمت بتثبيت vim و dos2unix وقمت بتحرير الملفات لإضافة السطر:

include conf.d/outlets/before-server/*.conf;

وأوقفت nginx وبدأت تشغيله ثم خرجت من الحاوية وقمت بتشغيل ./launcher rebuild app مرة أخرى ولكن تم إرجاع نفس الخطأ:

FAILED
--------------------
Pups::ExecError: grep -q 'outlets/before-server' /etc/nginx/conf.d/discourse.conf || ( >&2 echo 'The "before-server" Nginx outlet is missing. This version of discourse_docker is not compatible with the chosen Discourse version.' ; exit 1 ) failed with return #<Process::Status: pid 300 exit 1>
Location of failure: /usr/local/lib/ruby/gems/3.3.0/gems/pups-1.3.0/lib/pups/exec_command.rb:131:in `spawn'
exec failed with the params {"cmd"=>["cp $home/config/nginx.sample.conf /etc/nginx/conf.d/discourse.conf", "rm /etc/nginx/sites-enabled/default", "mkdir -p /var/nginx/cache", "grep -q 'outlets/before-server' /etc/nginx/conf.d/discourse.conf || ( >&2 echo 'The \"before-server\" Nginx outlet is missing. This version of discourse_docker is not compatible with the chosen Discourse version.' ; exit 1 )", "grep -q 'outlets/server' /etc/nginx/conf.d/discourse.conf || ( >&2 echo 'The \"server\" Nginx outlet is missing. This version of discourse_docker is not compatible with the chosen Discourse version.' ; exit 1 )", "grep -q 'outlets/discourse' /etc/nginx/conf.d/discourse.conf || ( >&2 echo 'The \"discourse\" Nginx outlet is missing. This version of discourse_docker is not compatible with the chosen Discourse version.' ; exit 1 )", "mkdir -p /etc/nginx/conf.d/outlets/before-server", "touch /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf", "touch /etc/nginx/conf.d/outlets/before-server/30-ratelimited.conf", "mkdir -p /etc/nginx/conf.d/outlets/server", "touch /etc/nginx/conf.d/outlets/server/10-http.conf", "touch /etc/nginx/conf.d/outlets/server/20-https.conf", "touch /etc/nginx/conf.d/outlets/server/30-offline-page.conf", "mkdir -p /etc/nginx/conf.d/outlets/discourse", "touch /etc/nginx/conf.d/outlets/discourse/20-https.conf", "touch /etc/nginx/conf.d/outlets/discourse/30-ratelimited.conf"]}
bootstrap failed with exit code 1
** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one.
./discourse-doctor may help diagnose the problem.
b18ed0cbde3a34dfe76ea066657ece16c5a063ff18627d4a7e4b9787268917c0

لذلك قمت بإعادة تشغيل الحاوية (./launcher start app) للتحقق من ذلك:

grep -q 'outlets/before-server' /etc/nginx/conf.d/discourse.conf
echo $?
0

لذلك لا أفهم لماذا يفشل عندما يكون تضمين Nginx موجودًا؟

هناك الكثير من الاختلافات بين /var/www/discourse/config/nginx.sample.conf و /etc/nginx/conf.d/discourse.conf - هل يجب أن أحاول استبدال الملف بالنموذج وتحريره لتحديث اسم النطاق؟

تحديث

في وقت سابق، لم تسمح واجهة الويب الخاصة بـ Discourse بالتحديثات، وذكرت أن التحديثات يجب أن تتم باستخدام سطر الأوامر، ولكن الآن تسمح بها (لماذا؟) لذلك قمت بتحديث discourse_docker باستخدام واجهة الويب:

وأيضًا discourse:

لذلك تم حل هذه المشكلة ولكن ما فعلته، إن وجد، لحلها هو لغز… :woman_shrugging:

لقد تعقبت المشكلة — لقد تسبب بها المكون الإضافي discourse-images-guardian من @mbcahyono والذي كان بحاجة إلى تحديث ملف nginx.sample.conf، لقد قمت بذلك وأنشأت طلب سحب لإصلاحه.

تم الدمج! شكرًا على طلب السحب.

لم تتح لي الفرصة لاختباره، لذا أثق بك في هذا الأمر :slight_smile:

إعجاب واحد (1)

شكرا @mbcahyono لقد أجريت بعض الاختبارات الأساسية ويبدو أنها تعمل…! ومع ذلك، هذه المشكلة — تجاوز عناوين URL لصور الموقع لم تعد تعمل، أي أفكار حول كيفية إصلاح هذا؟

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.