Docker 101: الأساسيات والممارسات

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

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

عامل ميناء

إليكم تعريف دوكر وفقًا لويكيبيديا:

Docker هو برنامج كمبيوتر يقوم بإجراء محاكاة افتراضية على مستوى نظام التشغيل.

بسيط جدا ، أليس كذلك؟ حسنًا ، ليس بالضبط. حسنًا ، إليك تعريفي لما هو عامل الإرساء:

Docker هي عبارة عن منصة لإنشاء وتشغيل الحاويات من الصور .

فقدت ما زال؟ لا تقلق ، لأنك ربما لا تعرف ما هي الحاويات أو الصور .

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

ملاحظة مهمة: قبل المتابعة ، تأكد من تثبيت docker باستخدام الخطوات الموصى بها لنظام التشغيل الخاص بك.

الجزء 1. "مرحبًا ، أيها العالم!" من صورة Python

لنفترض أنه ليس لديك Python مثبتًا في جهازك - أو على الأقل ليس أحدث إصدار - وتحتاج إلى Python لطباعة "Hello، World!" في محطتك. ماذا تفعل؟ أنت تستخدم عامل ميناء!

انطلق وقم بتشغيل الأمر التالي:

docker run --rm -it python:3 python

لا تقلق ، سأشرح هذا الأمر في ثوانٍ ، لكن في الوقت الحالي ربما ترى شيئًا كهذا:

هذا يعني أننا داخل حاوية عامل ميناء تم إنشاؤها من صورة عامل إرساء python 3 ، نقوم بتشغيل pythonالأمر. لإنهاء المثال ، اكتب print("Hello, World!")وشاهد بينما يحدث السحر.

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

تقسمها

دعونا نبدأ من البداية. و docker runالأمر أداة عامل ميناء القياسية لمساعدتك على بدء وتشغيل الحاويات الخاصة بك.

و --rmالعلم هناك لنقول للعامل الميناء الشيطان لتنظيف الحاويات وإزالة نظام الملفات بعد خروج الحاويات. يساعدك هذا في توفير مساحة على القرص بعد تشغيل حاويات قصيرة العمر مثل هذه ، والتي بدأنا فقط في طباعة "Hello، World!".

و -t (or --tty)العلم يقول عامل الميناء إلى تخصيص جلسة محطة افتراضية داخل الحاوية. يستخدم هذا بشكل شائع مع -i (or --interactive)الخيار ، والذي يبقي STDIN مفتوحًا حتى إذا كان يعمل في وضع منفصل (المزيد عن ذلك لاحقًا).

ملاحظة: لا تقلق كثيرًا بشأن هذه التعريفات الآن. فقط اعلم أنك ستستخدم -itالعلم في أي وقت تريد فيه كتابة بعض الأوامر على الحاوية الخاصة بك.

أخيرًا ، python:3هي الصورة الأساسية التي استخدمناها لهذه الحاوية. في الوقت الحالي ، تأتي هذه الصورة مع الإصدار 3.7.3 من python مثبتًا ، من بين أشياء أخرى. الآن ، ربما تتساءل من أين أتت هذه الصورة وما بداخلها. يمكنك العثور على إجابات لكل من هذين السؤالين هنا ، بالإضافة إلى جميع صور الثعبان الأخرى التي كان من الممكن أن نستخدمها في هذا المثال.

أخيرًا وليس آخرًا ، pythonكان الأمر الذي طلبنا من Docker تنفيذه داخل python:3صورتنا ، والذي بدأ في إنشاء قشرة بيثون وسمح print("Hello, World!")لدعوتنا بالعمل.

شيء اخر

للخروج من python وإنهاء الحاوية الخاصة بنا ، يمكنك استخدام CTRL / CMD + D أو exit(). انطلق وافعل ذلك الآن. بعد ذلك ، حاول تنفيذ أمرنا docker runمرة أخرى وسترى شيئًا مختلفًا قليلاً ، وأسرع كثيرًا.

هذا لأننا قمنا بالفعل بتنزيل python:3الصورة ، لذلك تبدأ الحاوية الخاصة بنا بشكل أسرع الآن.

