Docker أداة لا غنى عنها في تطوير البرمجيات الحديثة، حيث يمكّن الفرق من بناء التطبيقات ونشرها وتشغيلها بكفاءة وسهولة غير مسبوقتين. ويكمن جوهر هذه التقنية في Dockerfile، وهو عبارة عن نص برمجي بسيط ولكنه قوي، يعمل كخطة أساسية لإنشاء صور Docker الخاصة بك.
إنّ تصميم عملية بناء فعّالة باستخدام Dockerfile ليس مجرد تمرين تقني، بل هو سبيلٌ إلى دورات تطوير أسرع، وبصمة تطبيق أصغر حجمًا وأكثر أمانًا، ونشر أكثر موثوقية. سواء كنتَ مبتدئًا في استخدام Docker أو تسعى إلى صقل مهاراتك، سيرشدك هذا الدليل إلى أساسيات كتابة ملفات Dockerfile عملية وفعّالة وآمنة.
فهم بيئة دوكر: مراجعة سريعة

قبل الخوض في تفاصيل ملفات Dockerfile، دعونا نتطرق بإيجاز إلى مفاهيم Docker الرئيسية:
- الصور: الصورة عبارة عن حزمة تنفيذية خفيفة الوزن ومستقلة تتضمن كل ما يلزم لتشغيل البرامج، بما في ذلك الكود، وبيئة التشغيل، والمكتبات، ومتغيرات البيئة، وملفات التكوين. الصور عبارة عن قوالب غير قابلة للتغيير.
- الحاويات: الحاوية هي نسخة قابلة للتشغيل من صورة. يمكنك إنشاء الحاويات، وبدء تشغيلها، وإيقافها، ونقلها، أو حذفها. وهي توفر بيئات معزولة لتطبيقاتك.
- ملف Dockerfile: هذا هو محور تركيزنا. ملف Dockerfile هو مستند نصي يحتوي على سلسلة من الأوامر التي يستخدمها Docker لتجميع صورة تلقائيًا.
- Docker Hub/Registries: هذه مستودعات لتخزين ومشاركة صور Docker، على غرار GitHub للتعليمات البرمجية.
يهدف ملف Dockerfile المكتوب بشكل جيد إلى إنتاج صورة تكون خفيفة وسريعة البناء وآمنة قدر الإمكان.
شرح علامات بناء Docker
- -t myapp:1.0 : يُضيف هذا الخيار وسمًا لصورة التطبيق باسم (myapp) ورقم إصدار (1.0). يُسهّل الوسم عملية التحكم في الإصدارات، ويُمكّن من الرجوع إلى إصدارات مُحددة من الصورة لاحقًا، خاصةً عند النشر أو رفعها إلى سجل التطبيقات.
- الرمز (.) إلى سياق البناء، وهو المجلد الذي يبحث فيه Docker عن ملف Dockerfile وأي ملفات أخرى مطلوبة أثناء عملية البناء (مثل الملفات المراد نسخها إلى الصورة).
يقوم Docker بضغط محتويات هذا المجلد وإرسالها إلى خادم Docker. من المهم ملاحظة أنه لا يمكن الوصول إلا إلى الملفات الموجودة داخل سياق البناء أثناء عملية البناء.
تعليمات أساسية لملف Dockerfile: المكونات الأساسية

