اذهب إلى المحتوى

مدخل إلى الحاويات


ابراهيم الخضور

تتمتع البرمجيات بدورة حياة كاملة ابتداءً من التصورات الأولية وانتقالًا إلى البرمجة ومنها إلى إصدار البرنامج إلى المستخدم النهائي وصيانته. سنتعرف في هذا المقال على مفهوم الحاويات Containers، وهي أداةٌ عصرية تُستخدم في المراحل النهائية من دورة حياة البرنامج. تُغلّف الحاويات تطبيقك ضمن حزمةٍ واحدة تتضمن كل الاعتماديات التي يحتاجها التطبيق، وتكون النتيجة حاويةً يمكن أن تعمل بصورةٍ مستقل عن غيرها من الحاويات.

تمنع الحاويات التطبيق من الوصول واستخدام ملفات وموارد الأجهزة، وقد يعطي مطورو التطبيقات بعض الأذونات للبرنامج الذي تضمه الحاوية في الوصول إلى ملفات محددة وتخصيص موارد محددة أيضًا. ولنكون أكثر دقة، تُعدّ الحاويات بمثابة بيئات عمل افتراضية على مستوى نظام التشغيل، وأكثر ما يشابهها من الناحية التقنية هي الآلات الافتراضية Virtual machines التي تساعد على تشغيل عدة أنظمة تشغيل على جهاز فيزيائي واحد. وينبغي على الآلات الافتراضية تشغيل النظام بأكمله، بينما تُشغّل الحاوية التطبيق بالاستفادة من نظام التشغيل الذي يستضيفها. وهكذا سيكون الاختلاف بين الحاويات والآلات الافتراضية هي أنك لن تلاحظ إلا نادرًا جدًا زيادة في تحميل النظام عند استخدام الحاويات، فهي عادةً ما تحتاج إلى تنفيذ عملية واحدة.

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

تدعم معظم الخدمات السحابية، مثل AWS و Google Cloud و Microsoft Azure الحاويات وبأشكال متعددة، بما في ذلك AWS Fargate و Google Cloud Run وهما خدمتان لتشغيل الحاويات دون خادم serverless إذ لا حاجة مطلقًا لتنفيذ الحاوية إن لم تُستخدم. يمكن أيضًا تثبيت مقومات تشغيل البيئة على أغلب الأجهزة وتشغيل الحاويات بنفسك، بما في ذلك حاسوبك الخاص.

طالما أن الحاويات تعمل في البيئات السحابية وحتى أثناء تطوير التطبيقات، فما الفائدة من الفعلية منها إذًا؟ إليك حالتي الاستخدام التاليتين:

  • الحالة الأولى: عندما تحاول أن تطور تطبيقًا من المفترض أن يعمل على نفس الجهاز لدعم إصدار أقدم، فكلاهما يحتاج إلى تثبيت نسخ مختلفة من Node.js. بإمكانك استخدام nvm أو آلة افتراضية أو حتى اختراع طريقة سحرية لجعل النسختين تعملان معًا، لكن تبقى الحاويات حلًا ممتازًا لأنك تستطيع تشغيل كلا التطبيقين كلًا ضمن حاويته الخاصة، فهما معزولان عن بعضهما ولا يتداخلان.
  • الحالة الثانية: عندما يعمل تطبيقك على حاسوبك وتحاول نقله إلى خادم، فمن الأمور الشائعة ألا يعمل التطبيق على الخادم علمًا أنه يعمل جيدًا على حاسوبك. قد يكون الأمر اعتماديات مفقودة، أو اختلافات أخرى في بيئات التشغيل. في حالة كهذه، تظهر الحاويات مثل حل رائع، لأنها قادرة على تنفيذ التطبيق في نفس بيئة التنفيذ على حاسوبك أو على الخادم. وقد لا يكون حلًا مثاليًا نظرًا لاختلاف العتاد الصلب، لكن يمكنك أن تجعل الاختلافات في بيئات التنفيذ محدودةً جدًا.