الجزء 2. آلي "Hello World!" من صورة Python

ما هو أفضل من كتابة "Hello، World!" في جهازك مرة واحدة؟ لقد فهمت ، اكتبها مرتين!

بما أننا لا نستطيع الانتظار لرؤية "Hello، World!" تمت طباعته في محطتنا مرة أخرى ، ولا نريد أن نخوض صخب فتح بايثون والكتابة printمرة أخرى ، دعنا نمضي قدمًا ونقوم بأتمتة هذه العملية قليلاً. ابدأ بإنشاء hello.pyملف في أي مكان تريده.

# hello.py
print("Hello, World!")

بعد ذلك ، امض قدمًا وقم بتشغيل الأمر التالي من نفس المجلد.

docker run --rm -it -v $(pwd):/src python:3 python /src/hello.py

هذه هي النتيجة التي نبحث عنها:

ملاحظة: لقد استخدمت lsقبل الأمر لأظهر لك أنني كنت في نفس المجلد الذي أنشأت فيه hello.pyالملف.

كما فعلنا سابقًا ، دعنا نعود خطوة إلى الوراء ونفهم كيف نجح ذلك.

تقسمها

نحن نشغل إلى حد كبير نفس الأمر الذي قمنا بتشغيله في القسم الأخير ، بصرف النظر عن شيئين.

و -v $(pwd):/srcيقول خيار عامل الميناء الشيطان لبدء ط حجم ن الحاويات لدينا . وحدات التخزين هي أفضل طريقة لاستمرار البيانات في Docker. في هذا المثال ، نخبر Docker أننا نريد إضافة الدليل الحالي - المسترجع من $(pwd)- إلى الحاوية الخاصة بنا في المجلد /src.

ملاحظة: يمكنك استخدام أي اسم أو مجلد آخر تريده ، وليس فقط /src

إذا كنت تريد التحقق من /src/hello.pyوجوده بالفعل داخل الحاوية الخاصة بنا ، فيمكنك تغيير نهاية الأمر من python hello.pyإلى bash. سيؤدي هذا إلى فتح غلاف تفاعلي داخل الحاوية الخاصة بنا ، ويمكنك استخدامها تمامًا كما تتوقع.

ملحوظة: لا يمكننا استخدام bashهنا إلا لأنه يأتي مثبتًا مسبقًا في python:3الصورة. بعض الصور بسيطة لدرجة أنها لا تمتلكها حتى bash. هذا لا يعني أنه لا يمكنك استخدامه ، ولكن سيتعين عليك تثبيته بنفسك إذا كنت تريد ذلك.

الجزء الأخير من أمرنا هو python /src/hello.pyالتعليمات. من خلال تشغيله ، فإننا نخبر الحاوية الخاصة بنا بالبحث داخل /srcمجلدها وتنفيذ hello.pyالملف باستخدام python.

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

الجزء 3. أسهل طريقة "Hello، World!" ممكن من صورة Python باستخدام Dockerfile

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

آخر أمر تعلمناه كان مطولًا بعض الشيء ، ويمكنني أن أرى نفسي قد سئمت من كتابة كل هذا الرمز في كل مرة أريد أن أقول "مرحبًا ، أيها العالم!" لنقم بأتمتة الأمور قليلاً الآن. قم بإنشاء ملف مسمى Dockerfileوأضف المحتوى التالي إليه:

# Dockerfile
FROM python:3
WORKDIR /src/app
COPY . .
CMD [ "python", "./hello.py" ]

الآن قم بتشغيل هذا الأمر في نفس المجلد الذي أنشأت فيه Dockerfile:

docker build -t hello .

كل ما تبقى الآن هو أن تصاب بالجنون باستخدام هذا الرمز:

docker run hello

أنت تعرف بالفعل كيف هو. دعنا نتوقف لحظة لفهم كيف يعمل Dockerfile الآن.

تقسمها

بدءًا من Dockerfile الخاص بنا ، فإن السطر الأول FROM python:3يخبر Docker أن يبدأ كل شيء بالصورة الأساسية التي نعرفها بالفعل python:3.