دعونا نستكشف التعليمات الأكثر شيوعًا وكيفية استخدامها بفعالية.
- من: يجب أن يبدأ كل ملف Dockerfile بتعليمات FROM. وهي تحدد الصورة الأساسية التي سيتم بناء صورتك عليها.
- الغرض: تحديد نقطة بداية، وغالبًا ما تكون نظام تشغيل (مثل Ubuntu:22.04) أو وقت تشغيل تطبيق مُعد مسبقًا (مثل node:18-alpine).
- مثال : FROM python:3.9-slim
- أفضل الممارسات: اختر صورة النظام الأساسية المصغرة التي تلبي احتياجات تطبيقك. إصدارات Alpine صغيرة الحجم، لكنها تستخدم مكتبة musl libc، مما قد يُسبب مشاكل توافق مع بعض الحزم المعتمدة على لغة C. أما الإصدارات المُصغّرة فهي حل وسط جيد، إذ تُقدّم نسخة مُبسّطة من توزيعة قياسية (مثل Debian) مع مكتبة glibc.
- دليل العمل: يحدد هذا الإعداد wدليل العمل لأي تعليمات لاحقة من نوع RUN وCMD وENTRYPOINT وCOPY وADD.
- الغرض: تحديد سياق الدليل الحالي داخل الصورة لعمليات الملفات اللاحقة وتنفيذ الأوامر. إذا لم يكن الدليل موجودًا، يقوم Docker بإنشائه.
- مثال: WORKDIR /usr/src/app
- أفضل الممارسات: استخدم المسارات المطلقة لـ WORKDIR. تغيير الدلائل باستخدام WORKDIR عدة مرات يكون أنظف بشكل عام من ربط أوامر cd داخل تعليمات RUN.
- ينسخ: يقوم بنسخ الملفات أو المجلدات من سياق البناء الخاص بك إلى نظام ملفات الصورة.
- الغرض: إضافة رمز التطبيق وملفات التكوين والأصول الأخرى الضرورية إلى الصورة.
- مثال:
Dockerfile
WORKDIR /usr/src/app
COPY package.json ./
COPY src/ ./src/
- أفضل الممارسات: لنسخ الملفات البسيطة، يُفضّل استخدام الأمر COPY بدلاً من ADD. فالأمر COPY أكثر شفافية. أما الأمر ADD فيحتوي على ميزات إضافية مثل تنزيل الملفات من عناوين URL واستخراج الملفات المضغوطة بصيغة tar، والتي قد تكون أقل قابلية للتنبؤ. ولضمان الوضوح والأمان، يُفضّل استخدام الأمر RUN مع أوامر curl وwget وtar عند الحاجة إلى التنزيل والاستخراج.
- يجري: ينفذ الأوامر في طبقة جديدة فوق الصورة الحالية ويحفظ النتائج. يُستخدم هذا لتثبيت البرامج، وإنشاء المجلدات، وتجميع التعليمات البرمجية، وما إلى ذلك.
- الغرض: تعديل نظام ملفات الصورة عن طريق تثبيت الحزم أو تشغيل البرامج النصية للبناء أو إعداد التكوينات.
- مثال:
Dockerfile
RUN apt-get update && apt-get install -y –no-install-recommends \
nginx \
curl \
&& rm -rf /var/lib/apt/lists/*
- أفضل الممارسات: استخدم تسلسل الأوامر ذات الصلة باستخدام &&، وقم بتنظيف الملفات المؤقتة أو ذاكرة التخزين المؤقت لمدير الحزم (مثل rm -rf /var/lib/apt/lists/* لنظامي Debian/Ubuntu أو yum clean all لنظامي CentOS/RHEL) في نفس أمر RUN. هذا يقلل من عدد الطبقات ويخفض حجم الصورة، حيث أن كل أمر RUN يُنشئ طبقة جديدة.
- البيئة: يقوم بتعيين متغيرات البيئة المتاحة أثناء عملية البناء (بعد تعريفها) وعند تشغيل الحاويات من الصورة.
- الغرض: توفير قيم التكوين أو المسارات أو الإعدادات التي يحتاجها تطبيقك أو نصوص البناء الخاصة بك.
- مثال:
Dockerfile
ENV NODE_ENV=production
ENV APP_PORT=3000
- أفضل الممارسات: استخدم متغير البيئة (ENV) لبيانات التكوين غير الحساسة. يُنصح باستخدام أساليب الحقن أثناء التشغيل بدلاً من تضمينها في الصورة مع متغير البيئة (ENV) للبيانات السرية.
- الأرجنتين: يُعرّف متغيرًا خاصًا بوقت الإنشاء يمكن للمستخدمين تمريره باستخدام علامة build-arg أثناء عملية إنشاء Docker.
- الغرض: السماح بتحديد معلمات عملية البناء دون تعديل ملف Dockerfile.
- مثال: Dockerfile
Dockerfile
ARG APP_VERSION=1.0.0
ENV APP_VERSION_ENV=${APP_VERSION}
RUN echo “Building version ${APP_VERSION_ENV}”
- تم بناؤه باستخدام: سحق docker build– build-arg APP_VERSION=1.2.3 -t myapp.
- ملاحظة: متغيرات ARG غير متاحة في الحاوية قيد التشغيل ما لم يتم تعيينها صراحة كمتغير ENV، كما هو موضح أعلاه.
- يفضح: يُعلم Docker بأن الحاوية تستمع على منافذ الشبكة المحددة أثناء التشغيل.
- الغرض: تُستخدم هذه الوثيقة بشكل أساسي كدليل لمنشئ الصور ومستخدمها. وهي لا تنشر المنفذ.
مثال:
Dockerfile
EXPOSE 8080
- ملاحظة: لجعل المنفذ قابلاً للوصول إليه من المضيف، يمكنك استخدام العلامة -p أو -P مع docker run (على سبيل المثال، docker run -p 8080:8080 myimage).
- CMD و نقطة الدخول: حدد الأمر الذي يتم تنفيذه عند بدء تشغيل الحاوية.
- CMD ["executable", "param1", "param2"] : يوفر الإعدادات الافتراضية للحاوية قيد التشغيل. يمكن تجاوز هذه الإعدادات بسهولة بإضافة أمر إلى أمر docker run. في حال وجود عدة أوامر CMD، يُطبّق الأمر الأخير فقط.
- ENTRYPOINT ["executable", "param1", "param2"] : يُستخدم لتهيئة حاوية لتشغيلها كملف تنفيذي. تُضاف الوسائط المُمررة إلى أمر docker run إلى أمر ENTRYPOINT.
- مثال (نمط نموذجي):
Dockerfile
ENTRYPOINT ["python", "app.py"] # الأمر الرئيسي
CMD ["–help"] # الوسيط الافتراضي في حال عدم توفير أي وسيط عند تشغيل docker run
- أفضل الممارسات: استخدم CMD إذا كنت ترغب في أمر افتراضي قابل للتعديل بسهولة. استخدم ENTRYPOINT لإنشاء صورة تعمل كملف تنفيذي محدد، وغالبًا ما تستخدم CMD لتوفير الوسائط الافتراضية. بالنسبة لتطبيقات الويب، يُعد CMD ["npm", "start"] أو CMD ["python", "manage.py", "runserver"] معيارًا.
أفضل الممارسات الأساسية لتحسين ملفات Dockerfile

إن كتابة ملف Dockerfile فعال ليست سوى البداية. أما تحسينه فيحقق فوائد كبيرة.
- استغل ذاكرة التخزين المؤقت للبناء بفعالية: يقوم Docker ببناء الصور على شكل طبقات، ويحاول إعادة استخدام الطبقات من عمليات البناء السابقة إن أمكن (التخزين المؤقت). لزيادة عدد مرات الوصول إلى ذاكرة التخزين المؤقت:
- رتب التعليمات من الأقل تغييراً إلى الأكثر تغييراً. على سبيل المثال، قم بتثبيت التبعيات (التي تتغير بشكل أقل) قبل نسخ شفرة المصدر لتطبيقك (التي تتغير بشكل متكرر).
Dockerfile
# مثال جيد للتخزين المؤقت لتطبيق Node.js
FROM node:18-alpine
WORKDIR /app
COPY package.json package-lock.json ./ # تتغير التبعيات بشكل أقل
RUN npm ci –omit=dev # يتم تخزين هذه الطبقة مؤقتًا إذا لم تتغير ملفات الحزمة
COPY . . # يتغير كود المصدر بشكل متكرر، لذا فهو الأخير
CMD [“node”, “server.js”]
- حافظ على صغر حجم صورك: الصور الأصغر حجماً أسرع في السحب والدفع والنشر، ولها سطح هجوم أقل.
- استخدم صورًا أساسية مصغرة: تُعد إصدارات Alpine أو slim أو distroless أصغر بكثير من صور نظام التشغيل الكاملة.
- التنظيف في نفس طبقة التشغيل: قم بإزالة الملفات المؤقتة أو الملفات غير الضرورية باستخدام نفس أمر التشغيل (RUN) بعد تثبيت الحزم. على سبيل المثال:
- ديبيان/أوبونتو: apt-get clean && rm -rf /var/lib/apt/lists/*
- CentOS/RHEL: yum clean all أو dnf clean all
- جبال الألب: rm -rf /var/cache/apk/*
- تبني عمليات البناء متعددة المراحل: هذه إحدى أكثر الطرق فعالية لتقليل حجم الصورة، خاصة بالنسبة للغات المترجمة أو التطبيقات ذات خطوات البناء (مثل واجهات المستخدم الأمامية JavaScript).
- المفهوم: استخدم مرحلة واحدة (كتلة FROM) تحتوي على جميع أدوات البناء ومتطلبات التطوير لتجميع/بناء تطبيقك. ثم، ابدأ جديدة من صورة أساسية لوقت التشغيل باستخدام COPY-from=
... لنسخ العناصر المجمعة الضرورية فقط - مثال (تطبيق Go مبسط): Dockerfile
- المفهوم: استخدم مرحلة واحدة (كتلة FROM) تحتوي على جميع أدوات البناء ومتطلبات التطوير لتجميع/بناء تطبيقك. ثم، ابدأ جديدة من صورة أساسية لوقت التشغيل باستخدام COPY-from=
Dockerfile
# المرحلة 1: البناء
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp
# المرحلة 2: وقت التشغيل
FROM debian:bullseye-slim
WORKDIR /app
COPY –from=builder /app/myapp .
CMD [“./myapp”]
- تحتوي مرحلة البناء على Go SDK، لكن الصورة النهائية لا تحتوي إلا على الملف الثنائي المُجمَّع ونظام التشغيل Alpine OS الأدنى.
- إعطاء الأولوية للأمن:
- التشغيل كمستخدم غير جذري: تعمل الحاويات افتراضيًا بصلاحيات المستخدم الجذر. وهذا يُشكل خطرًا أمنيًا. أنشئ مستخدمًا ومجموعةً مخصصين غير مميزين في ملف Dockerfile الخاص بك، واستخدم أمر USER للتبديل إليهما. Dockerfile
Dockerfile
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# … نسخ الملفات وتغيير ملكيتها إلى appuser:appgroup …
USER appuser
- قم بتثبيت الحزم الضرورية فقط: كل حزمة تُشكل ثغرة أمنية محتملة. تجنب تثبيت أدوات تصحيح الأخطاء أو أدوات التطوير في صور الإنتاج (استخدم عمليات بناء متعددة المراحل لهذا الغرض).
- لا تُضمّن الأسرار بشكل مباشر في الكود: تجنّب وضع كلمات المرور أو مفاتيح واجهة برمجة التطبيقات أو أي أسرار أخرى في ملف Dockerfile (مثلًا، في متغيرات البيئة). استخدم طرق حقن البيانات أثناء التشغيل، مثل أسرار Docker أو أسرار Kubernetes أو متغيرات البيئة المُقدّمة بشكل آمن أثناء التشغيل.
- استخدم ملف .dockerignore بفعالية: أنشئ ملف .dockerignore في جذر سياق البناء (على نفس مستوى ملف Dockerfile). حدد الملفات والمجلدات التي تريد استبعادها من الإرسال إلى خادم Docker (مثل: .git، وnode_modules إذا كانت مثبتة في الصورة، وإعدادات بيئة التطوير المتكاملة المحلية، وملفات *.log).
- الفوائد: تسريع عملية بناء Docker عن طريق تقليل حجم سياق البناء ومنع تضمين الملفات الحساسة أو غير الضرورية في صورتك.
ما وراء الأساسيات: تحسينات إضافية

بمجرد أن تشعر بالراحة تجاه ما سبق، ضع في اعتبارك هذه النقاط للحصول على ملفات Dockerfile أفضل:
- BuildKit: محرك بناء Docker الأحدث، والذي غالبًا ما يكون مُفعّلاً افتراضيًا. يوفر أداءً أفضل (بناء متوازي)، وتخزينًا مؤقتًا مُحسّنًا، وميزات متقدمة مثل أسرار البناء (RUN– mount=type=secret,…) ووحدات التخزين المؤقت (RUN– mount=type=cache,…) لمديري الحزم. تأكد من تفعيله أو قم بتمكينه باستخدام DOCKER_BUILDKIT=1.
- فحص ملفات Dockerfile: استخدم أدوات مثل Hadolint (hadolint Dockerfile) لتحليل ملف Dockerfile الخاص بك بشكل ثابت بحثًا عن الأخطاء، ومخالفات الأسلوب، والالتزام بأفضل الممارسات قبل البناء.
نصائح سريعة لحل المشكلات الشائعة
- "لم يتم العثور على الملف" أثناء النسخ أو الإضافة : تحقق جيدًا من مسار المصدر (فهو نسبي إلى جذر سياق البناء) وتأكد من أن الملف غير مستبعد بواسطة .dockerignore.
- عمليات البناء البطيئة: راجع ترتيب التعليمات لتحسين استخدام الذاكرة المؤقتة. ادمج أوامر التشغيل حيثما أمكن. تأكد من أن ملف .dockerignore الخاص بك شامل.
- الصور الكبيرة: استخدم عمليات بناء متعددة المراحل! نظّف الطبقات في وضع التشغيل. اختر صورًا أساسية قليلة.
ملفات Docker في سير عمل DevOps الخاص بك
يُعد ملف Dockerfile جزءًا أساسيًا من "البنية التحتية كبرنامج"
- التحكم في الإصدار: قم دائمًا بحفظ ملف Dockerfile الخاص بك في مستودع Git الخاص بك جنبًا إلى جنب مع كود التطبيق الخاص بك.
- التكامل مع أنظمة التكامل المستمر والتسليم المستمر: يمكنك أتمتة عملية بناء Docker ودفع الصور ضمن مسارات التكامل المستمر والتسليم المستمر (مثل GitHub Actions وJenkins وGitLab CI). يضمن ذلك عمليات بناء ونشر متسقة وقابلة للتكرار.
الخلاصة: بناء أساس للنجاح
يُعدّ إنشاء ملفات Dockerfile فعّالة استثمارًا يُحقق فوائد كبيرة في سرعة التطوير، وموثوقية التشغيل، وأمان التطبيقات. من خلال إتقان التعليمات الأساسية، وتطبيق أفضل الممارسات مثل عمليات البناء متعددة المراحل والإدارة الدقيقة لطبقات الصورة، وإعطاء الأولوية للأمان، يُمكنك إنتاج صور Docker مُختصرة وفعّالة وقوية.
يُقدّم هذا الدليل أساسًا متينًا. ومع استمرارك في رحلتك مع Docker، واصل الاستكشاف والتجربة وتحسين ملفات Dockerfile الخاصة بك.
هل أنت مستعد للارتقاء بممارساتك في مجال Docker و DevOps؟
في سي هوك ميديا ، نتخصص في مساعدة الشركات على الاستفادة القصوى من تقنيات الحاويات، والحوسبة السحابية، وخطوط أنابيب التكامل المستمر/التسليم المستمر (CI/CD) المُحسّنة. فريقنا من الخبراء جاهز لتقديم المساعدة إذا كنت ترغب في تحسين عمليات نشر تطبيقاتك، أو تعزيز أمانها، أو تسريع دورة تطويرها.