غير قادر على إعداد دلو S3

مرحباً،

أحاول إعداد عمليات التحميل إلى S3 ويبدو أن عمليات التحميل تعمل بشكل صحيح ولكن طلبات GET تفشل لسبب غريب. يبدو أن discourse يضيف “.cn” إلى URI للكائن الذي تم تحميله.

بعد تحميل الصورة في حاوية S3 الخاصة بي، يكون عنوان URL العام هو:

https://hobig...bucket-eu.s3.eu-central-1.amazonaws.com/original/1X/5e894113...48918.jpeg

ولكن عندما أفحص المتصفح، يحاول منتدى discourse الخاص بي تحميل (لاحظ .cn):

https://hobig...bucket-eu.s3.eu-central-1.amazonaws.com.cn/original/1X/5e894113...48918.jpeg

هل يعرف أحد لماذا يحدث هذا؟

إليك إعدادات المسؤول الخاصة بي:

يجب عليك اتباع التعليمات الموجودة في تكوين موفر تخزين كائنات متوافق مع S3 لعمليات التحميل و/أو Set up file and image uploads to S3 ووضع هذه الإعدادات في ملف yml الخاص بك بدلاً من قاعدة البيانات/تجربة المستخدم.\n\nلا تحتاج إلى تكوين نقطة نهاية لـ AWS. تريد تكوين شبكة توصيل محتوى (CDN).

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

مرحباً @pfaffman،

يبدو أنك قمت بلصق نفس الدليل مرتين عن غير قصد.

عندما تذكر “الإعدادات في ملف yml الخاص بك”، هل يمكنك توضيح الملف الذي تشير إليه؟ هل تتحدث ربما عن ملف app.yml الموجود في مجلد /var/discourse/containers؟

بالإضافة إلى ذلك، إذا قمت بتكوين تكامل S3/CloudFront الخاص بي مباشرة من خلال ملف YAML، فهل ستتجاوز هذه الإعدادات ما تم تكوينه في قسم المسؤول في Discourse؟

شكراً لك!

آسف. كان ينبغي أن يكون أحدها Set up file and image uploads to S3.

راجع المواضيع المرتبطة التي تصف كيفية تكوين S3، ولكن نعم، app.yml هو ما تريد تغييره (نظرًا لأنك لم تذكر web_only.yml)

نعم. إدخالها في ملف YML يخفيها عن واجهة المستخدم.

مرحباً @pfaffman،

لديّ حاوية S3 الخاصة بي، وإعداد CloudFront، وتم تعيين مصدر CloudFront إلى حاوية S3 الخاصة بي. إليك تكوين app.yml الحالي الخاص بي:

ENV:
  DISCOURSE_USE_S3: true
  DISCOURSE_S3_REGION: eu-central-1
  DISCOURSE_S3_ACCESS_KEY_ID: AKIAWPLPUxxxxxx
  DISCOURSE_S3_SECRET_ACCESS_KEY: PaXQu7pKxxxx
  DISCOURSE_S3_CDN_URL: https://dsuxxxhrz2qn.cloudfront.net
  DISCOURSE_S3_BUCKET: hobigxxxxbucket-eu

بعد إعادة بناء التطبيق باستخدام ./launcher rebuild app، عندما أزور الموقع، فإنه يعرض فقط المُحمّل دون تحميل أي شيء. عند فحص علامة التبويب “الشبكة”، وجدت أنه لا يمكنه جلب الأصول الثابتة المُجمّعة مسبقًا (معظمها .js)، والتي أفترض أنها غير موجودة في حاوية S3 الخاصة بي. يمكنك التحقق من ذلك هنا: forum.hobiguru.com.

حاولت أيضًا تشغيل مهمة الترحيل rake، ولكن دون جدوى:

root@ubuntu-s-1vcpu-1gb-fra1-01-app:/var/www/discourse# rake uploads:migrate_to_s3 --trace


** Invoke uploads:migrate_to_s3 (first_time)
** Invoke environment (first_time)
** Execute environment