السطر الثاني WORKDIR /src/app، يحدد دليل العمل داخل الحاوية الخاصة بنا. هذا لبعض التعليمات التي سننفذها لاحقًا ، مثل CMDأو COPY. يمكنك الاطلاع على بقية التعليمات المدعومة WORKDIRهنا.

السطر الثالث ، COPY . .يخبر Docker بشكل أساسي بنسخ كل شيء من مجلدنا الحالي (أولاً .) ، ولصقه /src/app(ثانيًا .). تم تعيين موقع اللصق WORKDIRبالأمر فوقه مباشرةً.

ملاحظة: يمكننا تحقيق نفس النتائج عن طريق إزالة WORKDIRالتعليمات واستبدالها COPY . .بـ COPY . /src/app. في هذه الحالة ، سنحتاج أيضًا إلى تغيير التعليمات الأخيرة CMD ["python", "./hello.py"]إلى CMD ["python", "/src/app/hello.py"].

أخيرًا ، CMD ["python", "./hello.py"]يوفر السطر الأخير الأمر الافتراضي لحاويتنا. إنه يقول بشكل أساسي أنه في كل مرة نقوم فيها runباستخدام حاوية من هذا التكوين ، يجب تشغيلها python ./hello.py. ضع في اعتبارك أننا نعمل بشكل ضمني /src/app/hello.pyبدلاً من الركض فقط hello.py، لأن هذا هو ما أشرنا إليه WORKDIR.

ملاحظة: و CMDيمكن أن يكون الأمر الكتابة فوقها في وقت التشغيل. على سبيل المثال ، إذا كنت تريد التشغيل bashبدلاً من ذلك ، فستفعل ذلك docker run hello bashبعد بناء الحاوية.

مع انتهاء Dockerfile الخاص بنا ، نمضي قدمًا ونبدأ عمليتنا build. و docker build -t hello .يقرأ الأمر كافة التكوين أضفنا إلى موقعنا Dockerfile ويخلق صورة عامل ميناء منه. هذا صحيح ، تمامًا مثل python:3الصورة التي استخدمناها في هذه المقالة بأكملها. و .في نهاية يروي عامل الميناء الذي نريده لتشغيل Dockerfile في موقعنا الحالي، و -t helloالخيار يعطي هذه الصورة اسم hello، حتى نتمكن من الرجوع إليها بسهولة في وقت التشغيل.

بعد كل ذلك ، كل ما نحتاج إليه هو تشغيل docker runالتعليمات المعتادة ، ولكن هذه المرة helloباسم الصورة في نهاية السطر. سيؤدي ذلك إلى بدء حاوية من الصورة التي أنشأناها مؤخرًا وأخيرًا طباعة حرف ol الجيد "Hello، World!" في محطتنا.

توسيع صورتنا الأساسية

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

باتباع مثال python ، إذا احتجنا إلى numpyالمكتبة لتشغيل الكود الخاص بنا ، فيمكننا إضافة RUNالتعليمات مباشرة بعد FROMالأمر.

# Dockerfile
FROM python:3
# NEW LINERUN pip3 install numpy
WORKDIR /src/app
COPY . .
CMD [ "python", "./hello.py" ]

على RUNتعليمات يعطي أساسا أمر ليتم تنفيذها بواسطة محطة الحاوية. بهذه الطريقة ، نظرًا لأن صورتنا الأساسية pip3مثبتة بالفعل ، فيمكننا استخدامها pip3 install numpy.

ملاحظة: بالنسبة إلى تطبيق python حقيقي ، من المحتمل أن تضيف جميع التبعيات التي تحتاجها إلى requirements.txtملف ، ونسخها إلى الحاوية ، ثم تحديث RUNالتعليمات إلى RUN pip3 install -r requirements.txt.

الجزء 4. "مرحبًا ، أيها العالم!" من صورة Nginx باستخدام حاوية منفصلة طويلة العمر

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

قم بإنشاء index.htmlملف في مجلد جديد بالمحتوى التالي.

# index.html

Hello, World!