قد تسمع أحيانًا عبارات من قبيل "يعمل ضمن حاويتي"، إذ تصف هذه العبارة الحالة التي يعمل فيها التطبيق جيدًا ضمن حاوية على جهازك لكنها تُخفق في تنفيذ التطبيق عندما تنقلها إلى الخادم. هذه العبارة هي تلاعب في العبارة "يعمل على جهازي"، فالحاويات مصممةٌ لتعمل، وغالبًا ما تكون هذه الحالة خطأ في الاستخدام.

حول هذا القسم

لن نركز اهتمامنا في هذا القسم على شيفرة جافاسكربت JavaScript، بل تهيئة البيئة التي سيُنفَّذ فيها التطبيق. لهذا قد لا تحتوي التمارين أية شيفرات. كما ستجد التطبيق جاهزًا على غيت هب GitHub ويحتاج فقط إلى التهيئة. ينبغي رفع التمارين إلى مستودع GitHub واحد يضم كل الشيفرات المصدرية وإعدادات التهيئة التي نفّذتها في هذا القسم.

لا بد أن تمتلك معرفة مبدئية بالتعامل مع Node و Express و React، وعليك إكمال الأقسام الجوهرية من 1 إلى 5 للمتابعة في هذا القسم.

التمرين 12.1

تنبيه

سنخرج في هذا القسم من دائرة الراحة الخاصة بمطوري JavaScript، وقد يتطلب منك ذلك جولةً لتتآلف مع أوامر الصدفة shell أو سطر الأوامر command line أو محث الأوامر command prompt أو الطرفية terminal قبل أن تبدأ؛ فإذا كنت تستخدم واجهة مستخدم رسومية ولم تلمس أبدًا طرفية لينوكس Linux أو ماك Mac، وشعرت بأنك تائه لا تعرف كيف تبدأ حل التمرين، ننصحك بالاطلاع على القسم الأول من كتاب "Computing tools for CS studies"، فهو يضم كل ما تحتاجه لمتابعة العمل هنا.

التمرين 12.1: استخدام الحاسوب دون واجهة مستخدم رسومية

  • الخطوة الأولى: اقرأ النص الذي يلي التنبيه.
  • الخطوة الثانية: نزّل مستودع التمرين واجعله مستودع تسليم التمارين لهذا القسم.
  • الخطوة الثالثة: انتقل إلى العنوان "http://helsinki.fi" واحفظ الخرج ضمن ملف، ثم احفظ الملف ضمن مستودعك بالاسم "script-answers/exercise12_1.txt". وتذكر أنك أنشأت بالفعل المجلد "script-answers" في الخطوة السابقة.

أدوات العمل

تحتاج إلى بعض الأدوات الأساسية التي تختلف وفقًا لنظام التشغيل.

  • ستحتاج WSL 2 terminal على نظام ويندوز.
  • الطرفية على نظام ماك.
  • سطر الأوامر على نظام لينوكس.

تثبيت كل ما تحتاجه للعمل

سنبدأ بتثبيت البرامج التي نحتاجها، وقد تشكل هذه الخطوة إحدى العقبات المحتملة، إذ لا بد من أذونات واسعة النطاق على جهازك طالما أننا نتحدث عن شكلٍ من البيئات الافتراضية على مستوى نظام التشغيل، وهذا ما يتطلب الولوج إلى نواته.

تتركز مادة القسم حول دوكر Docker، وهو يمثّل مجموعةً من المنتجات التي سنستخدمها في تشكيل وإدارة الحاويات، لكن إن لم تستطع تثبيته فلن تتمكن لسوء الحظ من متابعة العمل في هذا القسم.

ستختلف إرشادات عملية تثبيت المنتجات على حاسوبك وفقًا لنظام التشغيل، لذلك عليك أن تجد الإرشادات الصحيحة لتثبيت المنتج من خلال صفحة Docker المخصصة للغرض، وتذكر وجود خيارات عدة للتثبيت على نفس نظام التشغيل.

لنفترض أن كل شيء جرى على ما يُرام، لهذا سنتأكد من تطابق الإصدارات، إذ لا بُد أن يكون إصدار نسختك أعلى من هذا الإصدار:

$ docker -v
Docker version 20.10.5, build 55c4c88

الحاويات والصور