** Execute uploads:migrate_to_s3
يرجى ملاحظة أن الترحيل إلى S3 غير قابل للعكس حاليًا!
[CTRL+c] للإلغاء، [ENTER] للمتابعة
ترحيل التحميلات إلى S3 لـ 'default'...
لم يتم ترحيل بعض التحميلات إلى المخطط الجديد. يتطلب هذا الإصلاح يدويًا...
تم إلغاء المهمة!
FileStore::ToS3MigrationError: لم يكن من الممكن ترحيل بعض التحميلات إلى المخطط الجديد. تحتاج إلى إصلاح هذا يدويًا. (FileStore::ToS3MigrationError)
/var/www/discourse/lib/file_store/to_s3_migration.rb:156:in `migrate_to_s3'
/var/www/discourse/lib/file_store/to_s3_migration.rb:59:in `migrate'
/var/www/discourse/lib/tasks/uploads.rake:126:in `migrate_to_s3'
/var/www/discourse/lib/tasks/uploads.rake:106:in `block in migrate_to_s3_all_sites'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.1.0/lib/rails_multisite/connection_management/null_instance.rb:49:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.1.0/lib/rails_multisite/connection_management/null_instance.rb:36:in `each_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.1.0/lib/rails_multisite/connection_management.rb:21:in `each_connection'
/var/www/discourse/lib/tasks/uploads.rake:104:in `migrate_to_s3_all_sites'
/var/www/discourse/lib/tasks/uploads.rake:100:in `block in <main>'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/task.rb:281:in `block in execute'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/task.rb:281:in `each'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/task.rb:281:in `execute'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/task.rb:219:in `block in invoke_with_call_chain'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/task.rb:199:in `synchronize'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/task.rb:199:in `invoke_with_call_chain'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/task.rb:188:in `invoke'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/application.rb:188:in `invoke_task'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/application.rb:138:in `block (2 levels) in top_level'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/application.rb:138:in `each'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/application.rb:138:in `block in top_level'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/application.rb:147:in `run_with_threads'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/application.rb:132:in `top_level'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/application.rb:83:in `block in run'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/application.rb:214:in `standard_exception_handling'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/application.rb:80:in `run'
bin/rake:13:in `<top (required)>'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/cli/exec.rb:58:in `load'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/cli/exec.rb:58:in `kernel_load'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/cli/exec.rb:23:in `run'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/cli.rb:455:in `exec'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/vendor/thor/lib/thor/command.rb:28:in `run'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/vendor/thor/lib/thor.rb:527:in `dispatch'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/cli.rb:35:in `dispatch'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/vendor/thor/lib/thor/base.rb:584:in `start'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/cli.rb:29:in `start'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/exe/bundle:28:in `block in <top (required)>'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/friendly_errors.rb:117:in `with_friendly_errors'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/exe/bundle:20:in `<top (required)>'
/usr/local/bin/bundle:25:in `load'

كان هدفي الأصلي هو استخدام S3 فقط لتخزين تحميلات المستخدمين، وأضفت CDN للتعامل مع ذلك فقط. ومع ذلك، أواجه الآن مشكلة جديدة - يتم تقديم الأصول الثابتة للتطبيق الخاص بي أيضًا عبر CDN، وهو ما لم أكن أنوي فعله. :confused:

هل هناك طريقة لتحميل جميع الأصول الثابتة عند بدء تشغيل التطبيق إلى حاوية S3 ثم تقديمها عبر CDN، أو ربما طريقة لتقديم تحميلات المستخدمين فقط عبر CDN أو هل هناك حل أفضل لهذا؟

ربما ما زلت أفتقد شيئًا واضحًا؟ لا أعرف
شكراً لمساعدتك!

أشك في أن ذلك بسبب عدم اتباعك للتعليمات.

نعم. أفهم. هذا ممكن، لكنك لم تتمكن من جعل ذلك يعمل. هذه هي الطريقة الموصى بها؛ إنها موثقة جيدًا ويقوم المئات من الأشخاص بذلك بهذه الطريقة.

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

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

after_assets_precompile:
    - exec:
        cd: $home
        cmd:
          - sudo -E -u discourse bundle exec rake s3:upload_assets
          - sudo -E -u discourse bundle exec rake s3:expire_missing_assets

ومع ذلك، لا تزال عمليات تحميل المستخدم لا تعمل بشكل صحيح. بعد التحميل إلى حاوية S3 (بشكل صحيح)، يتم تقديم الصورة على النحو التالي:

//my-bucket-eu.my-bucket-eu/original/1X/7f242572bdb45b65ded727c13366fe490541358f.jpeg

وهو بالطبع ليس مسار S3 أو CDN صالحًا.

في الدليل الذي تشير إليه، يوجد هذا القسم الذي يبدو ذا صلة:

DISCOURSE_CDN_URL هو شبكة توصيل محتوى (CDN) تشير إلى اسم مضيف Discourse الخاص بك وتقوم بتخزين الطلبات مؤقتًا. سيتم استخدامه بشكل أساسي للأصول القابلة للسحب: CSS وأصول السمات الأخرى.

DISCOURSE_S3_CDN_URL هو شبكة توصيل محتوى (CDN) تشير إلى حاوية تخزين الكائنات الخاصة بك وتقوم بتخزين الطلبات مؤقتًا. سيتم استخدامه بشكل أساسي للأصول القابلة للدفع: JS والصور وتحميلات المستخدم.

نوصي بأن تكون هاتان مختلفتين وأن يقوم المسؤولون بتعيين كليهما.

ومع ذلك، لست متأكدًا مما يجب تعيينه كـ DISCOURSE_CDN_URL؟ هل يجب تعيينه على نفس قيمة DISCOURSE_S3_CDN_URL: https://dsxxxxx2qn.cloudfront.net أو إنشاء مثيل CDN منفصل؟

ثم مرة أخرى، ربما يكون شيئًا مختلفًا تمامًا :confused:

شكراً جزيلاً على كل المساعدة!

عليك تكوين شبكة توصيل المحتوى (CDN) واستخدام نطاقك المطلوب على جانب AWS. بالإضافة إلى ذلك في نظام أسماء النطاقات (DNS).

ولكن لماذا؟ لا أحد عمليًا يرى هذا الرابط أبدًا.

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

مرحباً جيك، لست متأكداً من أنني فهمت ما تقصده بشكل صحيح. هل يمكنك توضيحه أكثر قليلاً؟

هل كنت تقصد أنه بدلاً من تعيين مستودع S3 كأصل لشبكة توصيل المحتوى (CDN) ، يجب علي تعيين نطاق forum.hobiguru.com الخاص بي كأصل؟ إذا كان الأمر كذلك ، فلا أعتقد أن هذا سيغير أي شيء لأن منتدى discourse هو الذي ينشئ تلك الروابط التي لا تؤدي إلى أي مكان ، على سبيل المثال //my-bucket-eu.my-bucket-eu/original/1X/7f242572bdb45b65ded727c13366fe490541358f.jpeg

لقد قمت بإضافة DISCOURSE_CDN_URL: https://dsuxxxhrz2qn.cloudfront.net أيضاً والآن أنتظر إعادة بناء التطبيق :crossed_fingers:

تحديث: لا، هذا لم ينجح أيضاً :/\

أنا أقدر المساعدة حقاً.
شكراً لك

لا يمكنك تسمية نطاق فرعي في ملف app.yml فقط. لا يمكن لأحد استخدامه بدون معلومات DNS مناسبة. ولأن تقديم ملفاتك يتم من AWS، يجب عليك تكوين هذا الجانب أيضًا، إذا كنت ترغب في استخدام شبكة توصيل المحتوى (CDN).

ولكن مرة أخرى. يرى المستخدمون عنوان URL الخاص بـ Disourse، إذا كانوا يريدون رؤيته. نادرًا ما يرغب أي شخص آخر غير المسؤول الإداري في القيام بشيء ما. وعمليًا لا يرى المستخدمون أبدًا عنوان URL للملفات الوسائط أو الملفات الثابتة الأخرى.

لذلك، من وجهة نظري، أنت تضيع وقتك عبثًا إذا كنت لا ترغب في استخدام شبكة توصيل المحتوى (CDN). وقد يكون ذلك ذكيًا إذا كان لديك جمهور عالمي، وبعضهم يعاني من اتصالات سيئة على مستوى الدولة.

أنا أعيش في فنلندا. لا أحصل على أي فوائد حقيقية إذا كان موقع على الجانب الآخر من العالم، في أستراليا، يستخدم شبكة توصيل المحتوى (CDN) (من خادم يقع على بعد 1000 كيلومتر مني). عنق الزجاجة الحقيقي يأتي من كيفية بناء هذا الموقع، مثل استخدامه للكثير من استدعاءات PHP غير الضرورية بدون موارد كافية.

ولكن بشكل أساسي، لا يمكنك استخدام عنوان URL cdn.example.tld دون وضع cdn على الأقل في نظام أسماء النطاقات (DNS).

مرحباً @Jagster

