خطأ Bootstrap أثناء تثبيت Discourse: ENOENT - /etc/runit/1.d/letsencrypt

مرحباً، أحاول تثبيت Discourse باستخدام العملية القياسية ./discourse-setup، ولكني أواجه خطأ أثناء التهيئة الأولية:

FAILED
--------------------
Errno::ENOENT: لا يوجد مثل هذا الملف أو الدليل @ rb_sysopen - /etc/runit/1.d/letsencrypt
موقع الفشل: /usr/local/lib/ruby/gems/3.3.0/gems/pups-1.3.0/lib/pups/replace_command.rb:11:in `read'
فشل الاستبدال بالمعلمات {"filename"=>"/etc/runit/1.d/letsencrypt", "from"=>"/--keylength/", "to"=>"-d forum.mysite.org --keylength"}
فشلت التهيئة الأولية برمز خروج 1
** فشل في التهيئة الأولية ** يرجى التمرير لأعلى والبحث عن رسائل خطأ سابقة، قد يكون هناك أكثر من واحدة.

يبدو أن الخطأ ناتج عن إضافة تحاول تشغيل أمر replace على الملف /etc/runit/1.d/letsencrypt، والذي لا يوجد داخل الحاوية أثناء التهيئة الأولية. السطر ذو الصلة في الإضافة يبدو كالتالي:

- replace:
    filename: "/etc/runit/1.d/letsencrypt"
    from: "/--keylength/"
    to: "-d forum.mysite.org --keylength"

أي نصائح حول كيفية إصلاح هذا أو إعادة إنشاء الملف المفقود بشكل صحيح؟

شكراً مقدماً.

إضافة؟ هذا هو كود cups من ملف app.yml الخاص بك، أليس كذلك؟ هل تحاول إضافة شهادة أخرى؟ مثل في Set up Let’s Encrypt with multiple domains / redirects هل يمكنك تضمين الكود الفعلي وكلا الشهادتين؟

كما أشرت، لم يعد runit موجودًا، والآن هذا السحر موجود في /usr/local/bin/letsencrypt (داخل الحاوية)

أعتقد ربما تريد شيئًا كهذا إذا كان موقعك هو www.mysite.org وتريد أيضًا أن يكون لديه شهادة لـ forum.mysite.org:

- replace:
    filename: "/usr/local/bin/letsencrypt"
    from: "/-d www.mysite.org/"
    to: "-d www.mysite.org -d forum.mysite.org "
    global: true

ما سأفعله (والذي قد لا يكون مفيدًا لك) هو الدخول إلى الحاوية، وتشغيل apt update;apt install -y vim ثم تعديل /usr/local/bin/letsencrypt بحيث يطلب الشهادات التي تريدها.

لقد أضفت كودًا إلى موضوع let’s encrypt المرتبط أعلاه والذي يجب أن يسمح لك بإدخال نطاقك والحصول على كود يمكنك نسخه/لصقه في ملف app.yml الخاص بك.

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

لقد واجهت ما يبدو أنه نفس رسالة الخطأ أثناء محاولة التحديث.

لا أحاول تغيير أي شيء يتعلق بالشهادات.

ملف app.yml الخاص بي يظهر هذا حاليًا:

 after_ssl:
    - replace:
        filename: "/etc/runit/1.d/letsencrypt"
        from: /--keylength/
        to: "-d www.nzarchitecture.net.nz --keylength"

لقد اتبعت اقتراحك:

 apt update;apt install -y vim

لكن النتيجة كانت ‘vim is already the newest version (2:9.1.0016-1ubuntu7.8).’

أما بالنسبة للخطوة الثانية المقترحة، فلا أعرف أي شهادات أريد، حيث لم تكن لدي نية لتغيير أي شيء.

حسنًا، بعد بضع ساعات من العناء، تمكنت من العودة إلى العمل مرة أخرى.

لقد وجدت ملف app.yml قديمًا واستبدلته، وحذفت فقط الإشارات القديمة إلى المكونات الإضافية التي تم دمجها منذ ذلك الحين في Discourse.

لم يحتوي ملف app.yml الأقدم هذا على الكود أدناه، والذي وجدته في ملف أحدث.

 after_ssl:
    - replace:
        filename: "/etc/runit/1.d/letsencrypt"
        from: /--keylength/
        to: "-d www.nzarchitecture.net.nz --keylength"

لا أتذكر أنني وضعت هذا الكود بنفسي على الرغم من أنني قمت بإعداد موقعي لاستخدام letsencrypt لشهادات الأمان المجانية، ولكن التعليمات الموجودة على Set up HTTPS support with Let's Encrypt لا تبدو تتطلب هذه الأسطر على الإطلاق، لذا لا أعرف ما الغرض منها.

هل يمكن أن يكون أي شيء آخر قد أضاف هذه الأسطر إلى app.yml؟ على سبيل المثال، هل يمكن إضافتها أثناء تحديث تجريبي؟

على الأقل في الوقت الحالي، مع إزالة هذه الأسطر، يعمل موقعي مرة أخرى وهو محدث.

عندما تنتهي صلاحية شهادة SSL الحالية الخاصة بي، أعتقد أنني قد أكتشف ما الغرض من هذه الأسطر الإضافية.

حسنًا، نعم أنت كذلك، لكنك لا تتذكر. :wink:

إذا كان لديك هذا المقطع after_ssl في ملف yml الخاص بك، فقد قمت في وقت ما بإعداد الأمور بحيث إذا قام شخص ما بإضافة www أمام نطاقك، فسيتم توجيهه إلى عنوان www وإعادة توجيهه إلى عنوان غير www دون خطأ في الشهادة.

كان اقتراحي هو تثبيت vim داخل الحاوية ومحاولة العبث بالملفات هناك، لكنني أعتقد أن الكود الخاص بي الذي سأضيفه إلى app.yml يجب أن يعمل.

صحيح. والآن إذا قمت بزيارة https://www.nzarchitecture.net.nz/ تحصل على خطأ في الشهادة. يمكنك استخدام https://forcewww.com/

يمكنك الذهاب إلى الرابط أعلاه والحصول على الكود الجديد الذي أعتقد أنه يجب أن يعمل، لكنني لم أختبره لأنني لم أجد موقعًا أقوم بترقيته يحتاج إليه.

هل أنا على حق في أن الكود الخاص بك سيكون على طول الأسطر أدناه، إذا كنت أريد أن يتم تغطية www.nzarchitecture.net.nz بنفس شهادة letsencrypt مثل nzarchitecture.net.nz؟

after_ssl:
    - replace:
        filename: /usr/local/bin/letsencrypt
        from: /-d nzarchitecture.net.nz /
        to: "-d nzarchitecture.net.nz -d www.nzarchitecture.net.nz "
        global: true

لقد حاولت إضافة هذه المقطع (مصطلحات رائعة، شكرًا!) إلى نهاية app.yml، بدلاً من مقطع ’after_ssl:’ الأصلي، والآن يمكنني إعادة بناء Discourse بدون أخطاء - ولكن هذا لا يبدو أنه يساعدني؛ لا يزال متصفحي يرمي استجابة ‘net::ERR_CERT_COMMON_NAME_INVALID’ إذا حاولت استخدام بادئة ‘www’ قبل النطاق الرئيسي/المعتمد الخاص بي nzarchitecture.net.nz

ملف app.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"
  - "templates/import/mysql-dep.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: "128MB"

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

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

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

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

  ## TODO: اسم النطاق الذي ستستجيب له هذه النسخة من Discourse
  ## مطلوب. لن تعمل Discourse برقم IP فارغ.
  DISCOURSE_HOSTNAME: nzarchitecture.net.nz

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

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

  ## TODO: خادم البريد SMTP المستخدم للتحقق من الحسابات الجديدة وإرسال الإشعارات
  # عنوان SMTP واسم المستخدم وكلمة المرور مطلوبة
  # تحذير الحرف '#' في كلمة مرور SMTP يمكن أن يسبب مشاكل!
  DISCOURSE_SMTP_ADDRESS: smtp.mailgun.org
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: ****************
  DISCOURSE_SMTP_PASSWORD: "****************"
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (اختياري، الافتراضي صحيح)

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

  ## عنوان CDN http أو https لهذه النسخة من Discourse (تم تكوينه للسحب)
  ## انظر https://meta.discourse.org/t/14857 للحصول على التفاصيل
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

## حاوية 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
          - git clone https://github.com/discourse/discourse-bbcode.git
## أي أوامر مخصصة لتشغيلها بعد البناء
run:
  - exec: echo "Beginning of custom commands"
  ## إذا كنت تريد تعيين عنوان البريد الإلكتروني 'من' لتسجيلك الأول، قم بإلغاء التعليق والتغيير:
  ## بعد الحصول على البريد الإلكتروني الأول للتسجيل، أعد التعليق على السطر. يحتاج فقط إلى التشغيل مرة واحدة.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "End of custom commands"

after_ssl:
    - replace:
        filename: /usr/local/bin/letsencrypt
        from: /-d nzarchitecture.net.nz /
        to: "-d nzarchitecture.net.nz -d www.nzarchitecture.net.nz "
        global: true

هل حقيقة عدم وجود ملفات في /usr/local/bin/ جزء من المشكلة؟

أين أجد ملف letsencrypt الصحيح لوضعه هناك، إذا كان هذا ما هو مطلوب؟

و، إذا كان ‘letsencrypt’ هو اسم الملف في نهاية هذا المسار، فهل من الطبيعي عدم وجود امتداد ملف كجزء من اسم الملف هذا؟

فكرتي هي إزالة السطر after_ssl وإلغاء المسافة البادئة للأسطر الأخرى.

إذا أضفت مفتاح ssh الخاص بي باستخدام

ssh-import-id-gh pfaffman

وأرسلت لي بريدًا إلكترونيًا، فسأرى ما يمكنني فعله.

شكرا! @pfaffman

لقد أرسلت لك بريدًا إلكترونيًا الآن

Here’s an update.

Adding this to the run section at the bottom of your app.yml will solve the problem of getting /usr/local/bin/letsencrypt to request certificates for DISCOURSE_HOSTNAME and www.DISCOURSE_HOSTNAME.

- exec: sed -i "s|-d \\${DISCOURSE_HOSTNAME}|-d \\${DISCOURSE_HOSTNAME} -d www.\\${DISCOURSE_HOSTNAME}|g" /usr/local/bin/letsencrypt

This (somehow?) used to be enough, but now when the request comes in for http://www.HOSTNAME/.well-known… it gets redirected to the non www site rather than sending the challenge that it’s supposed to send. I tried to do something like this:

server {
  listen 80;
  listen [::]:80;
  server_name nzarchitecture.net.nz www.nzarchitecture.net.nz;

  # Serve ACME challenge (Let's Encrypt)
  location ^~ /.well-known/acme-challenge/ {
    root /var/www/discourse/public;  # Make sure this matches your Let's Encrypt webroot
    allow all;
  }

  # Redirect everything else to HTTPS
  location / {
    return 301 https://$host$request_uri;
  }
}

but didn’t quite figure it out.

If anyone from team is listening, it would be good if there were a letsencrypt hook so that this could be called in an after_letsencrypt. Before making these changes in after_ssl worked, but it seems that now if we do that this gets run after ssl, but before letsencrypt.

3 إعجابات

أواجه هذه المشكلة أيضًا. سأعلمك إذا تمكنت من إصلاحها.

DISCOURSE_HOSTNAME الخاص بي هو www.textkit.com. أنا أفعل عكس nzarchitecture.net.nz وأضيف اسم مضيف بدون www إلى شهادتي. نجح هذا معي:

- exec: sed -i "s|-d \\${DISCOURSE_HOSTNAME}|-d www.textkit.com -d textkit.com|g" /usr/local/bin/letsencrypt

لا يمكنني القول لماذا قد يواجه @pfaffman و nzarchitecture.net.nz مشكلة في نسخته، على الرغم من أن ترتيب أسماء المضيفين في نسختي قد يكون ذا صلة.

لقد واجهت هذا أيضًا.

لقد قمت بإزالة هذا (عن طريق التعليق عليه):

  after_ssl:
#    - replace:
#        filename: "/etc/runit/1.d/letsencrypt"
#        from: /--keylength/
#        to: "-d example.com --keylength"
#    - replace:
#        filename: "/etc/nginx/conf.d/discourse.conf"
#        from: /return 301 https.+/
#        to: |
#          return 301 https://$host$request_uri;

وأضافت هذا في قسم التشغيل في الأسفل حسب @pfaffman

- exec: sed -i "s|-d \\${DISCOURSE_HOSTNAME}|-d \\${DISCOURSE_HOSTNAME} -d www.\\${DISCOURSE_HOSTNAME}|g" /usr/local/bin/letsencrypt

يبدو أن هذا كان كافيًا بالنسبة لي:

  • أعيد بناء الموقع ويبدو أنه يحتوي على شهادات صالحة
  • إعادة التوجيه من Apex إلى www تعمل

شكرًا @pfaffman!

4 إعجابات

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

سأضع هذا في اعتباري إذا واجهت أي مواقع أخرى تحتاج إلى هذا قبل قبول طلب السحب (PR).

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

هناك بعض الأجزاء المتحركة هنا. لقد نجحت معي في تلك إعادة البناء، وسأبلغ هنا إذا تغير هذا الوضع!

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

لم يتم دمج طلب السحب (PR) للسماح بتجديد الشهادات بعد - هذا الجزء لا يزال قيد الانتظار.

بمجرد دمجه، يجب أن يسمح ذلك بتطبيق أكثر تبسيطًا لـ app.yml

إعجابَين (2)

بشكل غريب إلى حد ما، تعمل هذه القطعة من التعليمات البرمجية في أحد مواقعي، لكن التعليمات البرمجية القديمة (والتعليمات البرمجية القديمة فقط) تعمل على موقعي الآخر. :person_shrugging:
حسنًا، نأمل أن يكون كل هذا بلا جدوى قريبًا على أي حال!

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

هذا غريب جداً. هل تم تثبيت discourse_docker على إصدار قديم؟

لا، ليس كذلك. لا يوجد فرق كبير بين الحالات (موضوعات / إضافات / تكوينات متشابهة)، باستثناء أن إحدى الحالات أقدم بكثير من الأخرى.

حسنًا، نأمل أن يكون هذا مجرد أكاديمي.

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

هل تم تنفيذ هذا على الإطلاق؟

انتهت صلاحية شهادة LetsEncrypt الخاصة بي بالأمس دون تجديد تلقائي. لست متأكدًا مما إذا كان لهذا علاقة بالتغييرات المقترحة على app.yml التي أجريتها وفقًا لهذا الموضوع أعلاه، أو بالتحديثات اللاحقة لـ Discourse.

بمساعدة الذكاء الاصطناعي (نعم، أعرف!) تمكنت الآن من جعله يتجدد، بعد اتباع الذكاء الاصطناعي في عدد من المتاهات التي تضمنت استخدام ngix و certbot (والتي نجحت في النهاية في الواقع)، قبل التراجع عن تلك التغييرات والعودة إلى الطريقة الافتراضية التي يديرها Discourse. خلال هذه العملية، اضطررت إلى إعادة البناء مرتين، لذا لست متأكدًا مما إذا كان هذا هو ما أدى إلى التجديد.

نعتذر عن الإزعاج - أنا فضولي، متى كانت آخر مرة قمت فيها بإعادة البناء قبل هذا؟

لقد تحققنا واختبرنا عملية التجديد مرة أخرى ولكننا غير قادرين على إعادة الإنتاج - تجديداتنا تعمل بشكل صحيح، لذا إما أن شيئًا ما لا يحدث من جانبنا، أو أن هناك شيئًا مختلفًا في كيفية عمل تجديد مرحلة الاختبار (staging) مقابل الإنتاج (prod) لـ Let’s Encrypt.

يمكنني أيضًا أن أؤكد أن إعادة بناء موقعك تجبر عملية التجديد على الحدوث، إذا فشل كل شيء آخر.

نحن نستخدم acme.sh تحت الغطاء (في /opt/acme.sh داخل الحاوية) - إذا كنت تميل إلى ذلك، يمكنك الدخول إلى حاوية docker قيد التشغيل وتشغيل البرنامج النصي للفحص/التجديد من خلال هناك أيضًا.

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