أمر Docker Exec: كيفية تشغيل الأوامر داخل صور وحاويات Docker
مقدمة إلى التفاعل مع بيئات Docker
في عالم تطوير البرمجيات وإدارة العمليات (DevOps)، غالبًا ما نجد أنفسنا نبني أنظمة معقدة ومتقدمة، ولكننا نحتاج في النهاية إلى التعامل معها وكأنها بيئة سطر أوامر عادية (shell). لا يختلف الأمر مع Docker، حيث يمكنك تشغيل “كمبيوتر” داخل كمبيوتر آخر، سواء كان ذلك الكمبيوتر عبارة عن خادم سحابي (مثل EC2 instance) أو جهازك المحمول. يتيح لنا Docker تجميع التطبيقات وتوزيعها بكفاءة، وأحيانًا نستخدمه لمشاريع حوسبة موزعة أكثر تعقيدًا، أو ببساطة لتجنب تثبيت أدوات سطر الأوامر (CLIs) التي قد تتعارض مع بعضها البعض على جهازنا.
إن القدرة على التفاعل مباشرة مع بيئة Docker، سواء كانت صورة (image) أو حاوية (container) قيد التشغيل، هي مهارة أساسية لكل مطور ومهندس DevOps. في هذا المقال، سنتعمق في كيفية استخدام أوامر Docker لتشغيل الأوامر داخل هذه البيئات، مع التركيز على أمر docker exec وكيف يمكن لأمر docker run أن يوفر تجربة صدفة تفاعلية لأغراض تصحيح الأخطاء.
الحصول على صدفة تفاعلية داخل صورة Docker باستخدام docker run
للبدء في التفاعل مع بيئة Docker، فإن إحدى الطرق الشائعة للحصول على صدفة (shell) تفاعلية داخل حاوية جديدة مبنية من صورة معينة هي استخدام أمر docker run مع الخيارات المناسبة. هذا مفيد بشكل خاص لاستكشاف محتويات الصورة أو تصحيح الأخطاء قبل تشغيلها كخدمة مستمرة.
يمكنك إخبار Docker بتشغيل أمر bash (أو أي صدفة أخرى مثل sh) داخل حاوية جديدة، مما يضعك مباشرة في بيئة سطر الأوامر الخاصة بها:
docker run -it اسم-الصورة bash
# مثال: تشغيل صدفة باش داخل صورة miniconda3
docker run -it continuumio/miniconda3:latest bash
# مثال: تشغيل صدفة باش داخل صورة Node.js
docker run -it node:latest bash
الخيار -it هو اختصار لـ --interactive و --tty، وهما ضروريان للحصول على تجربة تفاعلية تتيح لك إدخال الأوامر ورؤية مخرجاتها.
تجربة الأمر والتحقق من البيئة
لنتأكد من أنك بالفعل داخل صدفة Docker، يمكنك تجربة بعض الأوامر البسيطة. ابحث عن صورة Docker للغة البرمجة المفضلة لديك (على سبيل المثال، Python و conda). ثم قم بتشغيل بعض الأوامر للتأكد من أنك داخل تلك الصدفة:
# من نظام التشغيل المضيف (Host)
echo $(pwd)
# ادخل إلى صدفة Docker
docker run -it continuumio/miniconda3:latest bash
# الآن أنت داخل صدفة Docker!
echo $(pwd)
echo $USER
ستلاحظ أن مسار العمل الحالي (pwd) واسم المستخدم (USER) قد يختلفان داخل حاوية Docker مقارنة بنظام التشغيل المضيف. هذه الطريقة مثالية لتصحيح أخطاء حاوية يفترض أن تعمل بشكل صحيح، وهي رائعة أيضًا لحالات الاستخدام التي لا ترغب فيها بتثبيت برامج معينة على جهازك المضيف.
تصحيح أخطاء بناء Docker باستخدام docker run
يعد التعامل مع صورة Docker كصدفة عادية مفيدًا للغاية عند محاولة تصحيح أخطاء عمليات بناء Docker. لنفترض أن لديك ملف Dockerfile لصورة تحاول بناءها. عادةً، عند تشغيل docker build -t صورتي-الخاصة . (حيث -t لتعيين وسم/tag)، يقوم Docker بتنفيذ كل خطوة RUN ويتوقف عند الوصول إلى أمر لا يخرج بشكل صحيح.
في صدفة UNIX، يعني رمز الخروج 0 أن كل شيء على ما يرام مع الأمر. لتوضيح هذه النقطة، قمنا بإنشاء ملف Dockerfile يحتوي على أمر RUN يخرج برمز 1 (مما يشير إلى خطأ).
FROM continuumio/miniconda3:latest
RUN apt-get update -y; \
apt-get upgrade -y; \
apt-get install -y \
vim-tiny vim-athena build-essential
RUN conda update conda \
&& conda clean --all --yes
RUN exit 1
عند محاولة بناء هذه الصورة:
docker build -t صورتي-الخاصة .
ستحصل على مخرجات مشابهة لما يلي، تشير إلى الفشل:
(base) ➜ my-image docker build -t my-image .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM continuumio/miniconda3:latest
---> 406f2b43ea59
Step 2/4 : RUN apt-get update -y; apt-get upgrade -y; apt-get install -y vim-tiny vim-athena build-essential
---> Using cache
---> 726af29a48a0
Step 3/4 : RUN conda update conda && conda clean --all --yes
---> Using cache
---> 19478bb3ce67
Step 4/4 : RUN exit 1
---> Running in 7c98aab6b52c
The command '/bin/sh -c exit 1' returned a non-zero code: 1
يمكنك التأكد من أن صورة Docker لم يتم بناؤها بنجاح عن طريق تشغيل docker images والبحث عن صورتي-الخاصة. لن تجدها هناك لأن عملية البناء فشلت.
تحديد موقع الخطأ وتصحيحه
لتحديد المشكلة، يمكننا الآن التعليق على أمر RUN المسبب للمشكلة في ملف Dockerfile:
FROM continuumio/miniconda3:latest
RUN apt-get update -y; \
apt-get upgrade -y; \
apt-get install -y \
vim-tiny vim-athena build-essential
RUN conda update conda \
&& conda clean --all --yes
#RUN exit 1
ثم عند إعادة البناء، سترى:
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM continuumio/miniconda3:latest
---> 406f2b43ea59
Step 2/3 : RUN apt-get update -y; apt-get upgrade -y; apt-get install -y vim-tiny vim-athena build-essential
---> Using cache
---> 726af29a48a0
Step 3/3 : RUN conda update conda && conda clean --all --yes
---> Using cache
---> 19478bb3ce67
Successfully built 19478bb3ce67
Successfully tagged my-image:latest
الآن تم بناء الصورة بنجاح! يمكنك الآن الدخول إلى صورة Docker هذه وبدء تشغيل الأوامر بشكل تفاعلي لتصحيح الأخطاء خطوة بخطوة:
docker run -it صورتي-الخاصة bash
# يمكنك أيضًا تشغيل:
# docker run -it صورتي-الخاصة:latest bash
من هنا، يمكنك البدء في تصحيح أخطاء أوامر RUN الخاصة بك واحدًا تلو الآخر لمعرفة ما حدث بشكل خاطئ. إذا لم تكن متأكدًا مما إذا كان الأمر قد خرج بشكل صحيح أم لا، فقم بتشغيل echo $?:
# أولاً، قم بتشغيل docker run -it صورتي-الخاصة bash للدخول إلى الصدفة
# طباعة السلسلة "hello"
echo "hello"
# hello
echo $?
# 0
# تشغيل أمر غير موجود
hello $(hello)
# bash: hello: command not found
echo $?
# 127
يمكنك الاستمرار في تكرار هذه الخطوات: التعليق على جزء من Dockerfile، الدخول إلى الصدفة، وتحديد الأوامر التي تسبب المشاكل، حتى يتم بناء صورة Docker الخاصة بك بشكل مثالي.
متى تستخدم docker exec؟
بينما يوفر docker run -it <image> bash صدفة تفاعلية عند بدء حاوية جديدة من صورة، فإن أمر docker exec مصمم لتشغيل الأوامر داخل حاوية Docker قيد التشغيل بالفعل. هذا هو الفرق الرئيسي بينهما.
docker run: يستخدم لبدء حاوية جديدة من صورة وتشغيل أمر بداخلها (مثلbashللحصول على صدفة). إذا لم تكن الحاوية موجودة، فسيتم إنشاؤها.docker exec: يستخدم لتنفيذ أمر داخل حاوية موجودة وقيد التشغيل. إنه مفيد جدًا لإدارة الحاويات النشطة، مثل فحص السجلات، أو تعديل الملفات، أو بدء خدمات إضافية مؤقتًا دون الحاجة إلى إعادة تشغيل الحاوية.
على سبيل المثال، إذا كانت لديك حاوية تسمى my-running-app تعمل في الخلفية، يمكنك الدخول إليها بشكل تفاعلي باستخدام:
docker exec -it my-running-app bash
أو يمكنك تشغيل أمر غير تفاعلي:
docker exec my-running-app ls -l /app
يعد فهم متى تستخدم كل أمر أمرًا بالغ الأهمية لإدارة بيئات Docker بكفاءة.
الخلاصة التقنية
لقد استعرضنا كيف أن التفاعل مع بيئات Docker، سواء عبر أمر docker run للحصول على صدفة تفاعلية داخل صور جديدة أو docker exec لتشغيل الأوامر في حاويات قيد التشغيل، لا يختلف كثيرًا عن استخدام سطر الأوامر على جهازك الخاص. إن استخدام صور Docker هو طريقة رائعة لتوزيع التطبيقات وتوفير بيئات تطوير متسقة. من خلال إتقان هذه الأوامر، يمكنك تبسيط عملية تصحيح الأخطاء، وتجنب مشكلات التثبيت، وبناء أنظمة أكثر قوة ومرونة. بدلاً من إنشاء سكربتات تثبيت معقدة، فكر في تجميع تطبيق سطر الأوامر المفضل لديك أو مشروع GitHub التالي باستخدام Docker لتبسيط عملية النشر والاستخدام.