استخدام الأمر docker exec في حاويات Docker


استخدام الأمر docker exec في حاويات Docker July 14, 2024 at 06:03PM

تعد دوكر 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.

اقرأ أيضًا

#3qpa7meed #ArabProgrammers #المبرمجون_العرب #arab_programmers #عقبة_البرق

تعليقات