لماذا تستضيف Ghost ذاتيًا على خادم VPS
يجمع Ghost بين ما يفعله WordPress بعناء وما يفرض عليه Substack ثمنًا باهظًا: محرّر أنيق، وأداء أصلي ممتاز (Node.js)، وإدارة مدمجة للأعضاء والاشتراكات المدفوعة عبر Stripe، وإرسال النشرات البريدية دون إضافة. لكن Ghost(Pro) يحتسب التكلفة حسب حجم الجمهور، ومنصات النشرات البريدية تقتطع عمولة من إيراداتك.
وباستضافته على خادمك الـVPS، تحتفظ بـ 100% من مشتركيك المدفوعين (باستثناء رسوم Stripe)، وتخصّص القالب دون قيود، وتتحكم في قائمة بريدك الإلكتروني — وهي أثمن أصولك. ومع Ghost v6، يستفيد المبدعون الذين يحقّقون دخلًا من نشراتهم البريدية من تحصيل ضريبة القيمة المضافة تلقائيًا عبر Stripe Tax، دون أي اعتماد على خدمة طرف ثالث.
فوائد Ghost مُستضاف ذاتيًا
- لا عمولة منصة على اشتراكاتك المدفوعة (باستثناء Stripe)
- أداء أصلي: يُقاس زمن التحميل انطلاقًا من اتصال القارئ نفسه — ويتغيّر بحسب المشغّل والساعة والطريق المسلوك
- نشرات بريدية وأعضاء مدمجون، دون تكديس الإضافات
- تخصيص كامل لقالب Handlebars ووصول كامل إلى واجهة API
- تحكّم في قائمة مشتركيك وبياناتك
- تكلفة ثابتة للخادم الـVPS مهما كان عدد القرّاء
- Ghost v6: تحصيل ضريبة القيمة المضافة مدمج عبر Stripe Tax للمبدعين الذين يحقّقون دخلًا
متطلبات واقعية
يعمل Ghost v6 على Node.js 20 LTS كحدٍّ أدنى (يُنصح بـ Node 22 للأداء). خصّص خادم VPS بـ vCPU واحد و2 غيغابايت من الذاكرة RAM على الأقل لمدوّنة بحركة مرور مريحة، وارتقِ إلى 4 غيغابايت إن نما جمهورك بقوة أو إن كنت ترسل نشرات بريدية ضخمة. للاستخدام الإنتاجي، احجز 20 غيغابايت من القرص كحدٍّ أدنى للوسائط وقاعدة البيانات.
قاعدة البيانات الموصى بها في الإنتاج هي MySQL 8 (لا يُدعم SQLite إلا في بيئة التطوير — راجع قسم استكشاف الأخطاء). تحتاج أيضًا إلى خدمة SMTP للمعاملات (Mailgun أو Postmark أو Brevo) للإرسال الموثوق للنشرات البريدية ورسائل مصادقة الأعضاء، ونطاق blog.yourdomain.com يشير إلى عنوان IP خادمك، وCaddy أو Nginx كوكيل عكسي HTTPS. يُفضَّل Caddy لأنه يُوفّر شهادات Let's Encrypt ويجدّدها دون أي إعداد إضافي.
التثبيت عبر Ghost CLI (الطريقة الموصى بها)
تحضير الخادم
على Debian/Ubuntu، ثبّت Node.js 20 وMySQL 8 وNginx (مطلوب من قِبَل Ghost CLI للتحقق من التوافق) وCaddy. أنشئ مستخدمًا مخصصًا (ليس root):
adduser --disabled-login ghost-user
su - ghost-userتثبيت Ghost CLI
npm install ghost-cli@latest -gGhost CLI يتولّى التثبيت وعمليات ترحيل قواعد البيانات والتحديثات وإعادة تشغيل مدير العمليات PM2.
إنشاء المجلد وتشغيل التثبيت
mkdir -p /var/www/ghost
cd /var/www/ghost
ghost installيطلب منك المعالج رابط المدوّنة (مثل https://blog.yourdomain.com) وبيانات اعتماد MySQL وإعدادات SMTP وما إذا كنت تريد ضبط Nginx. أجب بـ لا على خطوة Nginx إن كنت تستخدم Caddy — ستضبطه في الخطوة التالية.
ضبط الوكيل العكسي TLS مع Caddy
أنشئ ملف Caddyfile أو عدّله:
blog.yourdomain.com {
reverse_proxy localhost:2368
encode gzip
header /ghost/* Cache-Control "no-store"
header /members/* Cache-Control "no-store"
}Caddy يحصل على شهادة Let's Encrypt ويجدّدها تلقائيًا. يستمع Ghost محليًا على المنفذ 2368؛ Caddy وحده هو المكشوف على المنفذَين 80 و443.
تأمين أول وصول
افتح المسار /ghost مباشرة بعد التثبيت: يعرض Ghost معالج إنشاء الحساب (الاسم والبريد الإلكتروني وكلمة المرور). أكمله دون تأخير — ما دام المعالج لم يكتمل، يمكن لأي شخص يصل إلى هذا العنوان أن يصبح مالك المدوّنة.
ربط خدمة SMTP
في الإعدادات → البريد الإلكتروني، تحقّق من صحة بيانات اعتماد SMTP وأرسل بريدًا اختباريًا. إرسال النشرات البريدية ورسائل تسجيل دخول الأعضاء يمرّان عبر هذا الإعداد — تنسيق MAIL_FROM خاطئ (دون نطاق موثَّق) هو أحد أكثر أسباب الأخطاء الصامتة عند التسجيل شيوعًا.
ربط Stripe وتفعيل الاشتراكات
في الإعدادات → الأعضاء، اربط حساب Stripe الخاص بك لتفعيل الاشتراكات المدفوعة. حدّد مستوياتك (tiers) وأسعارك الشهرية والسنوية، ثم انشر مقالك الأول وأرسل نشرتك البريدية الأولى.
تشغيل Caddy والتحقق من الوكيل العكسي
بعد كتابة ملف Caddyfile، شغّل Caddy أو أعِد تحميله لتطبيق الإعداد:
caddy run --config /etc/caddy/Caddyfileإذا كان Caddy مُدارًا كخدمة systemd (وهو الحال بعد التثبيت عبر APT)، فضّل أمر إعادة التحميل السلس دون انقطاع:
systemctl reload caddyيتصل Caddy فورًا بـ Let's Encrypt للحصول على شهادة TLS لنطاقك عبر تحدي HTTP-01. في غضون 30 ثانية، يجب أن يستجيب https://blog.yourdomain.com. تحقّق من حالة الشهادة:
curl -sv https://blog.yourdomain.com/ 2>&1 | grep -E 'SSL|subject|issuer'إذا أظهر الأمر issuer: O=Let's Encrypt، فالشهادة سارية. في حال ظهور connection refused، تحقّق من تشغيل Ghost على المنفذ 2368 بالأمر ghost status من مجلد التثبيت. إذا كان المنفذ 443 مغلقًا في جدار الحماية، افتحه قبل تشغيل Caddy: ufw allow 443.
Ghost v6 وStripe Tax: الحقل الجديد tax_id_collection
يُدخل Ghost v6 دعم الحقل tax_id_collection في واجهة API الخاصة بـ Stripe. يتيح هذا الحقل لـ Stripe Tax جمع رقم التسجيل الضريبي أو رقم تعريف المشتري تلقائيًا لحظة الدفع، وفق الأنظمة الضريبية الأوروبية والعالمية.
بالنسبة للنسخ الموجودة المُحدَّثة إلى Ghost v6، هذه الميزة هي ضبط من جانب Stripe، وليس تغييرًا في Ghost نفسه. نقطتان للتحقق:
1. في لوحة تحكم Stripe، فعّل Stripe Tax واضبط قواعدك الضريبية حسب البلد.
2. في Stripe → Checkout → الإعدادات، فعّل جمع الرقم الضريبي إن كان مطلوبًا في سوقك.
ستستمر نسخ Ghost v5 المُحدَّثة إلى v6 دون تعديل إعدادات Stripe في العمل، غير أن ميزات الامتثال الضريبي الجديدة ستظل غير نشطة حتى تضبط Stripe Tax من جانبك.
تحديث Ghost عبر Ghost CLI
يُبسّط Ghost CLI عمليات التحديث الصغيرة والكبيرة. من مجلد التثبيت:
cd /var/www/ghost
ghost updateلاستهداف إصدار محدد، مثلًا عند الانتقال من v5 إلى v6:
ghost update 6.x.xGhost CLI يوقف عملية PM2، ويُطبّق عمليات ترحيل قاعدة البيانات، ويُحدّث الملفات، ويُعيد تشغيل Ghost. إذا فشلت عملية ترحيل ما، يُجري Ghost CLI تراجعًا تلقائيًا ويعرض تفاصيل الخطأ في الطرفية.
قبل أي تحديث رئيسي (v5 → v6)، خطوتان وقائيتان لا غنى عنهما: احتفظ بنسخة احتياطية من مجلد المحتوى /var/www/ghost/content (الوسائط والثيمات المخصصة)، وصدّر قاعدة بيانات MySQL:
mysqldump -u ghost -p ghost_db > ghost_backup_$(date +%F).sqlأخيرًا، تحقّق من الإصدار المثبَّت بعد التحديث:
ghost versionرقم إصدار خاطئ بعد التحديث يدل عادةً على مشكلة في أذونات مجلد /var/www/ghost — تحقّق من أن المستخدم المخصص هو مالك المجلد.
استكشاف الأخطاء: أخطاء البدء الشائعة
يبدأ Ghost لكنه يُرجع صفحة بيضاء أو خطأ 500
تحقّق من السجلات بالأمر ghost log. أكثر الأسباب شيوعًا هي قيمة url غير صحيحة في config.production.json — يولّد Ghost جميع روابطه الداخلية من هذه القيمة، وعنوان HTTP بينما Caddy يخدم عبر HTTPS يُسبّب حلقات إعادة توجيه.
الخطأ «ER_NOT_SUPPORTED_AUTH_MODE» عند البدء
Ghost v6 يتطلّب MySQL 8 مع مكوّن المصادقة mysql_native_password. إن كان MySQL لديك يستخدم caching_sha2_password افتراضيًا، عدّل المستخدم:
ALTER USER 'ghost'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password';
FLUSH PRIVILEGES;SQLite في الإنتاج: لماذا ليس خيارًا
Ghost يقبل SQLite في وضع التطوير، لكن هذا المحرّك غير مدعوم في الإنتاج: لا يتعامل مع الوصول المتزامن، والنشرات البريدية الضخمة وذُرى حركة المرور تُسبّب أقفال قاعدة بيانات لا يمكن التراجع عنها. انتقل إلى MySQL قبل الإطلاق.
فشل رفع الثيم في الإنتاج
Ghost يُقيّد أحجام رفع الثيمات. إن فشل الرفع صامتًا أو أعاد خطأ 413، اضبط الحدّ من جانب Caddy:
blog.yourdomain.com {
request_body {
max_size 50MB
}
reverse_proxy localhost:2368
}MAIL_FROM مُعطَّل: الأعضاء لا يتلقّون رسائل بريدية
يجب أن يحمل الحقل mail.from في config.production.json عنوانًا يكون نطاقه موثَّقًا لدى مزوّد SMTP الخاص بك (سجلات SPF وDKIM نشطة). النطاق غير الموثَّق يُفضي إلى أخطاء صامتة عند التسجيل أو إلى رفض SMTP الذي نادرًا ما يُظهره Ghost بوضوح في سجلاته.
ضع Cloudflare في وضع الوكيل أمام Caddy لامتصاص ذُرى حركة المرور: كل محتوى Ghost العام تقريبًا ثابت ويُخزَّن مؤقتًا بكفاءة عالية. استثنِ /ghost/ و/members/ و/api/ من التخزين المؤقت عبر قواعد صفحة أو قاعدة تخزين مؤقت مخصصة — يجب أن تصل هذه المسارات دائمًا مباشرةً إلى Ghost لكي تعمل مصادقة الأعضاء واللوحة الإدارية بصورة صحيحة.
النسخ الاحتياطية التلقائية
يعيش المحتوى الديناميكي لـ Ghost (الوسائط والثيمات المخصصة) في /var/www/ghost/content. أضف مهمة cron تحتفظ بنسخة احتياطية من هذا المجلد وتصدير MySQL يومي إلى تخزين بعيد. لا يحتفظ Ghost CLI بنسخ احتياطية تلقائيًا.
# تصدير MySQL يومي — أضفه إلى crontab
0 2 * * * mysqldump -u ghost -p ghost_db | gzip > /backups/ghost-$(date +%F).sql.gzالتوثيق الرسمي
للإعداد المتقدّم والخيارات الخاصة بالأداة، ارجع إلى التوثيق الرسمي لـ Ghost. يغطي هذا الدليل النشر على خادم VPS؛ ويبقى توثيق الناشر المرجعَ للإعدادات الدقيقة والتحديثات الكبرى وحالات الاستخدام الخاصة.