نظرة عامة
يحدد Dockerfile كيفية بناء Docker صورة. تغطي هذه الورقة المرجعية جميع 17 تعليمة أساسية، أنماط متقدمة مثل البناء متعدد المراحل وتثبيتات ذاكرة التخزين المؤقت، أفضل الممارسات الأمنية والأداء، وتقنيات التحسين. جميع الصيغ حالية لـ Docker 27.
التعليمات الأساسية
FROM
| التعليمة | الغرض | مثال |
|---|---|---|
FROM <image>:<tag> |
تعيين الصورة الأساسية (يجب أن تكون السطر الأول، باستثناء التعليقات/ARG) | FROM ubuntu:24.04 |
FROM <image>:<tag> AS <stage> |
تعيين مرحلة مسماة في بناء متعدد المراحل | FROM golang:1.22 AS builder |
FROM scratch |
البدء من أساس فارغ (للملفات الثنائية الثابتة فقط) | FROM scratch |
ملاحظات:
– يمكنك استخدام عدة بيانات FROM لإنشاء عدة مراحل بناء.
– تعيد كل FROM تعيين نظام الملفات؛ يتم تجاهل الطبقات السابقة ما لم يتم نسخها صراحةً.
– scratch يحتوي فقط على ما تضيفه صراحةً؛ أصغر صورة ممكنة.
RUN
| التعليمة | الغرض | مثال |
|---|---|---|
RUN <command> |
تشغيل أمر أثناء البناء (نموذج shell) | RUN apt-get update && apt-get install -y curl |
RUN ["executable", "param1", "param2"] |
تشغيل أمر بنموذج exec (بدون shell) | RUN ["python3", "-m", "pip", "install", "django"] |
أفضل الممارسات:
– استخدم نموذج exec عندما يكون ممكناً لتجنب مشاكل تفسير shell.
– اربط الأوامر بـ && للحفاظ على الطبقات صغيرة: RUN apt-get update && apt-get install && apt-get clean
– نظّف ذاكرة مدير الحزم المؤقتة: rm -rf /var/lib/apt/lists/* (apt)، apk del .build-deps (apk)
– استخدم أعلام --no-cache في مديري الحزم لتقليل حجم الطبقة.
COPY
| التعليمة | الغرض | مثال |
|---|---|---|
COPY <source> <dest> |
نسخ الملفات/المجلدات من سياق البناء إلى الصورة | COPY app.py /app/app.py |
COPY --chown=<user>:<group> <source> <dest> |
النسخ وتعيين الملكية | COPY --chown=appuser:appuser . /app/ |
COPY --chmod=<mode> <source> <dest> |
النسخ وتعيين أذونات الملف | COPY --chmod=755 script.sh /app/script.sh |
أفضل الممارسات:
– يُفضل COPY على ADD للنسخ البسيطة للملفات.
– استخدم .dockerignore لاستثناء القطع الأثرية وملفات الاختبار و .git.
– انسخ فقط ما تحتاجه؛ اقسم إلى عدة أسطر COPY لكفاءة ذاكرة التخزين المؤقت.
ADD
| التعليمة | الغرض | مثال |
|---|---|---|
ADD <source> <dest> |
نسخ الملفات/المجلدات مع ميزات إضافية (استخراج tar وجلب URL) | ADD archive.tar.gz /app/ |
ADD --chown=<user>:<group> <source> <dest> |
الإضافة مع الملكية | ADD --chown=appuser:appuser file.txt /app/ |
ADD --chmod=<mode> <source> <dest> |
الإضافة مع أذونات الملف | ADD --chmod=644 config.txt /etc/config.txt |
ملاحظات:
– إذا كان المصدر أرشيف tar/zip/gzip، يتم استخراجه تلقائياً.
– إذا كان المصدر عنوان URL، يتم تحميله (بدون استخراج).
– عادةً ما يكون COPY أوضح؛ استخدم ADD فقط لاستخراج tar أو جلب URL.
WORKDIR
| التعليمة | الغرض | مثال |
|---|---|---|
WORKDIR <path> |
تعيين دليل العمل لجميع الأوامر اللاحقة (RUN و CMD و ENTRYPOINT و COPY و ADD) | WORKDIR /app |
ملاحظات:
– إذا لم يكن المجلد موجوداً، يتم إنشاؤه.
– استخدم المسارات المطلقة لتجنب الالتباس.
– عدة تعليمات WORKDIR تراكمية: WORKDIR /app ثم WORKDIR src تؤدي إلى /app/src.
ENV
| التعليمة | الغرض | مثال |
|---|---|---|
ENV <key>=<value> |
تعيين متغير بيئي (متاح في الحاوية قيد التشغيل) | ENV NODE_ENV=production |
ENV <key> <value> |
صيغة بديلة (عفا عليها الزمن، تجنب) | ENV DEBUG true |
ملاحظات:
– ينقل إلى الحاويات؛ عيّن مرة واحدة أثناء البناء، متاح في وقت التشغيل.
– استخدم لإعدادات مستوى التطبيق (عناوين URL لقاعدة البيانات وكلمات مرور API للاختبار).
– لا تستخدم ENV للأسرار؛ استخدم أسرار Docker أو مرر في وقت التشغيل.
ARG
| التعليمة | الغرض | مثال |
|---|---|---|
ARG <name>=<default> |
تحديد متغير وقت البناء (غير متاح في الحاوية قيد التشغيل) | ARG PYTHON_VERSION=3.12 |
ARG <name> |
تحديد متغير بدون افتراضي (يجب توفيره مع --build-arg) |
ARG BUILD_NUMBER |
الاستخدام في البناء:
docker build --build-arg PYTHON_VERSION=3.11 -t myapp:1.0 .
ملاحظات:
– متغيرات ARG تُستخدم فقط أثناء البناء؛ لا تظهر في الصورة النهائية.
– لتمرير قيمة ARG إلى الحاوية قيد التشغيل، أعد تعيينها باستخدام ENV: ENV PYTHON_VERSION=$PYTHON_VERSION
EXPOSE
| التعليمة | الغرض | مثال |
|---|---|---|
EXPOSE <port> |
توثيق أن حاوية تستمع على منفذ (لا تنشره) | EXPOSE 8080 |
EXPOSE <port>/udp |
توثيق منفذ UDP | EXPOSE 53/udp |
EXPOSE <port1> <port2> |
توثيق منافذ متعددة | EXPOSE 8080 8443 |
ملاحظات:
– EXPOSE هي بيانات وصفية فقط؛ لا تنشر المنفذ فعلياً.
– للنشر، استخدم docker run -p <host>:<container> أو Docker Compose ports:.
– مفيد للتوثيق ولـ docker run -P (منافذ عالية الرقم عشوائية).
USER
| التعليمة | الغرض | مثال |
|---|---|---|
USER <user> |
تعيين المستخدم (أو UID) للأوامر اللاحقة (RUN و CMD و ENTRYPOINT و COPY و ADD) | USER appuser |
USER <uid>:<gid> |
استخدم UID و GID مباشرة | USER 1000:1000 |
أفضل ممارسة أمنية:
RUN groupadd -r appgroup && useradd -r -g appgroup appuser
USER appuser
ملاحظات:
– التشغيل كـ root في حاوية مخاطرة أمنية.
– استخدم مستخدماً مخصصاً بدون جذر لتحديد دائرة الانفجار عند الهروب من الحاوية.
– يجب إنشاؤها قبل تعليمة USER (استخدم RUN).
HEALTHCHECK
| التعليمة | الغرض | مثال |
|---|---|---|
HEALTHCHECK --interval=<seconds> --timeout=<seconds> --start-period=<seconds> --retries=<count> CMD <command> |
تحديد أمر فحص صحي | HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 CMD curl -f http://localhost:8000/health \|\| exit 1 |
HEALTHCHECK NONE |
تعطيل فحص صحي موروث من الصورة الأساسية | HEALTHCHECK NONE |
الخيارات:
– --interval: عدد مرات تشغيل الفحص (الافتراضي: 30 ثانية)
– --timeout: كم من الوقت ننتظر الفحص (الافتراضي: 30 ثانية)
– --start-period: فترة رحمة قبل الفحص الأول (الافتراضي: 0 ثانية)
– --retries: الأخطاء المتتالية قبل وضع العلامة كغير صحي (الافتراضي: 3)
ملاحظات:
– رمز الخروج 0 = صحي، 1 = غير صحي، 2 = محجوز.
– يستخدم Docker Compose وموجهات الحاويات حالة الصحة لإعادة التشغيل/الاستبدال.
ENTRYPOINT
| التعليمة | الغرض | مثال |
|---|---|---|
ENTRYPOINT ["executable", "param1"] |
تحديد العملية الرئيسية للحاوية (نموذج exec، مفضل) | ENTRYPOINT ["python3", "-u", "app.py"] |
ENTRYPOINT command param1 |
تحديد العملية الرئيسية (نموذج shell، تجنب) | ENTRYPOINT python3 -u app.py |
نموذج Exec مقابل نموذج Shell:
– نموذج Exec: يشغل التنفيذي مباشرة؛ يتم تسليم الإشارات (SIGTERM) بشكل صحيح؛ بدون تفسير shell.
– نموذج Shell: يلف الأمر في /bin/sh -c؛ معالجات shell الإشارات وليس تطبيقك؛ يمكن أن يسبب عمليات zombie.
مع CMD:
ENTRYPOINT ["python3"]
CMD ["app.py"]
# docker run image arg → python3 app.py arg
ملاحظات:
– يحدد ENTRYPOINT ما لا يمكن تجاوزه بسهولة.
– استخدم دائماً نموذج exec لـ ENTRYPOINT.
CMD
| التعليمة | الغرض | مثال |
|---|---|---|
CMD ["executable", "param1", "param2"] |
توفير حجج أو أمر افتراضي (نموذج exec، مفضل) | CMD ["python3", "app.py"] |
CMD command param1 |
توفير حجج افتراضية (نموذج shell، تجنب) | CMD python3 app.py |
CMD ["param1", "param2"] |
توفير حجج افتراضية إلى ENTRYPOINT | CMD ["production"] |
ملاحظات:
– إذا لم يتم تعيين ENTRYPOINT، فإن CMD هو الأمر.
– إذا تم تعيين ENTRYPOINT، فإن CMD يوفر حجج له.
– استخدم دائماً نموذج exec لـ CMD.
VOLUME
| التعليمة | الغرض | مثال |
|---|---|---|
VOLUME <path> |
وضع علامة على مجلد كنقطة تثبيت حجم | VOLUME /data |
VOLUME ["<path1>", "<path2>"] |
وضع علامة على نقاط تثبيت متعددة | VOLUME ["/var/log", "/data"] |
ملاحظات:
– VOLUME إعلانية؛ توثق أن مجلداً يجب أن يبقى أو يتم تثبيته.
– لا ينشئ حجماً فعلياً؛ يتم إنشاء الحجم في وقت التشغيل.
– في وقت التشغيل: docker run -v myvolume:/data image أو docker run -v /host/path:/data image
LABEL
| التعليمة | الغرض | مثال |
|---|---|---|
LABEL <key>=<value> |
إضافة بيانات وصفية إلى صورة | LABEL maintainer="team@example.com" |
LABEL <key1>=<value1> <key2>=<value2> |
إضافة عدة تسميات | LABEL version="1.0" description="My app" |
ملاحظات:
– التسميات قابلة للبحث: docker images --filter "label=version=1.0"
– التسميات الشائعة: maintainer، version، description، org.opencontainers.image.*
STOPSIGNAL
| التعليمة | الغرض | مثال |
|---|---|---|
STOPSIGNAL SIGTERM |
الإشارة المراد إرسالها عند إيقاف الحاوية (الافتراضي: SIGTERM) | STOPSIGNAL SIGTERM |
STOPSIGNAL SIGKILL |
إشارة قتل القوة (نادراً ما تكون مطلوبة) | STOPSIGNAL SIGKILL |
ملاحظات:
– معظم التطبيقات تتعامل مع SIGTERM (15) للإيقاف الرشيق.
– استخدم SIGKILL (9) فقط إذا لم يتعامل تطبيقك مع SIGTERM.
SHELL
| التعليمة | الغرض | مثال |
|---|---|---|
SHELL ["<executable>", "<param>"] |
تجاوز shell الافتراضي (الافتراضي: ["/bin/sh", "-c"] على Linux) |
SHELL ["/bin/bash", "-c"] |
حالة الاستخدام:
FROM mcr.microsoft.com/windows/servercore:ltsc2022
SHELL ["powershell", "-Command", "-ErrorActionPreference", "Stop"]
RUN Get-ChildItem
ONBUILD
| التعليمة | الغرض | مثال |
|---|---|---|
ONBUILD <instruction> |
تشغيل تعليمة في الصور الفرعية (نادراً ما تُستخدم) | ONBUILD RUN npm install |
ملاحظات:
– عندما تستخدم صورة فرعية FROM <parent>، يتم تنفيذ تعليمات ONBUILD من الأصل.
– مفيدة لصور الأساس التي تنظم عمليات البناء؛ تجنب في Dockerfiles التطبيق.
البناء متعدد المراحل
يقلل البناء متعدد المراحل حجم الصورة النهائية بواسطة استخدام المراحل الوسيطة للبناء ومرحلة نهائية بها فقط تبعيات التشغيل.
النمط: Builder + Runtime
# المرحلة 1: البناء
FROM golang:1.22 AS builder
WORKDIR /src
COPY . .
RUN go build -o app .
# المرحلة 2: التشغيل (الحد الأدنى)
FROM alpine:3.20
COPY --from=builder /src/app /app
ENTRYPOINT ["/app"]
الفوائد الرئيسية:
– تبعيات البناء (المترجمات وأدوات التطوير) ليست في الصورة النهائية.
– الصورة النهائية تحتوي فقط على الملف الثنائي المترجم.
– يمكن تقليل حجم الصورة من 500 ميجابايت إلى 10 ميجابايت أو أقل.
متقدم: المراحل المسماة والبناء الشروطي
FROM golang:1.22 AS builder
ARG BUILD_TARGET=linux
WORKDIR /src
COPY . .
RUN GOOS=linux GOARCH=amd64 go build -o app .
FROM alpine:3.20 AS runtime
COPY --from=builder /src/app /app
USER nobody
ENTRYPOINT ["/app"]
# الاستخدام: docker build --target runtime -t myapp:latest .
تثبيتات ذاكرة التخزين المؤقت (Docker 19.03+)
تحافظ تثبيتات ذاكرة التخزين المؤقت على الملفات بين عمليات البناء، مما يتيح التثبيت الأسرع للحزم وتخزين التبعيات المؤقت.
FROM python:3.12-alpine
WORKDIR /app
# تثبيت ذاكرة مؤقتة لحزم pip
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r requirements.txt
# الاستخدام: docker build --build-context . -t myapp:1.0 .
حالات الاستخدام:
– ذاكرة مدير الحزم المؤقتة (pip، npm، cargo، إلخ)
– ذاكرة التخزين المؤقت للقطع الأثرية البناء (Go cache، Rust target، Maven .m2)
أمر البناء:
docker build -t myapp:1.0 --build-context .
.dockerignore
استخدم .dockerignore لاستثناء الملفات من سياق البناء، مما يقلل حجم الطبقة ووقت البناء.
# .dockerignore
.git
.gitignore
.env
.env.local
*.pyc
__pycache__
.pytest_cache
node_modules
dist
build
*.log
README.md
.vscode
.idea
.DS_Store
ملاحظات:
– الأنماط تعمل مثل .gitignore.
– يقلل حجم السياق المرسل إلى Docker daemon.
– يمكن أن يسرع عمليات البناء بشكل كبير على المشاريع الكبيرة.
أفضل الممارسات الأمنية
التشغيل بدون جذر
FROM alpine:3.20
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
COPY --chown=appuser:appgroup . /app
USER appuser
ENTRYPOINT ["./app"]
إسقاط القدرات غير الضرورية
RUN setcap -r /bin/app # إزالة جميع القدرات من التنفيذي
# أو في وقت التشغيل: docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE image
استخدام نظام ملفات للقراءة فقط
# في وقت التشغيل: docker run --read-only --tmpfs /tmp image
صور أساسية بالحد الأدنى
alpine:3.20(~7 MB) — يُنصح به لمعظم الحالاتdistroless/python3-nonroot(~50 MB) — محسّن مسبقاً وبدون مدير حزمscratch(~0 MB) — للملفات الثنائية الثابتة فقط
أفضل الممارسات للحجم
تنظيف ذاكرة مدير الحزم المؤقتة
# Alpine
RUN apk add --no-cache python3 py3-pip
# Debian/Ubuntu
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
# pip
RUN pip install --no-cache-dir django
دمج أوامر RUN
# سيء (3 طبقات)
RUN apt-get update
RUN apt-get install -y curl
RUN rm -rf /var/lib/apt/lists/*
# جيد (1 طبقة)
RUN apt-get update && \
apt-get install -y curl && \
rm -rf /var/lib/apt/lists/*
استخدم COPY بشكل استراتيجي
# انسخ فقط ما تحتاجه بترتيب تغيير التكرار
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY src ./src
# تغيير src لا يلغي طبقة pip
الأنماط التي ستعاد استخدامها
# صورة أساسية مع ARG لالإصدار
FROM python:${PYTHON_VERSION:-3.12}-alpine AS base
# متعدد المراحل مع حجج البناء
FROM node:20-alpine AS builder
ARG NODE_ENV=production
RUN npm ci --only=production
# فحص صحي مع curl
HEALTHCHECK --interval=30s --timeout=5s \
CMD curl -f http://localhost:3000/health || exit 1
# مستخدم بدون جذر برقم معرّف ثابت للقابلية للتكرار
RUN adduser -D -u 1000 appuser
# نسخ مع الملكية للمستخدم بدون جذر
COPY --chown=appuser:appuser . /app
# استخدم ذاكرة البناء المؤقتة لمديري الحزم
RUN --mount=type=cache,target=/root/.cache/pip pip install -r requirements.txt
# نموذج Exec ENTRYPOINT + CMD
ENTRYPOINT ["python3", "-u"]
CMD ["app.py"]
الأسئلة الشائعة
ما الفرق بين COPY و ADD؟
COPY أبسط وأفضل للملفات المحلية. يمكن لـ ADD استخراج أرشيفات tar وجلب عناوين URL، لكن هذه الميزات يمكن أن تسبب سلوكاً غير متوقع. استخدم COPY ما لم تحتج تحديداً إلى استخراج tar أو جلب URL.
هل يجب أن أستخدم ENV أم ARG؟
ARG لمتغيرات وقت البناء (متاح فقط أثناء البناء وليس في الحاوية قيد التشغيل). ENV لمتغيرات التشغيل (متاح في الحاوية قيد التشغيل). استخدم ARG لإعدادات البناء و ENV لإعدادات التطبيق.
ما الفرق بين ENTRYPOINT و CMD؟
يحدد ENTRYPOINT العملية الرئيسية للحاوية ولا يمكن عادةً تجاوزها. يوفر CMD حجج افتراضية إلى ENTRYPOINT، أو هو الأمر إذا لم يتم تعيين ENTRYPOINT. استخدم نموذج exec لكليهما.
كيف أكتب Dockerfile ينتج صورة صغيرة؟
استخدم صورة أساسية مثل alpine:latest أو scratch. استخدم البناء متعدد المراحل لنسخ القطع الأثرية المترجمة فقط. أزل تبعيات البناء. نظّف ذاكرة مدير الحزم المؤقتة (rm -rf /var/lib/apt/lists/*). تجنب تضمين الملفات غير الضرورية (استخدم .dockerignore).
لماذا يجب أن أشغل كمستخدم بدون جذر؟
التشغيل كـ root في حاوية يعني أن الخرق أو الهروب يمكن أن يعطي مهاجماً وصول جذر إلى المضيف. أنشئ مستخدماً مخصصاً واسقط القدرات لتقليل المخاطر. أضف USER <uid> قبل الأمر النهائي.
كيف تم التحقق من هذا الدليل
كُتب يدويًا من الوثائق الرسمية، وأُعيد فحص كل أمر، ثم رُوجع مرة ثانية قبل النشر. آخر مراجعة في .
المصادر الرسمية التي قُرئت لهذا المقال

