الـ instructions الأساسية
| الـ instruction | بيعمل إيه |
|---|---|
FROM | الـ base image |
WORKDIR | فولدر الشغل جوه الـ image (ويتعمل لو مش موجود) |
COPY | ينسخ ملفات من الـ build context للـ image |
RUN | أمر وقت البناء، بيعمل طبقة |
ENV | متغيّر بيئة ثابت في الـ image |
EXPOSE | توثيق للبورت اللي التطبيق بيسمع عليه (مش بيفتحه) |
USER | يشغّل اللي بعده بمستخدم معين بدل root |
CMD | الأمر الافتراضي لما الـ container يقوم |
سر السرعة: الـ layer cache
كل instruction بتعمل طبقة، و Docker بيعمل cache لكل طبقة. لو الطبقة وكل اللي قبلها متغيّروش، بيستخدم الكاش. أول ما طبقة تتغيّر، كل اللي بعدها يتبني من جديد.
عشان كده الترتيب مهم: الحاجات اللي بتتغير قليل (الـ dependencies) فوق، والحاجات اللي بتتغير كتير (الكود) تحت.
🧪 Lab: API بـ Node
Dockerfile
FROM node:22-alpineWORKDIR /app# انسخ ملفات الـ dependencies الأول بس → الكاش يفضل شغال لما الكود يتغيرCOPY package.json package-lock.json ./RUN npm ci --omit=dev# بعدين الكودCOPY . .ENV NODE_ENV=productionEXPOSE 3000USER nodeCMD ["node", "src/index.js"]ولو بتستخدم pnpm، فعّله بـ corepack enable جوه الـ image وانسخ pnpm-lock.yaml بدل package-lock.json (راجع الـ docs لأمر التسطيب المناسب).
.dockerignore
زي .gitignore بس للـ build context. من غيره، COPY . . هينسخ node_modules بتاعتك (وممكن تكون لنظام تشغيل تاني!) و .env بأسرارك.
.dockerignore
node_modulesdist.git.env*.logDockerfiledocker-compose.yml🧪 Lab: React app بـ multi-stage
React بعد الـ build مجرد ملفات static. مش محتاج Node في الـ production خالص، محتاج web server زي nginx. هنا ييجي الـ multi-stage build: stage يبني، و stage تاني ياخد الناتج بس.
Dockerfile
# Stage 1: البناءFROM node:22-alpine AS buildWORKDIR /appCOPY package.json package-lock.json ./RUN npm ciCOPY . .RUN npm run build# Stage 2: التشغيل — nginx بس + ملفات الـ buildFROM nginx:alpineCOPY --from=build /app/dist /usr/share/nginx/htmlEXPOSE 80build stagenode + node_modules + كود ≈ مئات الميجات
COPY --fromdist بس
final imagenginx + static ≈ عشرات الميجات
ابني وشغّل
terminal
docker build -t my-api ./apidocker run -d --name api -p 3000:3000 my-apidocker build -t my-web ./webdocker run -d --name web -p 8080:80 my-webخلّصت الفصل لما
🧠 اختبر نفسك
١) غيّرت سطر في src/index.js. أنهي طبقات هتتبني تاني؟
من
COPY . . وانت نازل. طبقة npm ci هتيجي من الكاش.٢) ليه final image بتاعة React مفيهاش node_modules؟
عشان الـ multi-stage: آخر stage بياخد
dist بس من الـ build stage.٣) عملت docker run -e VITE_API_URL=... والـ React لسه بيكلم الـ URL القديم. ليه؟
متغيّرات Vite بتتحط وقت الـ build، مش وقت التشغيل.