في الواقع، لا أرغب في استخدام شبكة توصيل المحتوى (CDN) على الإطلاق - أريد فقط تخزين جميع تحميلات المستخدمين في S3 وتقديمها مباشرة من هناك، على الرغم من أن CloudFront هو حقًا حل أفضل من S3 مباشرة.

نشأت مشكلتي عندما حاولت إعداد S3 (خاصة لتقديم الأصول، وليس التحميلات)، واقترح @pfaffman أن أتبع دليل تكوين موفر تخزين كائنات متوافق مع S3 للتحميلات وتكوين شبكة توصيل محتوى (CDN).

بخصوص تعليقك:

“لا يمكنك تسمية نطاق فرعي فقط في app.yml. لا يمكن لأحد استخدامه بدون معلومات DNS صحيحة. ولأن تقديم ملفاتك يحدث من AWS، يتعين عليك تكوين هذا الجانب أيضًا، إذا كنت تريد استخدام شبكة توصيل محتوى (CDN).”

أنا آسف، لكنني لم أفهم تمامًا ما كنت تقصده بهذه الفقرة. هل يمكنك التوضيح أكثر أو تقديم شرح؟ هل تقول إنني بحاجة إلى تكوين سجلات DNS لدلو S3 الخاص بي أو أن هناك شيئًا محددًا أحتاج إلى تعديله على جانب AWS؟

شكراً مقدماً على مساعدتك!

مرحباً مرة أخرى، أيها الجميع،

أردت المتابعة على منشوري السابق ومشاركة أنني أحرزت بعض التقدم.

ما يعمل الآن

  • يتم تقديم تحميلات المستخدم بشكل صحيح من مخزن S3 الخاص بي عبر شبكة توصيل المحتوى (CloudFront)، وهذا رائع!

ولكن، ما زلت أواجه مشكلة مع الأصول المترجمة مسبقًا

لم يتم تقديم الأصول المترجمة مسبقًا بشكل صحيح من شبكة توصيل المحتوى.

عندما أقوم بتعيين DISCOURSE_CDN_URL إلى عنوان URL الخاص بـ CloudFront (أي https://dsuqioxhrz2qn.cloudfront.net)، تصبح عناوين URL للأصول المترجمة مسبقًا:

المشكلة هي أن هذه المسارات غير موجودة في مخزن S3 الخاص بي. يتم تحميل الأصول المترجمة مسبقًا ضمن مجلد /assets/* في S3 (على سبيل المثال، /assets/locales، /assets/plugins، /assets/scripts)، ولكن لا يوجد مجلد /stylesheets/ وبالطبع يؤدي تحميل تلك عناوين URL إلى خطأ 403 Forbidden.

إذا قمت بتغيير DISCOURSE_CDN_URL: https://forum.hobiguru.com، فإن منتدى يعمل بشكل صحيح، ولكن الأصول يتم تقديمها الآن من الخادم (على سبيل المثال، https://forum.hobiguru.com/) وليس من شبكة توصيل المحتوى (على سبيل المثال، https://forum.hobiguru.com/stylesheets/admin_308d905aa5c03567866fec50e9a28d8721ab0463.css?__ws=forum.hobiguru.com)

إعدادي الحالي (للسياق) هو:

app.yaml

DISCOURSE_USE_S3: true
DISCOURSE_S3_REGION: eu-central-1
DISCOURSE_S3_ACCESS_KEY_ID: AKIA......LQMB
DISCOURSE_S3_SECRET_ACCESS_KEY: PaXQu7pKN.....fJNY
DISCOURSE_S3_BUCKET: hobiguru-s3-bucket-eu
DISCOURSE_CDN_URL: https://dsuqioxhrz2qn.cloudfront.net  # Ensure CDN URL points to CloudFront
# DISCOURSE_CDN_URL: https://forum.hobiguru.com # NOTICE THIS!

وخطافات ما قبل الترجمة:

hooks:
  after_assets_precompile:
    - exec:
        cd: $home
        cmd:
          - sudo -E -u discourse bundle exec rake s3:upload_assets
          - sudo -E -u discourse bundle exec rake s3:expire_missing_assets

يبدو أنه بعد ترجمة الأصول مسبقًا، يتم تحميلها إلى S3 بهيكل معين، ولكن عند تحميلها عبر شبكة توصيل المحتوى، يكون المسار إلى الكائنات غير صحيح قليلاً.