لماذا الاستضافة الذاتية لـ Rails على خادم VPS؟
يجمع تطبيق Rails في بيئة الإنتاج بين عدّة عمليات: خادم الويب Puma، وعمّال Sidekiq للمهام غير المتزامنة، وPostgreSQL وRedis. تفرض المنصّات المُدارة رسومًا على كلّ dyno أو عامل على حدة، مما يرفع الفاتورة بمجرّد نموّ التطبيق. على خادم VPS، تتعايش جميع هذه العمليات على خادم واحد تتحكّم فيه: تضبط عدد خيوط وعمّال Puma، وتُشغّل من عمّال Sidekiq بقدر ما تسمح به الذاكرة، وتُدير التصريف المسبق للأصول والتخزين المؤقّت. ومع Rails 7 وما بعده، يزيد التكامل الأصلي مع Propshaft وSolid Queue وSolid Cache من تبسيط الاستضافة الذاتية. تحافظ على تكلفة ثابتة وحزمة شفّافة بالكامل.
الفوائد الملموسة لاستضافة Rails ذاتيًا
- Puma وSidekiq على خادم VPS نفسه، دون فرض رسوم على كلّ عامل على حدة.
- ضبط عدد خيوط وعمّال Puma وفقًا للأنوية والذاكرة.
- مهام خلفية غير محدودة مع Sidekiq/Redis أو Solid Queue.
- PostgreSQL تحت السيطرة: الفهارس ونسخ
pg_dumpالاحتياطية وضبط الاتصالات. - التصريف المسبق للأصول والتخزين المؤقّت لـ Rails يُدار محليًا، دون تكلفة إضافية.
- تكلفة ثابتة وقابلة للتوقّع، مثالية لتطبيقات SaaS والتطبيقات المهنية المتنامية.
المتطلّبات العتادية والبرمجية
يستهلك Rails ذاكرة أكثر من المتوسّط بسبب عمّال Puma وSidekiq: استهدف 2 جيجابايت كحدّ أدنى، و4 جيجابايت بمجرّد تشغيل عدّة عمّال أو إضافة Redis وElasticsearch. ثبّت Ruby 3.2+ عبر rbenv أو asdf، أو استخدم صورة Docker باسم ruby:3.3-slim. جهّز PostgreSQL 15، وRedis لـ Sidekiq والتخزين المؤقّت، وNode.js إذا كنت تستخدم مُجمِّع JS، وBundler. يعمل Nginx كواجهة أمامية لـ TLS والأصول الثابتة. يلزم توجيه نطاق نحو خادم VPS. عيّن RAILS_ENV=production وأنشئ SECRET_KEY_BASE.
نشر Rails خطوة بخطوة
تجهيز الخادم والتطبيق
عبر SSH، ثبّت Ruby 3.3 وPostgreSQL وRedis (أو Docker). استنسخ المستودع واضبط المتغيّرات: DATABASE_URL وREDIS_URL وRAILS_MASTER_KEY وSECRET_KEY_BASE. شغّل bundle install --without development test.
التصريف المسبق للأصول والترحيل
نفّذ RAILS_ENV=production bin/rails assets:precompile ثم bin/rails db:migrate. مع Rails 7+، يبسّط Propshaft وimportmap خطّ أنابيب الأصول دون بناء Node معقّد.
تشغيل Puma
ابدأ الخادم عبر bundle exec puma -C config/puma.rb، مع ضبط WEB_CONCURRENCY (العمّال) وRAILS_MAX_THREADS في البيئة. اجعل Puma يستمع على مقبس Unix للحصول على أداء أفضل مع Nginx، وأدر العملية عبر systemd.
تشغيل عمّال Sidekiq
أنشئ خدمة systemd تُشغّل bundle exec sidekiq -e production -C config/sidekiq.yml، مع إعادة تشغيل تلقائية. اضبط عدد خيوط Sidekiq وفقًا لحمل المهام والذاكرة المتاحة.
إعداد Nginx وSSL
وجّه Nginx نحو مقبس Puma عبر upstream وproxy_pass، وقدّم public/assets مباشرةً مع تخزين مؤقّت طويل، ثمّ احصل على شهادة Let's Encrypt باستخدام Certbot لـ yourdomain.com. افرض HTTPS والتجديد التلقائي.
أتمتة عمليات النشر
أنشئ سكربتًا أو استخدم Kamal/Capistrano يسلسل git pull وbundle install وdb:migrate وassets:precompile وإعادة تشغيل Puma وSidekiq. يتيح النشر الذرّي عبر الروابط الرمزية العودة إلى الوراء فورًا عند حدوث مشكلة.
راقب البصمة الذاكرية لـ Puma: تتضخّم عمليات Ruby بمرور الوقت بسبب تجزئة الذاكرة. فعّل jemalloc كمُخصّص للذاكرة (عبر LD_PRELOAD) لتقليل الذاكرة التي يستهلكها العمّال بشكل ملحوظ، واضبط إعادة تشغيل دورية لعمّال Puma. على خادم VPS تكون فيه الذاكرة أكثر مورد محدود لـ Rails، قد يُغنيك هذا الضبط وحده عن الترقية إلى فئة أعلى.