تعد دوكر Docker واحدة من الأدوات المشهورة والمستخدمة على نطاق واسع لتغليف التطبيقات ضمن حاويات containerization، وهي تساعد المطورين على إنشاء وإدارة حاويات لينكس المحمولة والمتسقة فيما بينها إذ توفر دوكر بيئة معزولة لتشغيل التطبيقات مما يسهل نقلها وتشغيلها عبر مختلف البيئات دون مشاكل التوافق.
ويحتاج المطورون عند تطوير الحاويات ونشرها إلى أوامر برمجية تعينهم على مراقبة حالتها في أثناء التشغيل أو حل مشكلاتها، وهذا ما يوفره الأمر docker exec
الذي يسمح لك بتشغيل البرامج في حاويات Docker مشغلة مسبقًا.
سنوضح في مقال اليوم ما هو الأمر docker exec
؟ وما هي خياراته؟ وكيف تستخدمه لتنفيذ الأوامر في الحاويات قيد التشغيل وطريقة الحصول على واجهة صدفة shell تفاعلية في داخل الحاوية، كما سنعرفك على أبرز الأخطاء التي قد تظهر لك عند تنفيذ هذا الأمر وكيفية التعامل معها وحلها.
متطلبات العمل
يتطلب تطبيق خطوات المقال وجود Docker مُثبتًا على حاسوبك أو خادمك الذي ستعمل منه، ومستخدمًا يمتلك صلاحيات تشغيل الأمر docker
، وإذا احتجت لتشغيل docker
بصلاحية الجذر root احرص على إضافة sudo
قبل كتابتك الأوامر الواردة هنا.
يمكنك الاطلاع على مقال كيفية تثبيت دوكر واستخدامه على دبيان لمعرفة خطوات تثبيت Docker، وستجد فيه فقرةً خاصة عن كيفية استخدام Docker دون كتابة sudo
في بداية كل أمر في حال فضلت عدم كتابتها.
تشغيل حاوية تجريبية
يُستخدم الأمر docker exec
كما ذكرنا سابقًا مع الحاويات قيد التشغيل، لذا إن لم يكن لديك حاوية تعمل أنشئ واحدة تجريبية وشغّلها باستخدام الأمر docker run
وفق التالي:
$ docker run -d --name container-name alpine watch "date >> /var/log/date.log"
يُنشئ هذا الأمر حاويةً جديدة بالاعتماد صورة image لتوزيعة Alpine الرسمية الموجود في مستودعات دوكر. إذ إن Alpine Linux من أشهر توزيعات لينكس المستخدمة مع الحاويات بسبب خفتها في استخدام الموارد وصغر حجمها.
تشير الراية d-
إلى فصل الحاوية عن نافذة الطرفية، فتعمل الحاوية في الخلفية، أما name container-name--
فيُحدد اسم الحاوية، سُميّت الحاوية هنا container-name
، اكتب الاسم الذي تريده أو يمكنك عدم كتابة أي اسم وترك دوكر Docker يعطي الحاوية اسمًا عشوائيًا فريدًا.
ويأتي بعد اسم الحاوية اسم الصورة التي ستُنشئ الحاوية انطلاقًا منها، واسمها في حالتنا alpine
.
وبعدها اكتب الأمر الذي تريد تشغيله داخل الحاوية، وهو في مثالنا "watch "date >> /var/log/date.log
. افتراضيًا يكرر الأمر watch
تشغيل الأمر المكتوب بعده أي "date >> /var/log/date.log"
كل ثانيتين، ويعرض الأمر date
التاريخ والوقت الحاليين على الخادم، كما يلي:
Fri Jan 26 14:57:05 UTC 2024
أما الجزء /var/log/date.log/ <<
فيعني أن نتيجة تنفيذ الأمر date
ستُخزن في ملف نصي يدعى /var/log/date.log/
، وبالتالي سيُكتب سطرٌ جديد كل ثانيتين في هذا الملف، وبعد عدة ثواني سيبدو محتواه على الشكل التالي:
Fri Jan 26 15:00:26 UTC 2024 Fri Jan 26 15:00:28 UTC 2024 Fri Jan 26 15:00:30 UTC 2024 Fri Jan 26 15:00:32 UTC 2024 Fri Jan 26 15:00:34 UTC 2024
سنعرض في الفقرة التالية طريقة اكتشاف أسماء الحاويات المشغلة على خادم معين، لتستفيد منها في الحالات التي تستهدف فيها العمل على حاوية لا تعرف اسمها بدقة.
اكتشاف اسم حاوية Docker
بما أن الأمر docker exec
يعمل مع الحاويات قيد التشغيل، لذا من المهم معرفة اسم الحاوية أو المعرّف الخاص بها Container ID لتمريره له، ويمكنك معرفة أسماء الحاويات ومعلوماتٍ أخرى عنها بواسطة الأمر docker ps
كما يلي:
$ docker ps
يعرض لك هذا الأمر أسماء الحاويات التي تعمل على الخادم، مع معلوماتٍ عامة عنها، مثل: صورة الحاوية، والأمر الذي تنفذه الآن، وحالة تشغيلها وغيرها، ألقِ نظرة على خرج الأمر docker ps
:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 76aded7112d4 alpine "watch 'date >> /var…" 11 seconds ago Up 10 seconds container-name
ستلاحظ في الخرج السابق وجود اسم الحاوية والمُعرّف الخاص بها، وهما ينوبان عن بعضهما، فيمكنك تمرير أي واحد منهما للأمر docker exec
للتعامل مع الحاوية.
وإذا رغبت بتغيير اسم الحاوية مثلًا، فاستخدم الأمر docker rename
، وفق التالي:
$ docker rename container-name new-name
الآن بعد أن تعلمنا كيف نحصل على اسم الحاوية، سنعرض بعضًا من الأمثلة العملية على طريقة استخدام docker exec
لتنفيذ الأوامر في حاوية قيد التشغيل.
تشغيل صدفة Sell تفاعلية في حاوية Docker
تحتاج في كثير من الحالات لتشغيل صدفة Shell تفاعلية داخل حاوية Docker لاستعراض نظام ملفاتها مثلًا أو لتقصي أخطاء بعض العمليات ضمنها وتصحيحها في أثناء التنفيذ أو لغير ذلك من الأسباب، يوفر لك docker exec
هذه الإمكانية عبر استخدامه مع الرايتين i-
و t-
.
تُبقي الراية i-
إمكانية إدخال البيانات إلى الحاوية متاحة، بينما تُنشئ الراية t-
طرفيةً وهمية pseudo-terminal ترتبط بالصدفة shell، ويمكنك استخدام الرايتين معًا في أمرٍ واحد وفق التالي:
$ docker exec -it container-name sh
ينتج عن الأمر السابق تشغيل الصدفة Shell أو sh
في الحاوية المحددة، وفتح مِحث أوامر Shell prompt اعتيادي لاستخدامه. وتستطيع الخروج من الحاوية بكتابة exit
ثم الضغط على ENTER
.
/ # exit
إذا احتوت صورة الحاوية التي تستخدمها صدفةً Shell متقدمة مثل باش Bash، فيمكنك العمل معها باستبدال الرمز sh
في الأمر السابق بالرمز bash
.
تشغيل أوامر غير تفاعلية في حاوية Docker
يمكنك استخدام docker exec
بلا رايات Flags، لتنفيذ الأوامر التي لا تتطلب تفاعلًا مع حاويات Docker قيد التشغيل، ألقِ نظرة على المثال التالي:
$ docker exec container-name tail /var/log/date.log
يُشغّل السطر السابق الأمر tail /var/log/date.log
في الحاوية المسماة container-name
ثم يعرض لك النتائج، إذ يُظهِر الأمر tail
آخر عشر أسطر من ملف الخرج على الشاشة، والذي يبدو مثل التالي:
Mon Jan 29 14:39:33 UTC 2024 Mon Jan 29 14:39:35 UTC 2024 Mon Jan 29 14:39:37 UTC 2024 Mon Jan 29 14:39:39 UTC 2024 Mon Jan 29 14:39:41 UTC 2024 Mon Jan 29 14:39:43 UTC 2024 Mon Jan 29 14:39:45 UTC 2024 Mon Jan 29 14:39:47 UTC 2024 Mon Jan 29 14:39:49 UTC 2024 Mon Jan 29 14:39:51 UTC 2024
لاحظ أن ما نفذناه هنا يشبه فتح صدفة Shell تفاعلية (كما في المثال السابق docker exec -it container-name sh
) ثم استدعاء الأمر tail /var/log/date.log
لعرض النتائج، فقد حصلنا في الحالتين على الخرج نفسه، ولكننا في الحالة الأولى (أي التفاعلية) فتحنا الصدفة Shell، ثم نفذنا الأمر، وبعدها أغلقنا الصدفة، أما هنا فتمت العملية بأمرٍ واحد فقط وبدون الحاجة لفتح طرفية وهمية.
تنفيذ الأوامر في مجلد بديل ضمن الحاوية Docker
يمكنك تحديد مجلد العمل أو المجلد الذي تود تنفيذ الأوامر فيه ضمن الحاوية بكتابة مساره بعد الراية workdir--
كما في المثال التالي:
$ docker exec --workdir /tmp container-name pwd
حددنا هنا المجلد tmp/
على أنه مجلد العمل، وسيُنفذ ضمنه الأمر pwd
، ووظيفة pwd
عرض اسم مجلد العمل الحالي، وستحصل بذلك على الخرج التالي:
/tmp
الذي يؤكد أن tmp/
هو مجلد العمل الحالي الذي نُفِّذ فيه الأمر لأنه ظهر في خرج pwd
.
تشغيل الأوامر بصفة مستخدم آخر في حاوية Docker
استخدم الراية user--
إذا رغبت بتنفيذ أمرٍ ما ضمن الحاوية بصفتك مستخدمًا آخر أي بصلاحياته والمحددات الخاصة به، كما في المثال التالي:
$ docker exec --user guest container-name whoami
يُنفّذ السطر السابق الأمر whoami
بصفة المستخدم guest، وبما أن الأمر whoami
يستعمل عادةً لمعرفة هوية المستخدم الحالي فستحصل على هذا الخرج:
guest
كما تلاحظ فقد أكدّ خرج الأمر whoami
أن guest هو المستخدم المُنَفِذ.
تمرير المتغيرات إلى داخل حاوية Docker
تساعدك الراية e-
على تمرير قيم متغيرات البيئة environment variables إلى داخل الحاوية لتُستخدم عند تنفيذ الأمر، ألقِ نظرة على المثال التالي:
$ docker exec -e TEST=sammy container-name env
يُسنِد هذا الأمر القيمة sammy
إلى المتغير TEST
ثم يُشغّل الأمر env
في داخل الحاوية، علمًا أن وظيفة الأمر env
هي عرض كافة متغيرات البيئة أمامك على الشاشة، مثل التالي:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=76aded7112d4 TEST=sammy HOME=/root
لاحظ أن المتغير TEST
أصبح يحمل القيمة sammy
بالفعل.
أما إذا احتجت لتمرير عدة متغيرات فاكتبهم بالترتيب واكتب الراية e-
قبل كل متغير منهم، وفق ما يلي:
$ docker exec -e TEST=sammy -e ENVIRONMENT=prod container-name env
تستطيع أيضًا تمرير كافة متغيرات البيئة التي تحتاجها إلى الحاوية ضمن ملفٍ نصي يحتوي على قيمها، وذلك بواسطة الراية env-file--
.
لكن أول ما عليك فعله تجهيز ملف المتغيرات، لذا افتح أي محرر نصوص تفضله مثل نانو nano
أو غيره، وأنشئ بواسطته ملفًا جديدًا كما يلي:
$ nano .env
اعتمدنا env.
اسمًا لملف متغيرات البيئة، لأنه الاسم المتعارف عليه لهذا النوع من الملفات، والذي يعتمده معظم المطورين لتسمية ملفاتهم الخاصة بإدارة معلومات التطبيق الخارجة عن عمليات التحكم بالإصدار.
عرّف الآن متغيرات بيئتك بكتابتها ضمن الملف بهيئة ثنائيات اسم وقيمة KEY=value
، وبمعدل متغير واحد في كل سطر، كما في المثال أدناه:
TEST=sammy ENVIRONMENT=prod
احفظ التغييرات على الملف، وأغلقه، لننتقل للخطوة التالية. إذا كنت تستخدم محرر النصوص نانو nano
، فاضغط على CTRL+O
ثم ENTER
لحفظ التغييرات، وبعدها اضغط على CTRL+X
للخروج.
نَفِّذ الآن الأمر docker exec
بعد كتابة اسم ملف التغيرات بدقة بعد الراية env-file--
كما يلي:
$ docker exec --env-file .env container-name env
وسيظهر أمامك الخرج التالي:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=76aded7112d4 TEST=sammy ENVIRONMENT=prod HOME=/root
لاحظ القيم التي حددناها للمتغيرين إنها مضبوطة تمامًا كما كتبناها ملف المتغيرات.
يمكنك أيضًا تمرير عدة ملفات لمتغيرات البيئة مع تكرار كتابة الراية env-file--
قبل كل واحد منها، وإذا حصل أي تعارض بينها في قيم المتغيرات، فإن الملف اللاحق سيكون ذا أولوية أعلى من الملفات التي تسبقه.
أخطاء شائعة
ستواجه بعض الأخطاء الشائعة عند تعاملك مع الأمر docker exec
، سنذكر أبرزها، انظر مثلًا الخطأ التالي:
Error: No such container: container-name
يعني الخطأ No such container
أن الحاوية التي تطلبها غير موجودة، أو أنك أخطأت في كتابة اسمها، يمكنك استخدام الأمر docker ps
لتحري أسباب الخطأ والتحقق من صحة اسم الحاوية التي تريدها فهو يعرض أسماء جميع الحاويات المُشغلة على الخادم.
وهذا خطأ آخر:
Error response from daemon: Container 2a94aae70ea5dc92a12e30b13d0613dd6ca5919174d73e62e29cb0f79db6e4ab is not running
تعني رسالة not running
أن الحاوية موجودة ولكنها متوقفة عن العمل، يمكنك تشغيلها بالأمر docker start container-name
.
أما الخطأ الأخير الذي نعرضه فهو:
Error response from daemon: Container container-name is paused, unpause the container before exec
يشرح الخطأ نفسه بدقة، فالرسالة Container is paused
تعني أن الحاوية موقفة عن العمل مؤقتًا، يمكنك إزالة الإيقاف المؤقت وإعادة تشغيلها باستخدام الأمر docker unpause container-name
.
الخلاصة
عرضنا في مقال اليوم طريقة تنفيذ الأوامر في حاويات Docker قيد التشغيل، ووضحنا أهم الخيارات المتاحة لتستخدمها حسب احتياجات عملك، ويمكنك معرفة المزيد عن هذه الحاويات والتعامل معها بالإطلاع على مقالات قسم Docker على أكاديمية حسوب.
ترجمة -وبتصرف- للمقال How To Use docker exec to Run Commands in a Docker Container لصاحبه Brian Boucheron.
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.