فشل الاستعادة - نسخة احتياطية متوافقة مع S3

لذا، كنت أحاول استعادة نسخة احتياطية، لكنني أواجه أخطاء. يبدو أن المشكلة تتعلق بنسخ S3 الاحتياطية.

من المهم الإشارة إلى أن هذا يحدث مع خدمة متوافقة مع S3 (Scaleway). ومع ذلك، غير متأكد مما إذا كانت هذه الأخطاء خاصة بالخدمة المتوافقة أم لا، حيث أن إعدادها سار بسلاسة كبيرة ويعمل بشكل جيد. إذا كانت المشكلة خاصة بـ Scaleway، فسأوقف على الأرجح استخدام خدمتهم، إذ أفهم أن AWS S3 فقط هو المدعوم رسميًا.

استخدمت هذا الدليل للإعداد: Configure an S3 compatible object storage provider for uploads لذا فإن الإعداد موجود في ملف app.yml.

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

استخدمت نفس الإعدادات لـ Scaleway أيضًا في ملف app.yml (لم أقم بإعدادها في إعدادات المسؤول لأنها بدت غير ضرورية): إعدادات Scaleway

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

[STARTED]
'system' has started the restore!
Marking restore as running...
Making sure /var/www/discourse/tmp/restores/default/2020-07-16-131434 exists...
Downloading archive to tmp directory...
#<Thread:0x000055c73a831df8@/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/aws-sdk-s3-1.66.0/lib/aws-sdk-s3/file_downloader.rb:116 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
	1: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/aws-sdk-s3-1.66.0/lib/aws-sdk-s3/file_downloader.rb:120:in `block (3 levels) in thread_batches'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/aws-sdk-s3-1.66.0/lib/aws-sdk-s3/file_downloader.rb:128:in `write': undefined method `split' for nil:NilClass (NoMethodError)
EXCEPTION: undefined method `split' for nil:NilClass
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/aws-sdk-s3-1.66.0/lib/aws-sdk-s3/file_downloader.rb:128:in `write'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/aws-sdk-s3-1.66.0/lib/aws-sdk-s3/file_downloader.rb:120:in `block (3 levels) in thread_batches'
Trying to rollback...
There was no need to rollback
Cleaning stuff up...
Removing tmp '/var/www/discourse/tmp/restores/default/2020-07-16-131434' directory...
Unpausing sidekiq...
Marking restore as finished...
Notifying 'system' of the end of the restore...
#<Thread:0x000055c73a831510@/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/aws-sdk-s3-1.66.0/lib/aws-sdk-s3/file_downloader.rb:116 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
	1: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/aws-sdk-s3-1.66.0/lib/aws-sdk-s3/file_downloader.rb:120:in `block (3 levels) in thread_batches'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/aws-sdk-s3-1.66.0/lib/aws-sdk-s3/file_downloader.rb:128:in `write': undefined method `split' for nil:NilClass (NoMethodError)
#<Thread:0x000055c73a8316c8@/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/aws-sdk-s3-1.66.0/lib/aws-sdk-s3/file_downloader.rb:116 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
	1: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/aws-sdk-s3-1.66.0/lib/aws-sdk-s3/file_downloader.rb:120:in `block (3 levels) in thread_batches'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/aws-sdk-s3-1.66.0/lib/aws-sdk-s3/file_downloader.rb:128:in `write': undefined method `split' for nil:NilClass (NoMethodError)
#<Thread:0x000055c73a8319e8@/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/aws-sdk-s3-1.66.0/lib/aws-sdk-s3/file_downloader.rb:116 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
	1: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/aws-sdk-s3-1.66.0/lib/aws-sdk-s3/file_downloader.rb:120:in `block (3 levels) in thread_batches'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/aws-sdk-s3-1.66.0/lib/aws-sdk-s3/file_downloader.rb:128:in `write': undefined method `split' for nil:NilClass (NoMethodError)
Finished!
[FAILED]
Restore done.

ربما يكون الخطأ خاصًا فقط بتحميل النسخة الاحتياطية؟ :face_with_monocle:

يبدو ذلك.