هناك مفهومان جوهريان فيما يتعلق بالحاويات، ومن السهل الخلط بينهما: الحاوية والصورة؛ إذ أن الحاوية هي نسخة التشغيل من الصورة، لهذا فكلا العبارتين التاليتين صحيحة:

  • تضم الصور الشيفرات والاعتماديات والإرشادات اللازمة لتشغيل التطبيق.
  • تُحزّم الحاويات البرنامج ضمن وحدات معيارية.

وبالتالي لا عجب من سهولة الخلط بينهما. للمساعدة في تجاوز الأمر، تُستخدم كلمة "حاوية" للإشارة إلى كلا المفهومين. لكنك لن تتمكن أبدًا من بناء حاوية أو تنزيلها لأنها موجودةٌ فقط أثناء التشغيل؛ أما الصورة فهي ملفاتٌ غير قابلة للتغيير، وبالتالي لن تكون قادرًا على تعديل صورة بعد إنشائها. لكن يمكنك استخدام صورة موجودة لإنشاء صورة جديدة بإضافة طبقات جديدة فوق القديمة. وبعبارات مجازية مستوردة من عالم الطبخ:

  • الصورة هي وجبة مطبوخة مسبقًا ومجمّدة.
  • الحاويات هي تلك الوجبة اللذيذة الجاهزة للأكل.

يُعد دوكر Docker أكثر تقنيات إنشاء الحاويات شهرةً وقد أبدع المعايير التي تستخدمها معظم تقنيات إنشاء الحاويات حاليًا. هذا المنتج تقنيًا هو مجموعة منتجات تساعد في إدارة الصور والحاويات وتمنحنا القدرة على العمل مع كل ميزاتها، إذ سيتولى Docker مثلًا مهمة تحويل الصور إلى حاويات.

هناك أداةٌ تُدعى Docker Compose لإدارة حاويات دوكر، إذ تسمح لك بتنسيق العمل على عدة حاويات في نفس الوقت، لهذا سنستخدمها في هذا القسم لبناء بيئة تطوير محلية مركّبة، ولم يعد هناك حاجةٌ لنثبت Node عند الانتهاء من إعداد بيئة التطوير هذه. يبقى هناك مجموعةٌ من المصطلحات التي علينا أن نعرّج عليها، لكننا سنتجاهل ذلك مؤقتًا لنتعلم أكثر عن دوكر.

لنبدأ من الأمر docker container run الذي يُستخدم لتشغيل الصور ضمن حاوية. لهذا الأمر الهيكلية التالية:

container run *IMAGE-NAME*

التي تخبر دوكر بإنشاء حاويةٍ من الصورة. ومن الميزات الجيدة لهذا الأمر هو إمكانية تشغيل حاوية حتى لو لم تُنزّل الحاوية على الجهاز بعد.

لننفِّذ الأمر:

§ docker container run hello-world

ستكون النتيجة العديد من المُخرجات، لهذا سنحاول فصلها إلى عدة أقسام كي نفسر هذه المخرجات معًا. رقمنا الأسطر لسهولة شرح ما فيها، فلن تجد أية أرقام لأسطر الخرج في الواقع:

1. Unable to find image 'hello-world:latest' locally
2. latest: Pulling from library/hello-world
3. b8dfde127a29: Pull complete
4. Digest: sha256:5122f6204b6a3596e048758cabba3c46b1c937a46b5be6225b835d091b90e46c
5. Status: Downloaded newer image for hello-world:latest

لم يعثُر الأمر على الصورة في جهازك، لذلك نزّلها من مُسجّل مجاني يُدعى Docker Hub. بإمكانك الاطلاع على صفحة الويب الخاصة بهذا المسجّل باستخدام المتصفح.

تنص الرسالة الأولى أن الصورة "hello-world:latest" غير موجودة بعد، وهذا ما يكشف بعض التفاصيل عن الصور بحد ذاتها، إذ تتألف أسماء الصور من عدة أجزاء بصورةٍ مشابهة لعناوين URL وهي على الشكل:

registry/organisation/image:tag

في حالتنا يعوَّض عن الحقول الثلاثة المفقودة بالقيم الافتراضية:

index.docker.io/library/hello-world:latest

يعرض السطر الثاني اسم المنظمة والمكتبة التي تحصل على الصورة منها، ويُختصر عنوان المكتبة في Docker Hub إلى _.

يعرض السطران الثالث والخامس الحالة فقط، لكن ما يضمه السطر الرابع هو المهم. لكل صورة معرّف تعمية مختزل وفريد digest بناءً على الطبقات التي بُنيت منها الصورة. وفي واقع الأمر تُنشئ كل تعليمة أو خطوة استُخدمت في بناء الصورة طبقةً فريدة، لهذا يستخدم دوكر معرّف التعمية المختزل لتمييز أن الصورة بقيت كما هي.

وهكذا نرى أن خرج الأمر السابق هو سحب ثم إخراج معلومات عن الصورة. تخبرنا الحالة بعد ذلك أن نسخةً جديدةً من الصورة "hello-world:latest" قد نُزّلت بالفعل. بإمكانك سحب الصورة باستخدام الأمر docker image pull hello-world ومتابعة ما سيحدث.

يمثل التالي خرجًا ناتجًا عن حاوية، ويشرح ما يجري عند تنفيذ الأمر docker container run hello-world:

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker container run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

يتضمن الخرج بعض الأشياء الجديدة التي يجب تعلّمها مثل:

  • Docker daemon: وهي خدمة في الخلفية تتحقق من عمل الحاوية.
  • Docker client: واجهة للتفاعل مع الخدمة السابقة.

لقد تفاعلنا مع الصورة الأولى وأنشأنا حاوية من هذه الصورة، وتلقينا الخرج أثناء تنفيذ الحاوية.

التمرين 12.2

لا تتطلب منك بعض هذه التمارين كتابة أية شيفرات أو إعدادات تهيئة في ملف. عليك أن تستخدم في هذا التمرين الأمر script لتسجيل الأوامر التي استخدمتها. جرّب ذلك بتنفيذ التعليمة script لتبدأ التسجيل ثم الأمر "echo "hello لتوليد خرج ما، ومن ثم التعليمة exit لإيقاف التسجيل. تُسجِّل تلك التعليمات أفعالك في ملف اسمه "typescript".

يمكنك أيضًا نسخ ولصق جميع الأوامر التي استخدمتها في ملف نصي إن لم تستطع استخدام script.

التمرين 12.2 تشغيل حاويتك الثانية

استخدم script لتسجيل ما تفعله واحفظ الملف بالاسم "script-answers/exercise12_2.txt".

نفّذ ما يلي:

  • الخطوة الأولى: شغّل حاوية بنفس أسلوب تشغيل الحاوية، إذ ستربطك هذه الخطوة مباشرةً مع الحاوية عبر تعليمات bash وستكون قادرًا على الوصول إلى كل الملفات والأدوات الموجودة ضمن الحاوية. لهذا نفذ الخطوات التالية ضمن الحاوية.
  • الخطوة الثانية: أنشئ المجلد "usr/src/app/".
  • الخطوة الثالثة: أنشئ الملف "usr/src/app/index.js/".
  • الخطوة الرابعة: نفّذ التعليمة exit للخروج من الحاوية.

ابحث عن طريقة إنشاء الملفات أو المجلدات بمساعدة محركات البحث إن لزم الأمر.

صورة Ubuntu

يحتوي الأمر التالي المُستخدم في تشغيل حاوية "ubuntu":

docker container run -it ubuntu bash

بعض الإضافات عن أمر تشغيل الحاوية "hello-world". سنستخدم التعليمة help-- لفهم الموضوع أكثر، وسنجتزئ بعض المعلومات التي تتعلق بحديثنا مما يرد في خرج العملية:

$ docker container run --help

Usage:  docker container run [OPTIONS] IMAGE [COMMAND] [ARG...]
Run a command in a new container

Options:
  ...
  -i, --interactive                    Keep STDIN open even if not attached
  -t, --tty                            Allocate a pseudo-TTY
  ...

تتحقق الرايتان أو الخياران it- من قدرتنا على التفاعل مع الحاوية، ثم نحدد بعد ذلك أن الصورة التي نشغلها هي "ubuntu"، ثم لدينا الأمر bash الذي يُنفَّذ داخل الحاوية عندما نشغلها.

يمكنك تجريب أوامر أخرى يمكن للصورة أن تُنفذها، مثل:

docker container run --rm ubuntu ls

إذ يرتب الأمر ls كل الملفات في المجلد ضمن قائمة، بينما يُزيل الأمر rm-- الحاوية بعد التنفيذ، فلا تُحذف الحاويات تلقائيًا عادةً.

لنتابع الآن مع أول حاوية "ubuntu" من خلال الملف "index.js" داخلها. لقد توقفت الحاوية عن العمل في اللحظة التي خرجنا منها. ولاستعراض جميع الحاويات، نستخدم الأمر container ls -a. إذ تستعرض الراية a- أو all-- كل الحاويات التي خرجنا منها توًا.

$ docker container ls -a
CONTAINER ID   IMAGE     COMMAND   CREATED          STATUS                            NAMES
b8548b9faec3   ubuntu    "bash"    3 minutes ago    Exited (0) 6 seconds ago          hopeful_clarke

أمامنا خياران يتعلقان بالتخاطب مع الحاوية: المعرّف في العمود الأول الذي يمكن استخدامه للتفاعل مع الحاوية في أي وقت، كما تقبل معظم الأوامر تمرير اسم الحاوية إليها. لاحظ أن الحاوية في مثالنا قد ولّدت تلقائيًا باسم "hopeful_clarke".

تُظهر حالة الحاوية أننا خرجنا منها منذ 6 ثوان ويمكنك تشغيلها مجددًا باستخدام الأمر start الذي يقبل معرّف الحاوية id أو اسمها:

$ docker start hopeful_clarke
hopeful_clarke

يشغّل الأمر الحاوية نفسها التي عملنا عليها سابقًا، لكن انتبه إلى أننا أغفلنا لسوء الحظ استخدام الراية interactive-- وبالتالي لن نتمكن من التفاعل معها. مع ذلك فالحاوية تعمل فعلًا، ويُظهر تنفيذ الأمر container ls -a ذلك، إلا أننا لا نستطيع التواصل معها:

$ docker container ls -a
CONTAINER ID   IMAGE     COMMAND   CREATED          STATUS                            NAMES
b8548b9faec3   ubuntu    "bash"    7 minutes ago    Up (0) 15 seconds ago            hopeful_clarke

يمكنك أيضًا تجاهل الراية a- في الأمر السابق لعرض الحاويات التي تعمل فقط:

$ docker container ls
CONTAINER ID   IMAGE     COMMAND   CREATED          STATUS             NAMES
8f5abc55242a   ubuntu    "bash"    8 minutes ago    Up 1 minutes       hopeful_clarke             

لنُنهي عمل الحاوية باستخدام الأمر kill يليه اسم الحاوية أو معرّفها ثم نحاول ثانية:

$ docker kill hopeful_clarke
hopeful_clarke

يُرسل الأمر الإشارة SIGKILL إلى العملية ليجبرها على التوقف، ونستطيع التأكد من حالتها بتنفيذ الأمر container ls -a:

$ docker container ls -a
CONTAINER ID   IMAGE     COMMAND   CREATED             STATUS                     NAMES
b8548b9faec3   ubuntu     "bash"   26 minutes ago      Exited 2 seconds ago       hopeful_clarke

لنشغل الحاوية الآن في وضع التفاعل:

$ docker start -i hopeful_clarke
root@b8548b9faec3:/#

سنجري بعض التعديلات على الملف"index.js" بإضافة شيفرة جافا سكربت، لكن تنقصنا الأداة اللازمة لذلك. سيكون المحرر Nano خيارًا جيدًا حاليًا، لذلك سننزّله ونشغله. يمكنك الاطلاع على طريقة استخدام هذا المحرر بإجراء بحث بسيط ضمن أي محرك بحث.

انتبه أنه لا حاجة لاستخدام التعليمة sudo فنحن فعليًا داخل المجلد الجذري:

root@b8548b9faec3:/# apt-get update
root@b8548b9faec3:/# apt-get -y install nano
root@b8548b9faec3:/# nano /usr/src/app/index.js

وهكذا يكون Nano جاهزًا للاستخدام.

التمرينان 12.3 - 12.4

حاول أن تحل التمرينين التاليين:

التمرين 12.3: 101 Ubuntu

استخدم script لتسجيل ما تفعله واحفظ الملف بالاسم "script-answers/exercise12_3.txt" واستخدم المحرر النصي Nano لتعديل الملف "usr/src/app/index.js/" ضمن الحاوية بإضافة السطر التالي:

console.log('Hello World')

يمكنك الاطلاع على طريقة استخدام محرر Nano بإجراء بحث بسيط ضمن أي محرك بحث.

التمرين 12.4: 102 Ubuntu

استخدم script لتسجيل ما تفعله واحفظ الملف بالاسم "script-answers/exercise12_4.txt" ثم ثبّت Node طالما أنك ضمن الحاوية، ثم شغِّل الملف "index" باستخدام الأمر ‍‍node /usr/src/app/index.js.

من الصعب أحيانًا إيجاد تعليمات واضحة لتثبيت Node لهذا إليك بعض الأوامر التي يمكنك نسخها ولصقها:

curl -sL https://deb.nodesource.com/setup_16.x | bash
apt install -y nodejs

لا بد أيضًا من تثبيت curl ضمن الحاوية بطريقة مشابهة لتثبيت Nano، وتأكد بعد اكتمال التثبيت من قدرتك على تنفيذ شيفرتك داخل الحاوية.

root@b8548b9faec3:/# node /usr/src/app/index.js
Hello World

أوامر دوكر أخرى

بعد أن ثبتنا Node ضمن الحاوية يمكننا تنفيذ شيفرة جافاسكريبت JavaScript داخلها. لنحاول الآن إنشاء صورة جديدة من الحاوية بعد التعديلات التي أجريناها. للأمر الصيغة التالية: "commit" + اسم أو معرف الحاوية + اسم الصورة الجديدة. يمكنك استخدام الأمر container diff للتحقق من التغييرات بين الصورة الأصلية والجديدة.

$ docker commit hopeful_clarke hello-node-world

كما يمكنك عرض قائمة بالصور الموجودة باستخدام image Is على النحو التالي:

$ docker image ls
REPOSITORY                                      TAG         IMAGE ID       CREATED         SIZE
hello-node-world                                latest      eef776183732   9 minutes ago   252MB
ubuntu                                          latest      1318b700e415   2 weeks ago     72.8MB
hello-world                                     latest      d1165f221234   5 months ago    13.3kB

وستتمكن من تشغيل الصورة الجديدة على النحو التالي:

docker run -it hello-node-world bash
root@4d1b322e1aff:/# node /usr/src/app/index.js

هناك عدة طرق لتحقيق النتيجة نفسها. لهذا دعونا نتحوّل إلى حل أفضل، وسنبدأ أولًا بإزالة الحاوية القديمة باستخدام الأمر container rm:

$ docker container ls -a
CONTAINER ID   IMAGE     COMMAND   CREATED          STATUS                  NAMES
b8548b9faec3   ubuntu    "bash"    31 minutes ago   Exited (0) 9 seconds ago               hopeful_clarke

$ docker container rm hopeful_clarke
hopeful_clarke

أنشئ الملف "index.js" في المجلد الحالي واكتب التعليمة ('console.log('Hello, World ضمنها. لا حاجة للحاويات بعد، ولنتفادى أيضًا تثبيت Node.

هناك العديد من الصور المفيدة الجاهزة للاستخدام يقدمها Docker Hub، لهذا سنستخدم الصورة " https://hub.docker.com/_/Node" التي تضم Node، وعلينا فقط اختيار الإصدار المناسب. كما تساعد الراية name-- في الأمر container run على تسمية الحاوية:

$ docker container run -it --name hello-node node:16 bash

سننشئ الآن مجلدًا للشيفرة ضمن الحاوية:

root@77d1023af893:/# mkdir /usr/src/app

وطالما أننا ضمن الحاوية، شغّل نسخة جديدة من الطرفية ونفّذ الأمر container cp لنسخ الملف من مكان وجوده في جهازك إلى الحاوية:

$ docker container cp ./index.js hello-node:/usr/src/app/index.js

يمكنك الآن تنفيذ الأمر ضمن الحاوية، كما يمكن تحضيرها على هيئة صورة جديدة، لكن هناك حل أفضل أيضًا. وهذا ما سنتابع البحث فيه لاحقًا.

ترجمة -وبتصرف- للفصل Introduction to Containers من سلسلة Deep Dive Into Modern Web Development

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...