Bootsnap::CompileCache::PermissionError

مرحبًا بالجميع. لدي نسخة جديدة من Discourse مُثبتة عبر Docker.
المشكلة هي أنه بعد إعادة بناء الحاوية، تعمل الحاوية ويمكنني الوصول إلى صفحة التطبيق. ومع ذلك، أحصل على استجابة 502. في السجلات أو عند محاولة الدخول مثل rails c (داخل الحاوية)، كل ما يمكنني رؤيته هو هذا الخطأ:
`permission_error’: bootsnap doesn’t have permission to write cache entries in ‘tmp/cache/bootsnap/compile-cache’ (or, less likely, doesn’t have permission to read ‘/usr/local/lib/ruby/2.7.0/set.rb’) (Bootsnap::CompileCache::PermissionError)

لحل هذه المشكلة، يجب أن أنفذ أمر chown -R discourse:discourse /var/www/discourse/tmp (لتوضيح أكثر، هو الدليل /var/www/discourse/tmp/cache/bootsnap) داخل الحاوية، وعندها فقط يعمل التطبيق بشكل صحيح حتى بدون إعادة تشغيل. إنه أمر مزعج جدًا يجب تنفيذه يدويًا بعد كل إعادة بناء.

فكرت في أن أتعامل مع هذه المشكلة باستخدام قسم الأوامر المخصصة في ملف app.yml مع الأمر المذكور أعلاه chown -R discourse:discourse /var/www/discourse/tmp، لكن للأسف لم ينجح ذلك. يبدو أن الأوامر تُنفذ هناك (جربت mkdir فقط للتحقق)، لكن صلاحيات الملفات لا تتأثر.

ما قد يكون المشكلة هنا وكيف يمكن حلها؟ هل هناك طريقة صحيحة لتغيير صلاحيات الملفات؟

هذا غريب. هل اتبعت التثبيت القياسي الرسمي لـ Discourse؟

بالتأكيد. لم تُتخذ أي خطوات إضافية.

هل يمكنك لصق ملف container.yml الخاص بك (بدون كلمات المرور)؟

بالتأكيد. إليك الملف:

## هذا قالب حاوية Docker شاملة ومستقلة لـ Discourse
##
## بعد إجراء أي تعديلات على هذا الملف، يجب عليك إعادة البناء
## /var/discourse/launcher rebuild app
##
## كن *حذرًا للغاية* عند التحرير!
## ملفات YAML حساسة للغاية للأخطاء في المسافات البيضاء أو المحاذاة!
## قم بزيارة http://www.yamllint.com/ للتحقق من صحة هذا الملف حسب الحاجة

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## قم بإلغاء التعليق عن هذين السطرين إذا كنت ترغب في إضافة Lets Encrypt (https)
  - "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"

## ما هي منافذ TCP/IP التي يجب أن تعرضها هذه الحاوية؟
## إذا كنت تريد لـ Discourse مشاركة منفذ مع خادم ويب آخر مثل Apache أو nginx،
## راجع https://meta.discourse.org/t/17247 للحصول على التفاصيل
expose:
  - "80:80"   # http
  - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## قم بتعيين db_shared_buffers إلى حد أقصى 25% من إجمالي الذاكرة.
  ## سيتم تعيينه تلقائيًا بواسطة bootstrap بناءً على الذاكرة المكتشفة، أو يمكنك تجاوز ذلك
  #db_shared_buffers: "256MB"

  ## يمكن أن يحسن أداء الفرز، لكنه يضيف استخدام الذاكرة لكل اتصال
  #db_work_mem: "40MB"

  ## أي إصدار Git يجب أن تستخدمه هذه الحاوية؟ (الافتراضي: tests-passed)
  #version: tests-passed

env:
  LC_ALL: en_US.UTF-8
  LANG: en_US.UTF-8
  LANGUAGE: en_US.UTF-8
  # DISCOURSE_DEFAULT_LOCALE: en

  ## كم عدد طلبات الويب المتزامنة المدعومة؟ يعتمد على الذاكرة وأنوية المعالج.
  ## سيتم تعيينه تلقائيًا بواسطة bootstrap بناءً على وحدات المعالجة المركزية المكتشفة، أو يمكنك تجاوز ذلك
  #UNICORN_WORKERS: 3

  ## TODO: اسم النطاق الذي ستستجيب له هذه النسخة من Discourse
  ## مطلوب. لن يعمل Discourse مع عنوان IP مجرد.
  DISCOURSE_HOSTNAME: 'example.com'

  ## قم بإلغاء التعليق إذا كنت تريد بدء الحاوية بنفس
  ## اسم المضيف (خيار -h) المحدد أعلاه (الافتراضي "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: قائمة عناوين البريد الإلكتروني المفصولة بفواصل سيتم تعيينها كمسؤول ومطور
  ## عند التسجيل الأولي، مثال 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'test@mail.com'

  ## TODO: خادم البريد SMTP المستخدم للتحقق من الحسابات الجديدة وإرسال الإشعارات
  ## عنوان SMTP واسم المستخدم وكلمة المرور مطلوبة
  ## تحذير: قد يسبب حرف '#' في كلمة مرور SMTP مشاكل!
  DISCOURSE_SMTP_ADDRESS: smtp.mail.io
  #DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: 111
  DISCOURSE_SMTP_PASSWORD: 111
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (اختياري، الافتراضي true)
  #DISCOURSE_SMTP_DOMAIN: discourse.example.com    # (مطلوب من بعض المزودين)
  #DISCOURSE_NOTIFICATION_EMAIL: noreply@discourse.example.com    # (العنوان المرسل منه الإشعارات)

  ## إذا أضفت قالب Lets Encrypt، قم بإلغاء التعليق أدناه للحصول على شهادة SSL مجانية
  #LETSENCRYPT_ACCOUNT_EMAIL: me@example.com

  ## عنوان CDN http أو https لهذه النسخة من Discourse (مُعد للاستخراج)
  ## راجع https://meta.discourse.org/t/14857 للحصول على التفاصيل
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com
  
  ## مفتاح عنوان IP لموقع Maxmind الجغرافي للبحث عن عناوين IP
  ## راجع https://meta.discourse.org/t/-/137387/23 للحصول على التفاصيل
  #DISCOURSE_MAXMIND_LICENSE_KEY: 1234567890123456

## حاوية Docker لا تحتوي على حالة؛ يتم تخزين جميع البيانات في /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## تذهب الإضافات هنا
## راجع https://meta.discourse.org/t/19157 للحصول على التفاصيل
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

## أي أوامر مخصصة للتشغيل بعد البناء
run:
  - exec: echo "Beginning of custom commands"
  ## إذا كنت تريد تعيين عنوان البريد الإلكتروني 'From' لأول تسجيل، قم بإلغاء التعليق وتغييره:
  ## بعد الحصول على أول بريد إلكتروني للتسجيل، أعد تعليق السطر. يجب تشغيله مرة واحدة فقط.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  #- exec: chown -R discourse:discourse /var/www/discourse/tmp/cache/bootsnap  # مثال على أمر حاولت من خلاله إصلاح أذونات الملفات
  - exec: echo "End of custom commands"

ألم تقم بتشغيل discourse-setup؟ كان يجب أن يُعرِّف بعض الأشياء التي قمت بإزالتها بالتعليق. لقد قمت بتطبيق هذه التغييرات وأريد التأكد من أنها تعمل كما هو متوقع.

هل هناك سبب لعدم استخدامك لـ let’s encrypt؟

مع ذلك، لا أرى أي تفسير لمشكلتك.

أولاً، تم بناء التطبيق باستخدام discourse-setup. بعد عدة محاولات لإعادة بنائه دون الحصول على نتيجة إيجابية، انتقلت إلى أحد ملفات التكوين المحددة مسبقًا (.yml) الموجودة في مجلد /samples، ثم قمت ببساطة بتعديلها باستخدام بيانات اعتماد الخاصة بي.

لماذا لا نستخدم Let’s Encrypt؟ طُلب استخدام شهادات العميل. ولكن بقدر ما أفهم، لا علاقة للشهادات بذلك، فهي صالحة ولا توجد مشكلة منها.

يبدو أن المشكلة على مستوى المشروع، وهي مرتبطة تحديدًا بأذونات ملف ذاكرة التخزين المؤقت لـ bootsnap (ربما تكون المشكلة من جانب Bootsnap).

شكرًا لك. أوافق على أن هذا غير مرجح أن يكون هو المشكلة. قمت بتثبيتين أمس نجحا تمامًا. لا أرى أي تفسير لمشكلتك.

كنا نواجه نفس المشكلة، وأؤكد أن تشغيل الأمر التالي (داخل حاوية Docker):

chown -R discourse:discourse /var/www/discourse/tmp

قد حل المشكلة! لم يكن هناك حاجة لإعادة التشغيل. كانت أذونات مجلد ‘tmp’ مُعيّنة سابقًا لـ ‘discourse:www-data’ قبل تغيير المالك. آمل أن يتم إصلاح هذا الأمر في المستقبل بحيث لا تكون هناك حاجة إلى هذا الإجراء اليدوي بعد كل إعادة بناء.

هل تشغّل المشغّل بصلاحيات الجذر؟

نعم @pfaffman، أنا كذلك. هل هذه هي المشكلة؟

لا أعتقد ذلك. أنا دائمًا أبدأ مثيلاتي المستضافة ذاتيًا بصلاحيات الجذر (root) ولم أرَ مشكلة مثل هذه من قبل.

من هو مالك الدليل إذا لم تستخدم الأمر chown؟ في حاوية تم إعادة بنائها مؤخرًا، يبدو الأمر كالتالي:

# ls -l /var/www/discourse/tmp
total 36
lrwxrwxrwx 1 root      root         19 Mar  2 14:56 backups -> /shared/tmp/backups
drwxr-xr-x 1 discourse discourse  4096 Mar  2 14:57 cache
drwxr-xr-x 1 discourse discourse  4096 Mar  2 14:57 ember-rails
drwxr-xr-x 1 discourse root       4096 Mar  2 15:04 pids
lrwxrwxrwx 1 root      root         20 Mar  2 14:56 restores -> /shared/tmp/restores
drwxr-xr-x 2 discourse root       4096 Mar  2 14:56 sockets
drwxr-xr-x 2 discourse discourse 12288 Mar  2 15:02 stylesheet-cache

هل أضفت أي أوامر مخصصة أو روابط (hooks) إلى ملف app.yml الخاص بك بخلاف استنساخ الإضافات؟

كان مالك المستخدم والمجموعة لمجلد /var/www/discourse/tmp هو discourse:www-data بعد تشغيل الحاوية. إعادة التعيين إلى discourse:discourse حلّت المشكلة. لم يحدث لي هذا من قبل رغم أنني أستخدم discourse منذ عدة أشهر. على أي حال، كان الإصلاح سهلاً وقد يكون الأمر عشوائيًا، لذا لا أريد إزعاجكم به أكثر من هذا. شكرًا جزيلاً @gerhard!