النشر: Docker والـ Monorepo والخوادم بلا خادم (Serverless)
النشر: Docker والـ Monorepo والخوادم بلا خادم (Serverless)
تنقّل تطبيق NestJS من حاسوبك إلى الإنتاج يتطلّب ثلاث مهارات مترابطة: تغليفه بشكل قابل للتكرار بـ Docker، وتنظيم قاعدة كود كبيرة على شكل Nest monorepo، ونشره اختياريًّا بوصفه دالة serverless على AWS Lambda. يستعرض هذا الدرس الثلاثة بأمثلة جاهزة للإنتاج.
Dockerfile متعدد المراحل
يُضمّن بناء Docker البسيط المرحلة الواحدة مجلد node_modules بالكامل — بما يشمل آلاف الاعتماديات التطويرية — في الصورة، مما يرفع حجمها إلى مئات الميغابايت. يستخدم البناء متعدد المراحل مراحل منفصلة للبناء والتشغيل حتى تحتوي الصورة النهائية على ما هو ضروري فقط:
npm ci، وليس npm install. يُثبّت npm ci ما هو موجود بالضبط في package-lock.json، مما يمنحك بناءً قابلًا للتكرار والتحديد في كل مرة. قد يُحدّث npm install بصمت إصدارات التصحيح.
تنسخ الصورة النهائية dist/ فقط وnode_modules للإنتاج من طبقة المُنشئ. والنتيجة عادةً أقل من 200 ميغابايت مقابل أكثر من 600 ميغابايت في حالة البناء البسيط.
إعداد الإنتاج
لا يُقبل أبدًا ترميز الأسرار أو عناوين URL بشكل ثابت. استخدم متغيرات البيئة وConfigModule الخاص بـ NestJS — المُهيَّأ مرة واحدة على مستوى الوحدة مع التحقق من الصحة عبر Joi أو مخطط class-validator:
.env أبدًا في نظام التحكم بالإصدار. خزّن الأسرار في مدير أسرار خط CI/CD الخاص بك (GitHub Actions Secrets، AWS Secrets Manager، إلخ) وأدخلها في وقت التشغيل كمتغيرات بيئة. ملف .env المُسرَّب في تاريخ git يصعب تطهيره بأمان.
مساحات عمل Nest monorepo
مع نمو مشروعك قد تحتاج إلى تطبيقات متعددة قابلة للنشر (مثل خادم API وعامل خلفي) تتشارك مكتبات مشتركة. تدعم واجهة CLI الخاصة بـ Nest وضع monorepo الذي يدير ذلك بملف واحد nest-cli.json:
apps/— كل مجلد فرعي تطبيق مستقل قابل للنشر بملفmain.tsالخاص به.libs/— كود مشترك (DTOs، أدوات مساعدة، نماذج قاعدة البيانات) يستورده أي تطبيق عبر مسارات مستعارة بأسلوب@app/shared.- بناء تطبيق محدد:
nest build api— الناتج فيdist/apps/api/. - التشغيل في وضع التطوير:
nest start api --watchبالتوازي معnest start worker --watch.
النشر بلا خادم على AWS Lambda
يُزيل Serverless الحاجة إلى إدارة مثيلات الخادم. يمكن تشغيل NestJS على AWS Lambda باستخدام محوّل @nestjs/platform-express أو @vendia/serverless-express، الذي يُغلّف تطبيق Express ويترجم أحداث Lambda إلى طلبات HTTP:
اختيار هدف النشر
- حاويات (Docker + ECS / Kubernetes) — الأفضل للاتصالات طويلة الأمد وذات الحالة (WebSockets، SSE) وزمن الاستجابة المتوقع والتطبيقات الكبيرة.
- بلا خادم (Lambda / Cloud Run) — الأفضل لواجهات API المدفوعة بالأحداث ذات حركة المرور المتفجرة، والتكاليف التشغيلية المنخفضة، والفوترة بحسب الطلب.
- Monorepo — متعامد مع كليهما؛ يُحدد كيفية تنظيم الكود، لا مكان تشغيله.
الخلاصة
يجمع نشر NestJS الإنتاجي بين: Dockerfile متعدد المراحل يُبقي الصورة النهائية خفيفة بفصل البناء عن التشغيل، وConfigModule مع التحقق من الصحة بالمخطط لضمان وجود جميع متغيرات البيئة المطلوبة وأنواعها الصحيحة، وNest monorepo اختياري لمشاركة الكود بين تطبيقات متعددة عبر مجلدات apps/ وlibs/، ومحوّل serverless (@vendia/serverless-express) عند استهداف AWS Lambda مع بوتستراب مُخزَّن لتقليل زمن التشغيل البارد. اختَر هدف النشر بناءً على أنماط حركة المرور ومتطلبات التشغيل.