أنصح بنقل موقع النسخة الاحتياطية إلى المحلي في ملف app.yml، ثم إعادة البناء، وتنزيل ملف النسخة الاحتياطية يدويًا، واستعادته عبر وحدة التحكم.

آه، هذا منطقي. شكرًا لك يا @Falco! :slight_smile:

سأجرب ذلك في الصباح وأعود لأخبرك بالنتيجة~

شكرًا لك @Falco، نقدر ذلك! سار كل شيء بسلاسة تامة :smiley:

لقد قمت بالانتقال إلى خادم جديد، ويبدو أن البقاء على نفس الخادم كان سيكون أمرًا جيدًا أيضًا.

في حال أراد شخص آخر الرجوع إلى هذا لاحقًا، إليك الخطوات بتفصيل أكبر (لاحظ أن إعدادات S3 الخاصة بي كانت موجودة فقط في ملف app.yml كما هو موضح هنا، دون أي تخصيص في إعدادات المسؤول):

  1. في الموقع المصدر، إذا لم يكن هناك استعادة للنسخة السابقة، فعّل خيار ‘تعطيل الرسائل الإلكترونية’ (قد لا يكون ضروريًا) وفعّل وضع القراءة فقط (تذكّر إعادة تفعيل هذه الإعدادات في المثيل الجديد بعد اكتمال الهجرة). قم بإنشاء نسخة احتياطية، وبمجرد اكتمالها، يمكنك إيقاف المثيل القديم أيضًا (./launcher stop app). بغض النظر عما إذا كان هناك استعادة للنسخة السابقة أم لا، قم بتحديث سجلات DNS من نوع A لتشير إلى عنوان IP للخادم الجديد. يمكنك تنفيذ هذه الخطوات بطريقة أكثر أناقة أو بترتيب يقلل من وقت التوقف، لكن وقت التوقف لم يكن مصدر قلق في حالتي (استعادة للنسخة السابقة، ولم يكن المنتدى قد أُطلق بعد).

  2. قم بتثبيت Discourse على الخادم الجديد، وقلّد كل الإعدادات المخصصة في ملف app.yml بما في ذلك إعدادات S3، وتأكد من أن إصدارات Discourse متطابقة أو قريبة جدًا من بعضها.

  3. علّق السطرين التاليين (يمكن ترك إعدادات S3 الأخرى في ملف app.yml كما هي):
    DISCOURSE_S3_BACKUP_BUCKET: BucketName
    DISCOURSE_BACKUP_LOCATION: s3

  4. قم بتنزيل النسخة الاحتياطية المطلوبة يدويًا من خدمة S3 أو خدمة متوافقة مع S3.

  5. انتقل إلى المسار /var/discourse/shared/standalone/backups وأنشئ مجلدًا جديدًا باسم ‘default’ إذا لم يكن موجودًا (لن يكون موجودًا إذا كان التثبيت جديدًا). ثم، وأنت في مجلد النسخ الاحتياطية، قم بتشغيل الأمر التالي (يُغيّر هذا الأمر أذونات المجلد لتطابق ما ستكون عليه عادةً إذا أنشأ Discourse نسخة احتياطية محلية - غير متأكد مما إذا كان هذا ضروريًا):
    chown -R 1000:www-data default

  6. قم برفع النسخة الاحتياطية إلى مجلد backups/default باستخدام عميل SFTP، ولا تُعيد تسمية ملف النسخة الاحتياطية.

  7. أعد بناء التطبيق:
    cd /var/discourse
    ./launcher rebuild app

  8. ادخل إلى التطبيق، فعّل خيار النسخ الاحتياطي واستعد (أعد تسمية BackupFileName.tar.gz):

./launcher enter app
discourse enable_restore
discourse restore BackupFileName.tar.gz
  1. بمجرد الانتهاء، قم بإزالة التعليق عن سطري ملف النسخ الاحتياطي S3 في ملف app.yml من الخطوة 2 وأعد بناء التطبيق.

  2. يمكنك حذف مجلد backups/default المحلي والنسخة الاحتياطية الموجودة بداخله (/var/discourse/shared/standalone/backups).

مرجع: