Docker وTypeScript: حاويات التطبيقات المتقدمة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

Docker وTypeScript: حاويات التطبيقات المتقدمة

\n\n

حاويات تطبيقات TypeScript باستخدام Docker ليست مجرد تغليف للكود في صورة. على المستوى المتقدم، إنها فن التحسين والأمان والأتمتة. في هذه المقالة، سنشرح كيفية إنشاء صور Docker فعالة لـ TypeScript، وإدارة البيئة، ودمج الحاويات في خط أنابيب CI/CD. ستتعلم كيفية تقليل حجم الصورة بمقدار 5-10 مرات، وتسريع البناء، وتحسين عزل التبعيات.

\n\n

1. البناء متعدد المراحل (Multi-stage builds) لـ TypeScript

\n\n

المشكلة الكلاسيكية لصور Docker الخاصة بـ TypeScript هي تضمين جميع أدوات التطوير في الصورة النهائية: مترجم TypeScript، تبعيات التطوير، الملفات المصدرية. هذا يؤدي إلى أحجام ضخمة (غالبًا > 1 جيجابايت). الحل هو البناء متعدد المراحل.

\n\n

الفكرة بسيطة: المرحلة الأولى (build) تقوم بتجميع TypeScript إلى JavaScript وتثبيت جميع التبعيات. المرحلة الثانية (production) تنسخ فقط JavaScript الجاهز وتبعيات الإنتاج.

\n\n
# المرحلة 1: البناء\nFROM node:20-alpine AS builder\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci --only=development\nCOPY . .\nRUN npm run build\n\n# المرحلة 2: الإنتاج\nFROM node:20-alpine AS production\nWORKDIR /app\nCOPY --from=builder /app/dist ./dist\nCOPY --from=builder /app/package*.json ./\nRUN npm ci --only=production\nEXPOSE 3000\nCMD ["node", "dist/index.js"]
\n\n

هذا الأسلوب يقلل حجم الصورة من ~800 ميجابايت إلى ~150 ميجابايت. لاحظ استخدام --only=development و --only=production — هذه علامات أساسية لفصل التبعيات.

\n\n

2. تحسين التخزين المؤقت لطبقات Docker

\n\n

كل تعليمة في Dockerfile تنشئ طبقة. يقوم Docker بتخزين الطبقات مؤقتًا إذا لم تتغير. الترتيب الصحيح للتعليمات مهم جدًا لسرعة عمليات البناء المتكررة.

\n\n

مثال سيء (يكسر التخزين المؤقت):

\n
FROM node:20-alpine\nWORKDIR /app\nCOPY . .\nRUN npm ci\nRUN npm run build\nCMD ["node", "dist/index.js"]
\n\n

هنا، أي تغيير في الكود المصدري (حتى في README.md) يعيد تعيين التخزين المؤقت لـ npm ci والبناء.

\n\n

مثال جيد (يحافظ على التخزين المؤقت):

\n
FROM node:20-alpine AS builder\nWORKDIR /app\nCOPY package*.json tsconfig.json ./\nRUN npm ci --only=development\nCOPY src ./src\nRUN npm run build
\n\n

لماذا يعمل هذا؟ التبعيات تتغير نادرًا، بينما الكود المصدري يتغير كثيرًا. بنسخ package*.json بشكل منفصل، نضمن أن الطبقة التي تحتوي على npm ci تُعاد بناؤها فقط عند تغيير هذه الملفات.

\n\n

3. العمل مع متغيرات البيئة والأسرار

\n\n

لتطبيقات TypeScript على Node.js، استخدام متغيرات البيئة هو المعيار. ومع ذلك، هناك تفاصيل دقيقة في Docker.

\n\n

خطأ شائع: تمرير البيانات الحساسة (مفاتيح API، كلمات المرور) عبر ENV في Dockerfile. هذا يترك الأسرار في تاريخ طبقات الصورة.

\n\n

النهج الصحيح:

\n
    \n
  • استخدم --env-file عند تشغيل الحاوية
  • \n
  • للإنتاج، استخدم Docker Secrets (في Swarm) أو Kubernetes Secrets
  • \n
  • للتطوير المحلي، استخدم ملف .env مع docker-compose
  • \n
\n\n

مثال docker-compose.yml:

\n
version: '3.8'\nservices:\n  app:\n    build: .\n    ports:\n      - "3000:3000"\n    env_file:\n      - .env.production\n    volumes:\n      - ./logs:/app/logs
\n\n

في كود TypeScript، استخدم مكتبة dotenv لتحميل المتغيرات:

\n
import dotenv from 'dotenv';\nimport { resolve } from 'path';\n\ndotenv.config({ path: resolve(__dirname, '../.env') });\n\nconst config = {\n  port: parseInt(process.env.PORT || '3000', 10),\n  dbUrl: process.env.DATABASE_URL,\n  apiKey: process.env.API_KEY\n};\n\nexport default config;
\n\n

هام: لا تقم أبدًا بإضافة ملفات .env الحقيقية إلى نظام التحكم بالإصدارات

المدونات

توصيات الكتب