كيفية إعداد Cloudflare R2 لمجتمع Discourse الخاص بك

يمكن استخدام مستودعات Cloudflare R2 لتخزين الأصول الثابتة مثل الصور وملفات GIF لمجتمع Discourse، ولكن لا يمكن استخدامها لتخزين النسخ الاحتياطية للمجتمع!

مقدمة:

يمكن استخدام تخزين الكائنات Cloudflare R2 كبديل لـ Amazon S3 لتخزين التحميلات لمنتدى Discourse الخاص بك. توضح الخطوات التالية كيفية تكوين ذلك.

خطوات التكوين:

  1. تمكين تحميلات S3: حدد المربع لتمكين تحميلات S3 في إعدادات Discourse الخاصة بك.
  2. معرف مفتاح الوصول إلى S3: أدخل معرف مفتاح واجهة برمجة التطبيقات (API) لمستودع تخزين R2 الخاص بك. هذا هو المعرف الذي تم توفيره عند إنشاء رمز مميز لواجهة برمجة التطبيقات (API) للمستودع الخاص بك.
  3. مفتاح الوصول السري: أدخل المفتاح السري الذي تم توفيره عند إنشاء الرمز المميز لواجهة برمجة التطبيقات (API) الذي يمنح الوصول إلى مستودع التخزين الخاص بك. هام: يتم عرض هذا المفتاح السري مرة واحدة فقط، لذا تأكد من نسخه احتياطيًا بشكل آمن.
  4. منطقة S3: يمكنك إدخال أي منطقة، فهي لا تهم بالنسبة لـ R2.
  5. مستودع تحميلات S3: أدخل اسم مستودع تخزين R2 الخاص بك.
  6. نقطة نهاية S3: أدخل رابط واجهة برمجة التطبيقات (API) لـ S3 لمستودع R2 الخاص بك، والذي يكون بالتنسيق https://xxxxxx.com. ارجع إلى لوحة تحكم Cloudflare R2 للعثور على هذا الرابط.
  7. عنوان URL لشبكة توصيل المحتوى (CDN) لـ S3: أدخل عنوان URL العام لمستودع تخزين R2.dev الخاص بك. سيتم العثور على هذا أيضًا في لوحة تحكم Cloudflare R2 الخاصة بك.

الاكتمال:

بمجرد تكوين هذه الإعدادات، سيتم إعداد منتدى Discourse الخاص بك لاستخدام Cloudflare R2 للتخزين.

معلومات الطبقة المجانية:

توفر خدمة R2 من Cloudflare طبقة مجانية تتضمن 10 جيجابايت من التخزين، ومليون عملية تحميل، ومليون عملية قراءة شهريًا.

5 إعجابات

أوصي بأن تتبع الأمثلة الموجودة في تكوين موفر تخزين كائنات متوافق مع S3 للتحميلات وتضع الإعدادات في ملف yml الخاص بك بدلاً من قاعدة البيانات.

شكراً لملاحظاتك. لقد قرأت الدليل بعناية سابقاً، وأعتقد أن النصيحة المتعلقة بـ Cloudflare R2 غير صحيحة. تقترح المقالة أن مجتمع Discourse لا يدعم مستودعات Cloudflare R2. ومع ذلك، في الواقع، يتوافق Cloudflare R2 بشكل كبير مع S3 ويمكنه التعامل بشكل مثالي مع تحميلات وتنزيلات الصور والملفات لمجتمع Discourse. وقد تم التحقق من ذلك من خلال التطبيق العملي على مجتمعي (starorigin.net).

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

وأشك في أن هذا كان صحيحًا عند كتابته.

من الأفضل بكثير وضع إعدادات S3 في ملف yml بدلاً من تكوينها عبر واجهة المستخدم وتخزينها في قاعدة البيانات. هل حاولت استعادة قاعدة بياناتك إلى خادم جديد؟

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

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

أنت على حق، أستخدم دلو تخزين Cloudflare R2 لتخزين صور مجتمعي وملفات GIF والموارد الأخرى. هذا يقلل بشكل كبير من الحمل على خادم المجتمع ويسرع تحميل الصفحات.

لم أقم بإعداد نسخ احتياطية تلقائية لمجتمعي ليتم تخزينها في دلو تخزين Cloudflare R2 لأن دلو Cloudflare R2 لا يدعم تخزين الملفات المضغوطة. ومع ذلك، يمكن لتخزين Cloudflare R2 تخزين ملفات PDF الخاصة بالمجتمع والصور وملفات GIF والموارد الثابتة الأخرى، وهو أمر جيد جدًا أيضًا.

مضحك. اعتقدت أنني استخدمت R2 للنسخ الاحتياطي من قبل. ولكن ربما لا أتذكر بشكل صحيح.

لا يزال بإمكانك اتباع التعليمات الموصى بها وتدوين ملاحظة بعدم وضع النسخ الاحتياطي هناك.

شكراً للتذكير، سأقوم بتسليط الضوء على هذا الجزء.

يمكن استخدام مستودعات Cloudflare R2 لتخزين الأصول الثابتة مثل الصور وملفات GIF لمجتمع Discourse، ولكن لا يمكن استخدامها لتخزين النسخ الاحتياطية للمجتمع!

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


1. المنطقة


لم يكن هذا صحيحًا، كان عليّ استخدام “auto” أو المنطقة التي اخترتها، “auto” أسهل لذا استخدم “auto”.
إذا كنت بحاجة إلى معرفة الخيارات التي يمكنك استخدامها، جرب أي سلسلة عشوائية في منطقتك و:

sudo -E -u discourse bundle exec rake s3:upload_assets

إذا كنت تستخدم nixos

sudo discourse-rake s3:upload_assets

سيؤدي هذا إلى إظهار خطأ للخيارات الصالحة الخاصة بك.


2. أذونات واجهة برمجة التطبيقات (API)


من المهم أيضًا معرفة أن رموز واجهة برمجة التطبيقات (API) التقييدية لا تعمل. يجب عليك استخدام Admin Read & Write
Object Read & Write لم يعمل

3 إعجابات

حدث خطأ عند تشغيل sudo -E -u discourse bundle exec rake s3:upload_assets @Eviepayne

تعيين المنطقة إلى تلقائي.
قد تحتاج أيضًا إلى تعيين:
DISCOURSE_S3_INSTALL_CORS_RULE: false

لقد قمت بكلا الأمرين وأعدت بناء app.yml:

  ## S3 Configuration
  DISCOURSE_USE_S3: true
  DISCOURSE_S3_REGION: auto
  DISCOURSE_S3_ACCESS_KEY_ID: XXX
  DISCOURSE_S3_SECRET_ACCESS_KEY: XXX
  DISCOURSE_S3_CDN_URL: https://pub-XXX.r2.dev
  DISCOURSE_S3_ENDPOINT: https://XXX.r2.cloudflarestorage.com/XXX
  DISCOURSE_S3_BUCKET: XXX
  DISCOURSE_S3_INSTALL_CORS_RULE: false

لقد تأكدت أيضًا من أن مفاتيح API هي مفاتيح API للحساب بدلاً من مجرد مفاتيح خاصة بالدلو (كما هو مذكور في المنشور). كما تظهر مثيل Discourse الخاص بي هذا:

وبعد تشغيل sudo -E -u discourse bundle exec rake s3:upload_assets يظهر:

`/root` is not writable.
Bundler will use `/tmp/bundler20250410-2363-zj2g6x2363' as your home directory temporarily.
Installing CORS rules...
skipping
rake aborted!
Seahorse::Client::NetworkingError: Empty or incomplete response body (Seahorse::Client::NetworkingError)
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/seahorse/client/plugins/raise_response_errors.rb:17:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-s3-1.182.0/lib/aws-sdk-s3/plugins/sse_cpk.rb:24:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-s3-1.182.0/lib/aws-sdk-s3/plugins/dualstack.rb:21:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-s3-1.182.0/lib/aws-sdk-s3/plugins/accelerate.rb:43:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/plugins/checksum_algorithm.rb:169:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/plugins/jsonvalue_converter.rb:16:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/plugins/invocation_id.rb:16:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/plugins/idempotency_token.rb:19:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/plugins/param_converter.rb:26:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/seahorse/client/plugins/request_callback.rb:89:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/plugins/response_paging.rb:12:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/seahorse/client/plugins/response_target.rb:24:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/plugins/telemetry.rb:39:in `block in call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/telemetry/no_op.rb:29:in `in_span'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/plugins/telemetry.rb:53:in `span_wrapper'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/plugins/telemetry.rb:39:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/seahorse/client/request.rb:72:in `send_request'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-s3-1.182.0/lib/aws-sdk-s3/client.rb:12654:in `list_objects_v2'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-s3-1.182.0/lib/aws-sdk-s3/bucket.rb:1513:in `block (2 levels) in objects'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/plugins/user_agent.rb:69:in `metric'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-s3-1.182.0/lib/aws-sdk-s3/bucket.rb:1512:in `block in objects'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/resources/collection.rb:101:in `each'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/resources/collection.rb:101:in `each'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/resources/collection.rb:101:in `block in non_empty_batches'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/resources/collection.rb:52:in `each'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/resources/collection.rb:52:in `each'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/resources/collection.rb:52:in `block in each'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/resources/collection.rb:58:in `each'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/resources/collection.rb:58:in `each'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/resources/collection.rb:58:in `each'
/var/www/discourse/lib/tasks/s3.rake:14:in `map'
/var/www/discourse/lib/tasks/s3.rake:14:in `existing_assets'
/var/www/discourse/lib/tasks/s3.rake:36:in `upload'
/var/www/discourse/lib/tasks/s3.rake:197:in `block (2 levels) in <main>'
/var/www/discourse/lib/tasks/s3.rake:197:in `each'
/var/www/discourse/lib/tasks/s3.rake:197:in `block in <main>'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/exe/rake:27:in `<top (required)>'
/usr/local/bin/bundle:25:in `load'
/usr/local/bin/bundle:25:in `<main>'
Tasks: TOP => s3:upload_assets
(See full trace by running task with --trace)

