نقل موقع بين خادمين من أكثر العمليات حساسية: خطأ واحد قد يعني بيانات مفقودة أو ساعات توقف يراها كل زوارك.

هذا الدليل يرتب العملية في ثماني مراحل واضحة. القاعدة العامة: نقل مباشر مشفر يوفر المساحة والوقت، ثم اختبار مسبق كامل قبل تغيير إعدادات DNS، ثم تحقق من التطابق للبيانات والملفات، ثم إيقاف آمن تدريجي ومراقبة حية قبل الحذف النهائي.

1. المفاهيم الهندسية ومبادئ النقل الآمن

تتطلب عمليات نقل الخوادم اتباع مبادئ صارمة لتجنب المشاكل الأكثر شيوعاً مثل عدم تطابق البيانات، أو انقطاع الخدمة عن الزوار، أو انتقال ملفات ضارة:

  • النقل المشفر المباشر (Direct Stream via SSH): تجنب إنشاء ملفات نسخ احتياطي ضخمة على القرص المحلي لتقليل استهلاك المساحة والجهد، ويتم تصدير البيانات ونقلها لحظياً عبر قنوات SSH.
  • مبدأ العزل والأمان (Zero-Trust Isolation): تشغيل كل موقع تحت مستخدم نظام مخصص ومجمّع PHP-FPM خاص (Pool) مستقل بصلاحيات صارمة لمنع التداخل بين التطبيقات.
  • الفحص المسبق (Isolation Testing): اختبار التطبيق على الخادم الجديد بكامل وظائفه قبل توجيه أي نطاق فعلي إليه.
  • الإيقاف الآمن التدريجي (Graceful Decommissioning): إيقاف الخدمات الأساسية على الخادم القديم مؤقتاً ومراقبة استقرار النظام قبل حذف الخادم نهائياً.

إذا كان النقل بهذا التعقيد، فغالباً الأفضل أن يتولاه فريق متخصص: راجع خدمة نقل المواقع لتعرف ما يتم فحصه قبل تحويل الدومين وما بعدها.

2. المرحلة الأولى: التجهيز والتخطيط المسبق (Pre-Migration)

2.1 خفض قيمة TTL سجلات الـ DNS (TTL)

قبل النقل بـ 24-48 ساعة، قم بخفض الـ TTL لسجلات النطاق (A / AAAA) إلى 300 ثانية (5 دقائق) أو Auto لدى مزود الـ DNS، لضمان سرعة انتشار التوجيه الجديد عند التحويل.

2.2 مطابقة بيئة العمل

تحقق من تطابق أو توافق البرمجيات بين الخادم القديم والجديد:

bash
# فحص إصدارات خادم الويب ونسخة PHP وقاعدة البيانات
nginx -v || httpd -v
php -v
mysql -V

وإن كنت تدير عدة مواقع، فـإدارة السيرفرات تجعل مطابقة البيئة والعزل والصلاحيات إجراءً ثابتاً بدل اجتهاد متكرر مع كل نقل.

2.3 إعداد المستخدم المستقل ومجلد الموقع على الخادم الجديد

على الخادم الجديد:

bash
# إنشاء مستخدم مستقل مع مجلد الموقع
useradd -m -s /bin/bash site_user
mkdir -p /home/site_user/example.com/public_html

# ضبط الصلاحيات القياسية للأمان (تقييد الوصول للآخرين)
chmod 750 /home/site_user
chmod 750 /home/site_user/example.com
chown -R site_user:site_user /home/site_user/example.com

3. المرحلة الثانية: نقل قواعد البيانات بطريقة النقل المباشر (Database Streaming)

تعتمد هذه الطريقة على استخراج قاعدة البيانات من الخادم القديم وتمريرها مباشرة إلى الخادم الجديد عبر نفق SSH دون الحاجة لتخزين ملف .sql وسيط على القرص.

3.1 إنشاء قاعدة البيانات والمستخدم على الخادم الجديد

sql
CREATE DATABASE site_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'site_db_user'@'127.0.0.1' IDENTIFIED BY 'STRONG_SECRET_PASSWORD';
GRANT ALL PRIVILEGES ON site_db.* TO 'site_db_user'@'127.0.0.1';
FLUSH PRIVILEGES;

3.2 أمر النقل المباشر لقاعدة البيانات

يتم تنفيذ هذا الأمر إما من محطة الإدارة أو من الخادم القديم موجهاً للجديد:

bash
# نقل ونسخ قاعدة البيانات مباشرة من الخادم القديم إلى الخادم الجديد
ssh user@OLD_SERVER_IP "mysqldump -u OLD_DB_USER -p'OLD_PASS' --single-transaction --quick --no-tablespaces site_db" \
  | ssh user@NEW_SERVER_IP "mysql -u site_db_user -p'STRONG_SECRET_PASSWORD' site_db"
معلومة

إضافة خيار --single-transaction تمنع قفل الجداول وتضمن استخراج البيانات بصورة متسقة دون إخراج من الخدمة موقع الإنتاج.

4. المرحلة الثالثة: نقل الملفات والملفات المرفوعة بكفاءة وأمان (Files and Media Transfer)

4.1 النقل الذكي باستخدام rsync

استخدم rsync لنقل ملفات الموقع مع الحفاظ على الصلاحيات والملكية، مع استبعاد الملفات المؤقتة وملفات التخزين المؤقت:

bash
# تنفيذ المزامنة من الخادم القديم إلى الخادم الجديد
rsync -avzP --human-readable \
  --exclude='*.log' \
  --exclude='cache/' \
  --exclude='tmp/' \
  --exclude='.git/' \
  /home/site_user/example.com/public_html/ \
  user@NEW_SERVER_IP:/home/site_user/example.com/public_html/

4.2 النقل الآمن للوسائط في حالات المواقع التي تتطلب تنقية أمنية

إذا كان الموقع قد تعرض لاختراق سابق وتريد استبعاد أي ملفات برمجية مرفوعة خبيثة داخل مجلد الملفات المرفوعة (uploads):

bash
# نقل مجلد الملفات المرفوعة مع حظر أي نصوص برمجية تنفيذية
tar -czf - --exclude='*.php' --exclude='*.phtml' --exclude='*.phar' -C /path/to/source uploads | \
  ssh user@NEW_SERVER_IP "tar -xzf - -C /home/site_user/example.com/public_html/wp-content/"

4.3 ضبط الصلاحيات بعد النقل

على الخادم الجديد، قم بإعادة تعيين الصلاحيات بشكل آمن لمنع ثغرات تعديل الملفات:

bash
# تعيين الملكية للمستخدم ومجموعة خادم الويب
chown -R site_user:site_user /home/site_user/example.com/public_html/

# تعيين صلاحيات المجلدات (755) والملفات (644)
find /home/site_user/example.com/public_html/ -type d -exec chmod 755 {} +
find /home/site_user/example.com/public_html/ -type f -exec chmod 644 {} +

# تقييد الوصول إلى ملف الإعدادات الحساس (مثل wp-config.php أو .env)
chmod 600 /home/site_user/example.com/public_html/wp-config.php

5. المرحلة الرابعة: نقل الخدمات المساعدة والمهام المجدولة كرون (Cron and Caching)

من أكبر الأخطاء التي تحدث أثناء النقل إغفال المهام المجدولة كرون (Cron Jobs) أو خدمات التخزين المؤقت (Redis / Memcached).

5.1 مراجعة ونقل مهام Crontab

افحص المهام المجدولة كرون على الخادم القديم:

bash
# فحص مهام المستخدمين
crontab -l
crontab -u site_user -l

# فحص مهام النظام المركزية
cat /etc/crontab
ls -la /etc/cron.d/

ثم أضف المهام المقابلة إلى /etc/crontab أو كرون المستخدم على الخادم الجديد مع تعديل المسارات إن لزم الأمر:

bash
# تشغيل مهمة كرون النظام للموقع كل 10 دقائق عبر مستخدمه المستقل
*/10 * * * * site_user php /home/site_user/example.com/public_html/cron-runner.php > /dev/null 2>&1

5.2 إعداد خدمات التخزين المؤقت (Redis)

إذا كان التطبيق يعتمد على Redis لتخزين الكائنات (Object Caching):

bash
# التحقق من تشغيل خدمة Redis على الخادم الجديد
systemctl is-active redis-server || systemctl is-active redis

# التحقق من تثبيت امتداد PHP الخاصة بـ Redis
php -m | grep redis

6. المرحلة الخامسة: الاختبار الداخلي قبل تحويل DNS (Pre-Cutover Verification)

تحذير

القاعدة الأهم: لا تقم أبداً بتوجيه الـ DNS قبل التحقق بنسبة 100% من استجابة الموقع من الخادم الجديد.

6.1 فحص الاستجابة عبر أداة cURL باستخدام resolve

تتيح ميزة --resolve اختبار الخادم الجديد مباشرة حتى لو كان النطاق يشير إلى الخادم القديم أو عبر Cloudflare:

bash
# اختبار اتصال HTTPS مباشرة مع الخادم الجديد
curl -Iv https://example.com/ --resolve example.com:443:NEW_SERVER_IP

# فحص رمز الاستجابة وسرعة التحميل
curl -s -o /dev/null -w "HTTP: %{http_code} | Total Time: %{time_total}s\n" \
  --resolve example.com:443:NEW_SERVER_IP https://example.com/

يجب أن تحصل على HTTP: 200 أو إعادة توجيه صحيح مثل 301.

6.2 فحص شهادة SSL (SSL Certificate)

تأكد من وجود شهادة صالحة على الخادم الجديد:

bash
# التحقق من شهادات Let's Encrypt
certbot certificates

# اختبار اتصال SSL يدوياً
echo | openssl s_client -servername example.com -connect NEW_SERVER_IP:443 2>/dev/null | openssl x509 -noout -dates

6.3 الاختبار عبر المتصفح باستخدام ملف Hosts المحلي

على حاسوبك الشخصي، يمكنك توجيه النطاق مؤقتاً لتصفحه في المتصفح بإضافة السطر التالي في ملف الـ hosts:

  • Linux / Mac: /etc/hosts
  • Windows: C:\Windows\System32\drivers\etc\hosts
text
NEW_SERVER_IP example.com www.example.com

تصفح الموقع بالكامل:

  • تسجيل الدخول للوحة التحكم.
  • رفع صورة تجريبية للتأكد من صلاحيات المجلدات.
  • تصفح المقالات والتأكد من الروابط الثابتة (Permalinks).

7. المرحلة السادسة: تحقق التطابق الشامل (Data and Assets Parity Audit)

قبل التحويل، قم بتنفيذ هذا التحقق الآلي للتأكد من عدم حدوث أي نقص أو اختلاف بين الخادمين.

7.1 تحقق تطابق قواعد البيانات (Record Count and Max Timestamps)

قارن أحدث السجلات وعددها بين الخادمين في الجداول الأكثر نشاطاً مثل جدول المقالات أو الطلبات:

bash
# على الخادم القديم
mysql -u site_db_user -p'OLD_PASS' site_db \
  -e "SELECT COUNT(*) AS total_rows, MAX(created_at) AS latest_record FROM main_table;"

# على الخادم الجديد
mysql -u site_db_user -p'STRONG_SECRET_PASSWORD' site_db \
  -e "SELECT COUNT(*) AS total_rows, MAX(created_at) AS latest_record FROM main_table;"
نصيحة

المعيار: يجب أن يكون عدد السجلات وتاريخ آخر سجل متطابقين تماماً بين الخادمين قبل المتابعة.

7.2 تحقق تطابق الملفات والملفات المرفوعة (File Counts and Sizes)

قارن عدد الملفات وحجم المجلدات بين الخادمين:

bash
# مقارنة عدد الملفات في مجلد الملفات المرفوعة
# الخادم القديم:
find /home/site_user/example.com/public_html/uploads/ -type f | wc -l
# الخادم الجديد:
find /home/site_user/example.com/public_html/uploads/ -type f | wc -l

# مقارنة الحجم الإجمالي للمجلد
du -sh /home/site_user/example.com/public_html/uploads/

7.3 المزامنة النهائية السريعة (Delta Sync)

في حال استغرقت عملية التحضير وقتاً وتمت كتابة بيانات جديدة على الخادم القديم، قم بإجراء مزامنة تكميلية سريعة قبل توجيه الـ DNS مباشرة:

bash
# مزامنة سريعة لقاعدة البيانات
ssh user@OLD_SERVER_IP "mysqldump -u OLD_DB_USER -p'OLD_PASS' --single-transaction --quick site_db" \
  | ssh user@NEW_SERVER_IP "mysql -u site_db_user -p'STRONG_SECRET_PASSWORD' site_db"

# مزامنة تكميلية للملفات الجديدة فقط
rsync -avzP --update /home/site_user/example.com/public_html/uploads/ user@NEW_SERVER_IP:/home/site_user/example.com/public_html/uploads/

8. المرحلة السابعة: تحويل الزيارات والمراقبة الحية (Traffic Cutover)

8.1 تحديث سجلات الـ DNS

  1. توجه إلى لوحة تحكم DNS مثل Cloudflare أو مسجل النطاق.
  2. قم بتعديل A Record للنطاق ليشير إلى NEW_SERVER_IP.
  3. قم بتعديل أي نطاقات فرعية متعلقة.

8.2 المراقبة الحية لالزيارات (Live Log Streaming)

افتح نافذتي طرفية وراقب سجلات الوصول اللحظية لكلا الخادمين:

  • على الخادم الجديد (يجب أن تبدأ الطلبات بالظهور وتتزايد تدريجياً):
bash
tail -f /var/log/nginx/example.com-access.log
  • على الخادم القديم (يجب أن تتناقص الطلبات حتى تتوقف تماماً):
bash
tail -f /var/log/nginx/access.log
  • التحقق من الاتصالات القائمة على الخادمين:
bash
# إحصاء الاتصالات القائمة على المنفذ 80 و 443
ss -tn state established '( dport = :80 or dport = :443 )' | wc -l

9. المرحلة الثامنة: الإيقاف الآمن التدريجي وإخراج الخادم من الخدمة نهائياً (Decommissioning)

خطر

لا تقم بحذف أو مسح بيانات الخادم القديم فوراً، اتبع طريقة الإيقاف الآمن التدريجي (Graceful Soft Shutdown) لتتفادى فقدان أي بيانات لم تنتقل بعد.

9.1 الخطوة الأولى: إيقاف خادم الويب وقاعدة البيانات فقط

قم بإيقاف الخدمات الأساسية على الخادم القديم مع الإبقاء على الخادم يعمل:

bash
# على الخادم القديم
systemctl stop nginx || systemctl stop apache2
systemctl stop mysql || systemctl stop mariadb

# منع تشغيلها تلقائياً عند إعادة التشغيل
systemctl disable nginx
systemctl disable mysql

9.2 الخطوة الثانية: اختبار الموقع المباشر (Validation Test)

بعد إيقاف الخدمات على الخادم القديم، قم بفحص موقعك فوراً من أجهزة وشبكات مختلفة:

bash
curl -I https://example.com/
  • إذا استمر الموقع في العمل بنجاح وبرمز الحالة 200 OK، فهذا دليل قاطع بأن الزيارات لم تعد تعتمد على الخادم القديم إطلاقاً.
  • إذا ظهر خطأ اتصال أو توقف، يمكنك ببساطة إعادة تشغيل الخدمة على الخادم القديم (systemctl start nginx) وتصحيح إعدادات الـ DNS فوراً دون أي خطر.

9.3 الخطوة الثالثة: الاحتفاظ بنسخة أرشيفية نهائية والإلغاء النهائي

  1. احتفظ بالخادم القديم مطفأ (Powered Off) لمدة 48 إلى 72 ساعة لضمان اكتمال انتشار الـ DNS عالمياً.
  2. أنشئ نسخة احتياطية نهائية وأرشيفية مشفرة لملفات وقواعد البيانات على خدمة تخزين خارجية (Cold Storage / S3).
  3. بعد انقضاء المهلة واستقرار النظام، يمكنك حذف الخادم أو إلغاء الخدمة بأمان كامل.
تحتاج تنفيذ هذا عملياً؟

راسلنا على واتساب وسنحوّل هذا المقال إلى خطة عمل واضحة لموقعك.

تواصل عبر واتساب

10. مرجع الأوامر السريع (مرجع سريع)

الإجراء الأمر
نقل قاعدة البيانات ssh OLD "mysqldump --single-transaction DB" | ssh NEW "mysql DB"
مزامنة الملفات rsync -avzP --exclude='*.log' /src/ user@NEW:/dest/
فحص استجابة الخادم الجديد curl -Iv https://example.com/ --resolve example.com:443:NEW_IP
فحص عدد السجلات SELECT COUNT(*), MAX(date_col) FROM table_name;
مراقبة الاتصالات القائمة ss -tn state established '( dport = :80 or dport = :443 )'
إيقاف الخدمات بأمان systemctl stop nginx && systemctl disable nginx

11. الخلاصة

تحويل ناجح بدون توقف يقوم على أربع ركائز: نقل مباشر مشفر يوفر المساحة والوقت، اختبار مسبق كامل قبل تغيير إعدادات DNS، التحقق من التطابق للبيانات والملفات، ثم إيقاف آمن تدريجي ومراقبة حية قبل الحذف النهائي. اتبع هذا الترتيب كل مرة، وستنتقل مواقعك بين الخوادم بثقة مهندس لا بمغامرة.

وإذا كان النقل جزءاً من خطة أوسع لاستضافة أسرع، فـالاستضافة السحابية المُدارة هي الخطوة التالية — موارد مضمونة ونسخ يومي بدل خادم مزدحم بلا إدارة.