الآن ، لنقم بإنشاء Dockerfile جديد في نفس المجلد.

# Dockerfile
FROM nginx:alpine
WORKDIR /usr/share/nginx/html
COPY . .

قم ببناء الصورة وتسميتها simple_nginx، كما فعلنا سابقًا.

docker build -t simple_nginx .

أخيرًا ، لنقم بتشغيل صورتنا التي تم إنشاؤها حديثًا بالأمر التالي:

docker run --rm -d -p 8080:80 simple_nginx

قد تفكر في أنه لم يحدث شيء لأنك عدت إلى جهازك الطرفي ، ولكن دعنا نلقي نظرة فاحصة على docker psالأمر.

و docker psيظهر الأمر كافة حاويات تعمل في جهازك. كما ترى في الصورة أعلاه ، لدي حاوية مسماة simple_nginxقيد التشغيل في جهازي الآن. دعنا نفتح متصفح ويب ونرى ما إذا كان nginxيقوم بعمله عن طريق الوصول localhost:8080.

يبدو أن كل شيء يعمل كما هو متوقع ، ونحن نقدم صفحة ثابتة من خلال nginxالتشغيل داخل الحاوية الخاصة بنا. دعونا نتوقف لحظة لفهم كيف أنجزنا ذلك.

تقسمها

سأتخطى شرح Dockerfile لأننا تعلمنا بالفعل هذه الأوامر في القسم الأخير. الشيء الوحيد "الجديد" في هذا التكوين هو nginx:alpineالصورة ، والتي يمكنك قراءة المزيد عنها هنا.

بصرف النظر عن الجديد ، يعمل هذا التكوين لأنه nginxيستخدم usr/share/nginx/htmlالمجلد للبحث عن index.htmlملف والبدء في تقديمه ، لذلك نظرًا لأننا قمنا بتسمية الملف index.htmlوتكوينه WORKDIRليكون usr/share/nginx/html، فسيعمل هذا الإعداد مباشرة خارج الصندوق.

و buildالأمر بالضبط مثل واحد ونحن المستخدمة في المقطع الأخير أيضا، نحن فقط باستخدام التكوين Dockerfile لبناء صورة مع اسم معين.

الآن للجزء الممتع ، docker run --rm -d -p 8080:80 simple_nginxالتعليمات. هنا لدينا علمان جديدان. الأول هو علامة ( -d) المنفصلة ، مما يعني أننا نريد تشغيل هذه الحاوية في الخلفية ، ولهذا السبب عدنا إلى محطتنا بعد استخدام docker runالأمر مباشرة ، على الرغم من أن الحاوية الخاصة بنا لا تزال قيد التشغيل.

العلم الجديد الثاني هو -p 8080:80الخيار. كما قد تكون خمنت ، هذا هو portالعلم ، وهو في الأساس يرسم خريطة المنفذ 8080من أجهزتنا المحلية إلى الميناء 80داخل الحاوية الخاصة بنا. كان من الممكن أن تستخدم أي منفذ آخر بدلاً من ذلك 8080، لكن لا يمكنك تغيير المنفذ 80دون إضافة إعداد إضافي nginxللصورة ، نظرًا لأنه 80المنفذ القياسي الذي nginxتعرضه الصورة.

ملاحظة: إذا كنت تريد إيقاف حاوية منفصلة مثل هذه ، يمكنك استخدام docker psالأمر للحصول على اسم الحاوية (وليس الصورة) ، ثم استخدام docker stopالتعليمات مع اسم الحاوية المطلوب في نهاية السطر.

الجزء 5. النهاية

هذا هو! إذا كنت لا تزال تقرأ هذا ، فلديك كل الأساسيات لبدء استخدام Docker اليوم في مشاريعك الشخصية أو عملك اليومي.

اسمحوا لي أن أعرف رأيك في هذه المقالة في التعليقات ، وسأحرص على كتابة مقالة متابعة تغطي مواضيع أكثر تقدمًا مثل docker-composeمكان ما في المستقبل القريب.

إذا كان لديك أي أسئلة ، يرجى إعلامي.

في صحتك!