قد تضطر إلى إزالة اسم الحاوية من نقطة النهاية.
يجب إزالة الشرطة المائلة اللاحقة /xxx بحيث تكون فقط .com

إعادة البناء وتشغيل الأمر مرة أخرى، شكراً لمساعدتي في هذا!

يبدو ملف app.yml الخاص بي كما يلي الآن:

  ## S3 Configuration
  DISCOURSE_USE_S3: true
  DISCOURSE_S3_REGION: auto
  DISCOURSE_S3_ACCESS_KEY_ID: XXX
  DISCOURSE_S3_SECRET_ACCESS_KEY: XXX
  DISCOURSE_S3_CDN_URL: https://pub-XXX.r2.dev
  DISCOURSE_S3_ENDPOINT: https://XXX.r2.cloudflarestorage.com
  DISCOURSE_S3_BUCKET: XXX
  DISCOURSE_S3_INSTALL_CORS_RULE: false

أعتقد أن كل ذلك صحيح.
تأكد من أن CDN_URL (https://pub-xxx.r2.dev)
لديها وصول قراءة عام حتى يتمكن المستخدمون المجهولون من رؤية الأصول.
يمكنك معرفة ما يحدث في أدوات مطوري متصفحك. ستحصل على الكثير من الأخطاء 403 وطلبات حمراء في علامة تبويب الشبكة إذا كانت الأذونات خاطئة.

نعم، أعتقد ذلك:

هل هذا هو الإعداد الصحيح:

هذه إحدى الطرق للقيام بذلك، ولكنها ليست الطريقة الموصى بها، وستواجه مشكلات.
بافتراض أن لديك بالفعل نطاقك وأن Cloudflare هو نظام أسماء النطاقات الخاص بك بالفعل:

سيقوم Cloudflare تلقائيًا بالوكالة ويمكنه التخزين المؤقت لهذا النطاق.
يمكنك بعد ذلك تغيير CDN_URL إلى هذا النطاق المخصص.

أوه، أحتاج إلى توصيل النطاق المخصص بالمخزن؟

داخل إعدادات دلو S3 يوجد إعداد وصول عام.
قم بتعيين نطاق فرعي فريد له. (سوف يقوم كلاودفلير تلقائيًا بإنشاء سجل DNS لك بالإضافة إلى البروكسي والتخزين المؤقت)

أعتقد أنني حصلت عليها؟

هل نجحت النسخ الاحتياطي أيضًا في العمل مع Cloudflare R2، وهل من الممكن (بافتراض أن النسخ الاحتياطي إلى Cloudflare R2 ممكن) جعله يقوم بالنسخ الاحتياطي محليًا وإلى Cloudflare R2؟

أيضًا، هل يعني البرنامج النصي الذي يقوم بتحميل جميع الأصول أنه سيحذفها محليًا (لتحرير مساحة التخزين)؟ أم أن هناك إجراء منفصلاً أحتاج إلى القيام به؟

شكرًا لك على تخصيص الوقت لمساعدتي في هذا :slight_smile:

لم أجرب شخصيًا.
يقع منتدى الخاص بي ضمن فئة “غير مدعوم” لأن قاعدة بياناتي خارجية ولدي استراتيجية نسخ احتياطي مختلفة عن النسخ الاحتياطي لـ pg_dumps الذي يستخدمه المنتدى.
حسب ما سمعت، النسخ الاحتياطي لا يعمل على Cloudflare ولكن لا شيء يمنعك من تجربته.

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