إعداد بيئة تطوير بايثون باستخدام VScode وDocker

يوفر هذا الدليل نموذج لإعداد بيئة تطوير Python 🐍 باستخدام VScode و Docker 🐳. تعد Docker أداة رائعة، ولكنها تحتوي على بعض منحنى التعلم. يهدف هذا البرنامج التعليمي إلى تقليل حاجز الدخول لأدوات التعلم مثل Docker.

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

لماذا نقوم بالتطوير مع Docker 🐳؟

Docker هي أداة CI/CD تتيح النشر السلس للتعليمات البرمجية من بيئات التطوير إلى بيئات الإنتاج. من خلال إنشاء محاكاة افتراضية على مستوى نظام التشغيل، يمكن حزم التطبيق وتبعياته في حاوية افتراضية وشحنه بين بيئات مختلفة. المزايا الرئيسية لاستخدام Docker في بيئة التطوير هي:

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

لماذا VScode 💻؟

VScode (المعروف أيضًا باسم Visual Studio Code) هو محرر تعليمات برمجية مجاني للأغراض العامة تم تطويره بواسطة Microsoft. يمكن تشغيله محليًا على أنظمة تشغيل Windows وmacOS وLinux أو على بيئة سحابية. المزايا الرئيسية لاستخدام VScode باعتباره IDE هي:

  • متعدد اللغات – يدعم JavaScript وTypeScript وNode.js الجاهزة، ويحتوي على مجموعة متنوعة من الامتدادات التي تتيح تشغيل لغات برمجة أخرى مثل Python وC++ وC# وGo وما إلى ذلك.
  • الامتدادات – يتمتع VScode بدعم مجتمعي كبير يقوم ببناء وصيانة مجموعة متنوعة من الامتدادات التي تعمل على توسيع قدرات المحرر ووظائفه. يتضمن ذلك الإضافات التي تدعم لغات البرمجة (مثل Python وR وJulia)، والمكونات الإضافية التي تتيح الاتصال بالتطبيقات الخارجية (Docker، وPostgres، وما إلى ذلك)، والتطبيقات الأخرى.
  • تكامل Git – يحتوي VScode على تكامل مدمج مع Git.
  • تكامل Docker – يدعم VScode تكامل Docker الأصلي، والذي سنتعمق فيه في الأقسام القادمة.

بالإضافة إلى ذلك، VScode مجاني ومفتوح المصدر.

إن قابلية التكرار العالية لـ Docker، إلى جانب التكامل السلس لـ Visual Studio Code مع Docker، تجعلها أداة تطوير رائعة، خاصة لمطوري Python. يمكّن هذا التكامل المطورين من إنشاء تطبيقات Python الخاصة بهم واختبارها ونشرها بسهولة في بيئة متسقة وقابلة للتكرار، مما يضمن تشغيل التعليمات البرمجية الخاصة بهم كما هو متوقع.

يركز هذا الدليل على إعداد بيئة تطوير Python باستخدام VScode. سنستكشف كيفية دمج VScode مع Docker باستخدام ملحقات Dev Container من Microsoft ونعرض طرقًا مختلفة لإعداد بيئة Python باستخدام Docker. ومع ذلك، من المهم ملاحظة أنه على الرغم من أن هذا الدليل يغطي بعض ميزات Docker الأساسية، إلا أنه ليس دليل Docker كاملاً. إذا لم تكن لديك خبرة سابقة في استخدام Docker، فإنني أوصي بشدة بالالتحاق بإحدى دورات Docker المكثفة.

المتطلبات الأساسية

لا يتطلب هذا الدليل خبرة سابقة في Docker و VScode. فالهدف هو تعليمك كيفية إعداد بيئة تطوير Python باستخدام Docker وVScode. ومع ذلك، كما هو مذكور أعلاه، ستستفيد أكثر من هذا االدليل وستستخدمه بشكل كبير إذا كنت تأخذ بعض الدورات التدريبية التمهيدية لـ Docker.

المتطلبات الأساسية هو إعداد VScode وDocker Desktop. بالإضافة إلى ذلك، ستحتاج إلى إعداد حساب في Docker Hub.

تثبيت VScode

يعد تثبيت VScode أمرًا بسيطًا – انتقل إلى موقع https://code.visualstudio.com وانقر على زر التنزيل (المستطيل الأرجواني):

صفحة تنزيل Visual Studio Code

قم بتنزيل ملف التثبيت واتبع التعليمات.

لإعداد بيئة Python باستخدام Docker في VScode، سنحتاج إلى الامتدادات التالية:

  • حاويات التطوير – يمكّن هذا الامتداد من فتح مجلد وتنفيذ تعليمات برمجية داخل حاوية Docker (مزيد من المعلومات متوفرة هنا).
  • Python – مكون Python الإضافي الرئيسي لـ VScode، يتيح التنفيذ وتصحيح الأخطاء والتنقل في التعليمات البرمجية وتنسيقها وما إلى ذلك (مزيد من المعلومات متاحة هنا).

إليك كيفية تثبيت الامتداد على VScode:

  • انقر فوق الزر “ملحقات” في القائمة اليسرى.
  • اكتب اسم الامتداد في قائمة البحث يمكنك الاطلاع على نتائج البحث أدناه، وسيؤدي النقر على كل امتداد إلى فتح نافذة تحتوي على تفاصيل الامتداد.
  • أخيرًا وليس آخرًا، انقر فوق زر التثبيت لتثبيت الامتداد.
خطوات تثبيت الامتداد على VScode

ملاحظة: ملحق Dev Containers مطلوب لتشغيل بيئة Docker. سنرى لاحقًا كيفية تعيين وتثبيت الامتدادات الضرورية لبيئة Docker تلقائيًا باستخدام ملف devcontainer.json.

إعداد Docker

توجد طرق مختلفة لإنشاء صور Docker وتشغيلها على أنظمة عمليات مختلفة. ولأغراض هذا الدليل، سنستخدم Docker Desktop. إنها واجهة إدارة حاويات سهلة الاستخدام ومتوافقة مع أنظمة التشغيل MacOS وWindows وLinux.

ملاحظة: Docker Desktop مجاني للاستخدام الشخصي ولكنه يتطلب ترخيصًا للاستخدام التجاري. لمزيد من المعلومات، يرجى الرجوع إلى https://www.docker.com/pricing.

لتثبيت Docker Desktop، انتقل إلى موقع Docker واتبع تعليمات التثبيت وفقًا لنظام التشغيل لديك:

صفحة تنزيل Docker Desktop

Docker Hub

يحتوي Container Registry على وظيفة مشابهة لوظيفة Github للتعليمات البرمجية، ويستخدم لتخزين الصور ومشاركتها. هناك العديد من سجلات الحاويات، وأكثرها شيوعًا هو Docker Hub. سنستخدم Docker Hub لسحب صور مختلفة، مثل صور Python المدمجة. للتسجيل وإنشاء حساب، انتقل إلى https://hub.docker.com واتبع تعليمات التسجيل.

بعد تثبيت Docker Desktop وإعداد الحساب على Docker Hub، افتح Docker Desktop، ومن سطر الأوامر، قم بتسجيل الدخول إلى Docker Hub:

 docker login

سيتعين عليك إدخال اسم المستخدم وكلمة المرور الخاصين بك، ويجب أن تتوقع الإخراج التالي في حالة نجاح تسجيل الدخول:

Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: rkrispin
Password:
Login Succeeded

Logging in with your password grants your terminal complete access to your account.
For better security, log in with a limited-privilege personal access token. Learn more at https://docs.docker.com/go/access-tokens/

ملاحظة: Docker Hub عام بالكامل (للطبقة المجانية). أي صورة تقوم بدفعها وتخزينها هناك ستكون متاحة لجميع المستخدمين الآخرين. بغض النظر عما إذا كان سجل الحاوية الخاص بك عامًا أم لا، فلا تقم مطلقًا بتخزين بيانات الاعتماد أو كلمات المرور أو أي معلومات حساسة أخرى على صور Docker الخاصة بك.

Hello World!

لا توجد طريقة أفضل لاختبار ما إذا كان Docker قد تم تثبيته بشكل صحيح من تشغيل الحوت (أو 🐳 على سبيل المثال) Hello World الخاص بـ Docker! مثال شائع.الحوت هو تعديل للعبة Linux Cowsay (🐮 مثلاً) باستخدام الحوت بدلاً من البقرة لطباعة بعض النصوص. لنقم بتشغيل الكود أدناه من الوحدة الطرفية لطباعة Hello Python Users! 👋 🐍:

docker run docker/whalesay cowsay Hello Python Users! 👋 🐍

إذا كانت هذه هي المرة الأولى التي تستخدم فيها Docker أو المرة الأولى التي تستخدم فيها صورة الحوت، فيجب أن تتوقع الرسالة التالية:

Unable to find image 'docker/whalesay:latest' locally

هذه رسالة عامة تُعلمك بأنه لا يمكن العثور على الصورة المطلوبة محليًا، وسيحاول Docker سحب الصورة من المركز (إذا تم تحديدها) ويتبع ذلك بتنزيل الصورة:

latest: Pulling from docker/whalesay
Image docker.io/docker/whalesay:latest uses outdated schema1 manifest format. Please upgrade to a schema2 image for better future compatibility. More information at https://docs.docker.com/registry/spec/deprecated-schema-v1/
e190868d63f8: Pull complete
909cd34c6fd7: Pull complete
0b9bfabab7c1: Pull complete
a3ed95caeb02: Pull complete
00bf65475aba: Pull complete
c57b6bcc83e3: Pull complete
8978f6879e2f: Pull complete
8eed3712d2cf: Pull complete
Digest: sha256:178598e51a26abbc958b8a2e48825c90bc22e641de3d31e18aaf55f3258ba93b
Status: Downloaded newer image for docker/whalesay:latest

وهذا هو الناتج المتوقع:

_______________________________
< Hello Python Users! 👋 🐍 >
 -------------------------------
    \
     \
      \
                    ##        .
              ## ## ##       ==
           ## ## ## ##      ===
       /""""""""""""""""___/ ===
  ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~
       \______ o          __/
        \    \        __/
          \____\______/

إذا كنت قادرًا على تشغيل تطبيق  whalesay، فأنت جاهز لبدء استخدام Docker.

البنية العامة وسير العمل

قبل التعمق في الوظائف الأساسية لـ Docker، دعنا نراجع بنية سير عمل التطوير العامة باستخدام Docker. يتمتع Docker بوظائف مشابهة لـ Git وGithub (أو Gitlab وBitbucket وما إلى ذلك)، مما يتيح تحويل بيئتك وإعداداتك (على عكس التعليمات البرمجية مع Git) من بيئة إلى أخرى (على سبيل المثال، dev -> staging أو dev -> prod) ) ضمان مستوى عال من الاستنساخ. في واقع الأمر، هذين الاثنين (Docker وGit) يسيران جنبًا إلى جنب.

الهندسة المعمارية العامة

يصف الرسم البياني أدناه بنية عالية المستوى لبيئة تطوير Dockerized مع VScode. قد يكون الأمر مربكًا إذا لم تستخدم Docker من قبل، وسيكون الأمر أكثر منطقية (كما آمل) بنهاية هذا القسم.

سير عمل التطوير باستخدام VScode وDocker

تتضمن هذه العملية المكونات التالية:

  • Dev Container – هو امتداد VScode الذي يمكّنك من تنفيذ التعليمات البرمجية المحلية داخل بيئة إرساء بسلاسة. افتراضيًا، يقوم بتثبيت المجلد المحلي في بيئة الإرساء مما يضمن تشغيل التعليمات البرمجية داخل الحاوية وبقاءها محليًا.
  • devcontainer.json – هو ملف إعداد Dev Container الذي يمكّنك من تخصيص بيئة تطوير VScode بشكل كبير عند استخدام ملحق Dev Container. من الإعدادات، خيارات VScode (على سبيل المثال، الخطوط، وقائمة الامتدادات المراد تثبيتها، وما إلى ذلك) إلى إعدادات Docker (على غرار وظيفة ملف docker-compose.yml)
  • Dockerfile – هو بيان الصورة أو الوصفة. فهو يوفر تعليمات لمحرك الإرساء حول الصورة الأساسية التي يجب استخدامها والمكونات التي سيتم تثبيتها. عادةً، تبدأ عملية الإنشاء عن طريق استيراد بعض الصور الأساسية باستخدام الأمر FROM، وهو ما سنشرحه لاحقًا في هذا الدليل. يمكّنك ملحق Dev Container من إنشاء الصورة بسرعة عند تشغيل البيئة باستخدام ملف Dockerfile أو استيراد صورة مضمنة من بعض سجلات الصور مثل Docker Hub.
  • سجل الصور – له وظائف مشابهة لـ Github / Gitlab / Bitbucket، ويتم استخدامه لتخزين الصور العامة (أو الخاصة في بعض إصدارات المؤسسات). يتيح لك سجل الصور نقل صورك وتوزيعها من بيئة إلى أخرى. في هذا الدليل، سنستخدم سجل الصور الرئيسي – Docker Hub.
  • تسجيل التعليمات البرمجية – بعيدًا عن التحكم في الإصدار، فهو يمكّنك من نقل التعليمات البرمجية من بيئة إلى أخرى. في هذا الدليل، سوف نستخدم Github باعتباره سجل التعليمات البرمجية الخاص بنا.

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

سير العمل التطويري

دعونا الآن ننظم هذه العملية ونرتبها وفقًا لسير العمل العام. يحدد الرسم البياني أدناه الترتيب العام للعملية لعملية التطوير مع تطبيق الخطوات التالية:

  • تثبيت التبعيات – تحديد المتطلبات الأساسية، بما في ذلك تثبيت VScode والامتدادات المطلوبة (على سبيل المثال، Dev Container، وما إلى ذلك)، وتثبيت Docker، وإعداد حساب Docker Hub (أو ما يعادله).
  • قم بتعيين ملف Dockerfile – هذه الخطوة اختيارية، إذا كنت ترغب في إنشاء صورتك بسرعة. وبدلاً من ذلك، يمكنك استيراد صورة مضمنة من سجل الصور وتخطي هذه الخطوة. في القسم التالي، سنتعمق في مزيد من التفاصيل حول الوظيفة الأساسية لملف Dockerfile وكيفية ضبطه.
  • قم بتعيين ملف devcontainer.json – يحدد هذا الملف البيئة ويمكّنك من تخصيص كل من وظيفة VScode وإعدادات VScode. لاحقًا في هذا الدليل، سنرى كيفية تعيين هذا الملف.
  • التطوير – بمجرد تعيين ملف devcontainer.json، يمكنك تشغيل بيئة التطوير الخاصة بك باستخدام ملحق Dev Container في المجلد المحلي.
  • الاختبار – هذه خطوة وسيطة موصى بها قبل شحن التعليمات البرمجية والبيئة للنشر. هناك طرق متعددة لاختبار التعليمات البرمجية والبيئة، والهدف الرئيسي هو التأكد من مزامنة التعليمات البرمجية مع بيئة الإرساء وتحديد المشكلات المحتملة قبل نشرها.
  • النشر – أخيرًا وليس آخرًا، باستخدام التعليمات البرمجية وسجل الحاويات (على سبيل المثال، Github وDocker Hub)، يمكننا نشر التعليمات البرمجية الخاصة بنا باستخدام نفس بيئة الإرساء إلى بعض الخوادم البعيدة (على سبيل المثال، Github Actions، وAWS، وGCP، وAzure، وما إلى ذلك) أو اطلب من زملائك تشغيل التعليمات البرمجية على أجهزة الكمبيوتر الخاصة بهم.
التطوير باستخدام سير عمل VScode وDocker

في القسم التالي، سنراجع أوامر Docker الأساسية ونتعلم كيفية تعيين Dockerfile.

الشروع في العمل مع Docker

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

  • Dockerfile – وصفة الصورة، تسمح لك بإضافة مكونات وتخصيص التبعيات وفقًا لمتطلبات بيئة التطوير.
  • Docker CLI – الأوامر الأساسية لبناء الصورة وتشغيلها كبيئة حاوية.
سير العمل العام ل Docker

ملاحظة: من المهم التأكيد على أن هذا القسم يغطي متطلبات Docker الأساسية وليس بديلاً لدورة Docker.

Dockerfile

يوفر Dockerfile مجموعة من الإرشادات لمحرك Docker حول كيفية إنشاء الصورة. يمكنك التفكير في الأمر كوصفة للصورة. لديها بناء جملة فريد وبديهي خاص بها باستخدام البنية التالية:

COMMAND some instructions

على سبيل المثال، يستورد Dockerfile التالي صورة Python الرسمية كصورة أساسية ثم يستخدم التحديث apt-get و apt-get install لتثبيت مكتبة  curl:

FROM python:3.10

LABEL example=1

ENV PYTHON_VER=3.10

RUN apt-get update && apt-get install -y --no-install-recommends curl

باختصار، استخدمنا الأمر FROM لتحديد الصورة التي نريد استيرادها من سجل Docker (لا تنس تسجيل الدخول إلى خدمة تسجيل Docker التي تستخدمها قبل إنشاء الصورة!). يتم استخدام أمر LABEL لتعيين التسميات أو التعليقات، ويستخدم أمر ENV لتعيين متغيرات البيئة. وأخيرًا وليس آخرًا، يتم استخدام أمر RUN لتشغيل أمر في سطر الأوامر، وفي هذه الحالة لتثبيت مكتبة curl.

لنراجع الآن أوامر Dockerfile الأساسية:

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

LABEL – يتيح إضافة معلومات حول الصورة إلى البيانات التعريفية للصورة، مثل المؤلفين والمشرفين والترخيص وما إلى ذلك.

ENV – يستخدم لتعيين متغيرات البيئة.

ARG – يتيح ضبط المعلمات أثناء وقت الإنشاء.

RUN – يسمح بتنفيذ أوامر CLI (على سبيل المثال pip install…، apt-get…، apt-install…، إلخ.) أثناء وقت الإنشاء لإضافة مكونات إضافية إلى الصورة الأساسية.

COPY – يتيح نسخ الكائنات (مثل الملفات والمجلدات) من نظامك المحلي إلى الصورة.

WORKDIR – يضبط دليل العمل داخل الصورة.

EXPOSE – يحدد رقم المنفذ لعرض الصورة أثناء وقت التشغيل.

CMD – يقوم بتعيين أمر افتراضي ليتم تنفيذه أثناء وقت تشغيل الصورة.

ENDPOINT – يسمح بإعداد حاوية سيتم تشغيلها كملف قابل للتنفيذ.

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

بناء Docker

بمجرد أن يصبح Dockerfile جاهزًا، فإن الخطوة التالية هي إنشاء الصورة باستخدام أمر docker build من سطر الأوامر. على سبيل المثال، لنقم بإنشاء Dockerfile أعلاه باستخدام أمر build من مجلد جذر المستودع:

docker build . -f ./examples/ex-1/Dockerfile -t rkrispin/vscode-python:ex1 

فيما يلي الوسائط التي استخدمناها مع أمر  build:

  • تحدد العلامة -f مسار Dockerfile. هذه الوسيطة اختيارية ويجب استخدامها إذا كنت تستدعي دالة build من مجلد مختلف عن أحد ملفات Dockerfile.
  • ال . تحدد مجلد السياق لنظام الملفات باعتباره أحد ملفات Dockerfile. على الرغم من أننا لم نستخدم نظام الملفات في هذه الحالة، إلا أن هذا يمكننا في حالات أخرى من استدعاء ونسخ الملفات من المجلد المحلي إلى الصورة أثناء وقت البناء.
  • يتم استخدام -t لتعيين اسم الصورة وعلامتها (على سبيل المثال، الإصدار). في هذه الحالة، اسم الصورة هو rkrispin/vscode-python والعلامة هي ex1.

يجب أن تتوقع الإخراج التالي:

[+] Building 94.2s (6/6) FINISHED                                                                                                                                                                                                  
 => [internal] load build definition from Dockerfile                                                                                                                                                                          0.0s
 => => transferring dockerfile: 162B                                                                                                                                                                                          0.0s
 => [internal] load .dockerignore                                                                                                                                                                                             0.0s
 => => transferring context: 2B                                                                                                                                                                                               0.0s
 => [internal] load metadata for docker.io/library/python:3.10                                                                                                                                                                6.0s
 => [1/2] FROM docker.io/library/python:3.10@sha256:a8462db480ec3a74499a297b1f8e074944283407b7a417f22f20d8e2e1619782                                                                                                         82.1s
 => => resolve docker.io/library/python:3.10@sha256:a8462db480ec3a74499a297b1f8e074944283407b7a417f22f20d8e2e1619782                                                                                                          0.0s
 => => sha256:a8462db480ec3a74499a297b1f8e074944283407b7a417f22f20d8e2e1619782 1.65kB / 1.65kB                                                                                                                                0.0s
 => => sha256:4a1aacea636cab6af8f99f037d1e56a4de97de6025da8eff90b3315591ae3617 2.01kB / 2.01kB                                                                                                                                0.0s
 => => sha256:23e11cf6844c334b2970fd265fb09cfe88ec250e1e80db7db973d69d757bdac4 7.53kB / 7.53kB                                                                                                                                0.0s
 => => sha256:bba7bb10d5baebcaad1d68ab3cbfd37390c646b2a688529b1d118a47991116f4 49.55MB / 49.55MB                                                                                                                             26.1s
 => => sha256:ec2b820b8e87758dde67c29b25d4cbf88377601a4355cc5d556a9beebc80da00 24.03MB / 24.03MB                                                                                                                             11.0s
 => => sha256:284f2345db055020282f6e80a646f1111fb2d5dfc6f7ee871f89bc50919a51bf 64.11MB / 64.11MB                                                                                                                             26.4s
 => => sha256:fea23129f080a6e28ebff8124f9dc585b412b1a358bba566802e5441d2667639 211.00MB / 211.00MB                                                                                                                           74.5s
 => => sha256:7c62c924b8a6474ab5462996f6663e07a515fab7f3fcdd605cae690a64aa01c7 6.39MB / 6.39MB                                                                                                                               28.2s
 => => extracting sha256:bba7bb10d5baebcaad1d68ab3cbfd37390c646b2a688529b1d118a47991116f4                                                                                                                                     1.6s
 => => sha256:c48db0ed1df2d2df2dccd680323097bafb5decd0b8a08f02684b1a81b339f39b 17.15MB / 17.15MB                                                                                                                             31.9s
 => => extracting sha256:ec2b820b8e87758dde67c29b25d4cbf88377601a4355cc5d556a9beebc80da00                                                                                                                                     0.6s
 => => sha256:f614a567a40341ac461c855d309737ebccf10a342d9643e94a2cf0e5ff29b6cd 243B / 243B                                                                                                                                   28.4s
 => => sha256:00c5a00c6bc24a1c23f2127a05cfddd90865628124100404f9bf56d68caf17f4 3.08MB / 3.08MB                                                                                                                               29.4s
 => => extracting sha256:284f2345db055020282f6e80a646f1111fb2d5dfc6f7ee871f89bc50919a51bf                                                                                                                                     2.5s
 => => extracting sha256:fea23129f080a6e28ebff8124f9dc585b412b1a358bba566802e5441d2667639                                                                                                                                     6.2s
 => => extracting sha256:7c62c924b8a6474ab5462996f6663e07a515fab7f3fcdd605cae690a64aa01c7                                                                                                                                     0.3s
 => => extracting sha256:c48db0ed1df2d2df2dccd680323097bafb5decd0b8a08f02684b1a81b339f39b                                                                                                                                     0.5s
 => => extracting sha256:f614a567a40341ac461c855d309737ebccf10a342d9643e94a2cf0e5ff29b6cd                                                                                                                                     0.0s
 => => extracting sha256:00c5a00c6bc24a1c23f2127a05cfddd90865628124100404f9bf56d68caf17f4                                                                                                                                     0.2s
 => [2/2] RUN apt-get update && apt-get install -y --no-install-recommends curl                                                                                                                                               5.9s
 => exporting to image                                                                                                                                                                                                        0.1s
 => => exporting layers                                                                                                                                                                                                       0.1s
 => => writing image sha256:a8e4c6d06c97e9a331a10128d1ea1fa83f3a525e67c7040c2410940312e946f5                                                                                                                                  0.0s
 => => naming to docker.io/rkrispin/vscode-python:ex1  

يمكنك استخدام أمر docker Images للتحقق من إنشاء الصورة بنجاح:

>docker images
REPOSITORY                             TAG       IMAGE ID       CREATED        SIZE
rkrispin/vscode-python                 ex1       a8e4c6d06c97   43 hours ago   1.02GB

سيركز القسم التالي على طبقات الصورة وعملية التخزين المؤقت.

طبقات الصورة

تعتمد عملية إنشاء صور Docker على الطبقات. اعتمادًا على السياق، يأخذ محرك docker كل أمر من أوامر Dockerfile أثناء وقت البناء ويترجمه إما إلى طبقة أو بيانات وصفية. تتم ترجمة أوامر Dockerfile، مثل FROM و RUN، إلى طبقة، ويتم ترجمة الأوامر، مثل LABEL و ARG و ENV و CMD إلى بيانات تعريف. على سبيل المثال، يمكننا أن نلاحظ في مخرجات إنشاء صورة rkrispin/vscode-python أعلاه أن هناك طبقتين:

  • بدأت الطبقة الأولى بـ [1/2] FROM…، المتوافق مع سطر FROM python:3.10 الموجود في Dockerfile، والذي يستورد صورة Python 3.10 الرسمية.
  • بدأت الطبقة الثانية بـ [2/2] RUN apt-get…، المطابق لأمر RUN الموجود في ملف Dockerfile.
مثال على مخرجات البناء فيما يتعلق بملف Dockerfile

يقوم أمر  docker inspect بإرجاع تفاصيل البيانات التعريفية للصورة بتنسيق JSON. يتضمن ذلك متغيرات البيئة والعلامات والطبقات والبيانات التعريفية العامة. في المثال التالي، سنطلب من jq استخراج معلومات الطبقات من ملف البيانات الوصفية JSON:

> docker inspect rkrispin/vscode-python:ex1 | jq '.[] | .RootFS'
{
  "Type": "layers",
  "Layers": [
    "sha256:332b199f36eb054386cd2931c0824c97c6603903ca252835cc296bacde2913e1",
    "sha256:2f98f42985b15cbe098d2979fa9273e562e79177b652f1208ae39f97ff0424d3",
    "sha256:964529c819bb33d3368962458c1603ca45b933487b03b4fb2754aa55cc467010",
    "sha256:e67fb4bad8f42cca08769ee21bbe15aca61ab97d4a46b181e05fefe3a03ee06d",
    "sha256:037f26f869124174b0d6b6d97b95a5f8bdff983131d5a1da6bc28ddbc73531a5",
    "sha256:737cec5220379f795b727e6c164e36e8e79a51ac66a85b3e91c3f25394d99224",
    "sha256:65f4e45c2715f03ed2547e1a5bdfac7baaa41883450d87d96f877fbe634f41a9",
    "sha256:baef981f26963b264913e79bd0a1472bae389441022d71f559e9d186600d2629",
    "sha256:88e1d36ff4812423afc93d5f6208f2783df314d5ecf6f961325c65e1dbf891da"
  ]
}

كما ترون من إخراج طبقات الصورة أعلاه، تحتوي صورة rkrispin/vscode-python:ex1 على تسع طبقات. يتم تمثيل كل طبقة بواسطة مفتاح التجزئة الخاص بها (على سبيل المثال، sha256:…)، ويتم تخزينها مؤقتًا على الواجهة الخلفية. بينما رأينا في مخرجات البناء أن محرك docker أطلق عمليتين من الأمرين FROM و RUN، فقد انتهى بنا الأمر بتسع طبقات بدلاً من طبقتين. ويرتبط السبب الرئيسي لذلك بحقيقة أنه عند استيراد الصورة الأساسية، ورثنا خصائص الصورة المستوردة، بما في ذلك الطبقات. في هذه الحالة، استخدمنا FROM لاستيراد صورة Python الرسمية، والتي تضمنت ثماني طبقات، ثم أضفنا الطبقة التاسعة عن طريق تنفيذ أوامر RUN. يمكنك اختبارها عن طريق سحب الصورة الأساسية واستخدام أمر الفحص لمراجعة طبقاتها:

> docker pull python:3.10
3.10: Pulling from library/python
bba7bb10d5ba: Already exists 
ec2b820b8e87: Already exists 
284f2345db05: Already exists 
fea23129f080: Already exists 
7c62c924b8a6: Already exists 
c48db0ed1df2: Already exists 
f614a567a403: Already exists 
00c5a00c6bc2: Already exists 
Digest: sha256:a8462db480ec3a74499a297b1f8e074944283407b7a417f22f20d8e2e1619782
Status: Downloaded newer image for python:3.10
docker.io/library/python:3.10

> docker inspect python:3.10 | jq '.[] | .RootFS'
{
  "Type": "layers",
  "Layers": [
    "sha256:332b199f36eb054386cd2931c0824c97c6603903ca252835cc296bacde2913e1",
    "sha256:2f98f42985b15cbe098d2979fa9273e562e79177b652f1208ae39f97ff0424d3",
    "sha256:964529c819bb33d3368962458c1603ca45b933487b03b4fb2754aa55cc467010",
    "sha256:e67fb4bad8f42cca08769ee21bbe15aca61ab97d4a46b181e05fefe3a03ee06d",
    "sha256:037f26f869124174b0d6b6d97b95a5f8bdff983131d5a1da6bc28ddbc73531a5",
    "sha256:737cec5220379f795b727e6c164e36e8e79a51ac66a85b3e91c3f25394d99224",
    "sha256:65f4e45c2715f03ed2547e1a5bdfac7baaa41883450d87d96f877fbe634f41a9",
    "sha256:baef981f26963b264913e79bd0a1472bae389441022d71f559e9d186600d2629"
  ]
}

التخزين المؤقت للطبقات

إحدى سلبيات Docker هي وقت بناء الصورة. نظرًا لأن مستوى تعقيد ملف Dockerfile أعلى (على سبيل المثال، عدد كبير من التبعيات)، فكلما زاد وقت الإنشاء. في بعض الأحيان، لن يتم تنفيذ البناء الخاص بك كما هو متوقع في المحاولة الأولى. إما أن بعض المتطلبات مفقودة، أو أن شيئًا ما تعطل أثناء وقت الإنشاء. هذا هو المكان الذي يساعد فيه استخدام التخزين المؤقت في تقليل وقت إعادة بناء الصورة. يتمتع Docker بميكنة ذكية تحدد ما إذا كان يجب إنشاء كل طبقة من البداية أو يمكنها الاستفادة من الطبقة المخزنة مؤقتًا وتوفير الوقت. على سبيل المثال، دعونا نضيف إلى المثال السابق أمرًا آخر لتثبيت محرر vim. بشكل عام، يمكننا (ويجب علينا) إضافتها إلى نفس apt-get الذي نستخدمه لتثبيت حزمة  curl، ولكن لغرض إظهار وظيفة التخزين المؤقت للطبقات، سنقوم بتشغيلها بشكل منفصل:

./examples/ex-2/Dockerfile
FROM python:3.10

LABEL example=1

ENV PYTHON_VER=3.10

RUN apt-get update && apt-get install -y --no-install-recommends curl

RUN apt-get update && apt-get install -y --no-install-recommends vim

سوف نستخدم الأمر أدناه لإنشاء هذه الصورة ووضع علامة عليها كـ rkrispin/vscode-python:ex2:

docker build . -f ./examples/ex-2/Dockerfile -t rkrispin/vscode-python:ex2 --progress=plain

يجب أن تتوقع الإخراج التالي (في حالة تشغيل الإصدار السابق):

 => [internal] load build definition from Dockerfile                                                                                                                                     0.0s
 => => transferring dockerfile: 234B                                                                                                                                                     0.0s
 => [internal] load .dockerignore                                                                                                                                                        0.0s
 => => transferring context: 2B                                                                                                                                                          0.0s
 => [internal] load metadata for docker.io/library/python:3.10                                                                                                                           0.0s
 => [1/3] FROM docker.io/library/python:3.10                                                                                                                                             0.0s
 => CACHED [2/3] RUN apt-get update && apt-get install -y --no-install-recommends curl                                                                                                   0.0s
 => [3/3] RUN apt-get update && apt-get install -y --no-install-recommends vim                                                                                                          34.3s
 => exporting to image                                                                                                                                                                   0.4s 
 => => exporting layers                                                                                                                                                                  0.4s 
 => => writing image sha256:be39eb0eb986f083a02974c2315258377321a683d8472bac15e8d5694008df35                                                                                             0.0s 
 => => naming to docker.io/rkrispin/vscode-python:ex2   

كما يمكن ملاحظة من ناتج البناء أعلاه، فإن الطبقتين الأولى والثانية موجودتان بالفعل من البناء السابق. لذلك، يضيف محرك docker طبقاته المخزنة مؤقتًا إلى الصورة (بدلاً من بنائها من البداية)، ويقوم فقط ببناء الطبقة الثالثة وتثبيت محرر vim.

ملاحظة: بشكل افتراضي، تكون مخرجات البناء موجزة وقصيرة. يمكنك الحصول على مخرجات أكثر تفصيلاً أثناء وقت الإنشاء عن طريق إضافة وسيطة  progress وتعيينها على  plain:

> docker build . -f ./examples/ex-2/Dockerfile -t rkrispin/vscode-python:ex2 --progress=plain
#1 [internal] load .dockerignore
#1 transferring context: 2B done
#1 DONE 0.0s

#2 [internal] load build definition from Dockerfile
#2 transferring dockerfile: 234B done
#2 DONE 0.0s

#3 [internal] load metadata for docker.io/library/python:3.10
#3 DONE 0.0s

#4 [1/3] FROM docker.io/library/python:3.10
#4 DONE 0.0s

#5 [2/3] RUN apt-get update && apt-get install -y --no-install-recommends curl
#5 CACHED

#6 [3/3] RUN apt-get update && apt-get install -y --no-install-recommends vim
#6 CACHED

#7 exporting to image
#7 exporting layers done
#7 writing image sha256:be39eb0eb986f083a02974c2315258377321a683d8472bac15e8d5694008df35 0.0s done
#7 naming to docker.io/rkrispin/vscode-python:ex2 done
#7 DONE 0.0s

نظرًا لأننا قمنا بالفعل بتخزين الطبقة الثالثة مؤقتًا في الإصدار السابق، فسيتم تخزين جميع الطبقات في الإخراج أعلاه مؤقتًا، ويكون وقت التشغيل أقل من ثانية واحدة.

عند إعداد Dockerfile، يجب أن تكون مهتمًا بعملية التخزين المؤقت للطبقات. ترتيب الطبقات مهم! توضح الصور التالية متى سيستخدم محرك docker الطبقات المخزنة مؤقتًا ومتى سيتم إعادة بنائها. الصورة الأولى توضح البناء الأولي:

رسم توضيحي للبناء الأولي للصورة. يمثل الجانب الأيسر أوامر Dockerfile والجانب الأيمن يمثل الطبقات المقابلة

في هذه الحالة، لدينا Dockerfile يحتوي على أربعة أوامر يتم ترجمتها أثناء وقت الإنشاء إلى أربع طبقات. ماذا سيحدث لو أضفنا أمرا خامسا ووضعناه بعد الأمر الثالث مباشرة؟ سيحدد محرك docker أن الأمرين الأول والثاني في Dockerfile لم يتغيرا، وبالتالي، سيستخدم الطبقات المخزنة مؤقتًا المقابلة (الواحدة والثانية)، وسيعيد بناء بقية الطبقات من البداية:

رسم توضيحي لعملية التخزين المؤقت أثناء إعادة بناء الصورة

عند التخطيط Dockerfile، إن أمكن، من الممارسات الجيدة وضع الأوامر التي من المرجح أن تظل كما هي والاحتفاظ بالتحديثات الجديدة حتى نهاية الملف إن أمكن.

كان هذا مجرد غيض من فيض، وهناك الكثير لنتعلمه عن Docker. سيستكشف القسم التالي طرقًا مختلفة لتشغيل Python داخل الحاوية.

تشغيل Python على Docker – بالطريقة الصعبة

لقد رأينا في الأقسام السابقة كيفية تحديد متطلبات الصورة باستخدام Dockerfile وإنشائها باستخدام أمر build. يركز هذا القسم على تشغيل Python داخل حاوية باستخدام أمر docker run.

Docker run

يمكّننا أمر docker run أو run من إنشاء حاوية جديدة وتشغيلها من صورة. عادةً، يتم استخدام أمر run لتشغيل تطبيق أو خادم dockerized أو لتنفيذ تعليمات برمجية تتبع بناء الجملة التالي:

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

على سبيل المثال، يمكننا استخدام أمر run مع صورة Python 3.10 الرسمية:

docker run python:3.10 

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

  • الخادم
  • التطبيق

في كلتا الحالتين، نستخدم Dockerfile لتعيين وتمكين إطلاقها أثناء وقت التشغيل. في حالة الخادم، نستخدم أوامر PORT و CMD في Dockerfile لتعيين منفذ الخادم على الصورة وتشغيل الخادم، على التوالي. نستخدم بعد ذلك أمر run ونضيف الخيار -p (أو --publish list) لتعيين منفذ الخادم بمنفذ محلي. وبالمثل، لتشغيل تطبيق ما، نستخدم أمر CMD الموجود في Dockerfile لتحديد أمر التشغيل أثناء وقت التشغيل واستخدام خيارات --interactive و --tty لتشغيل الحاوية في الوضع التفاعلي، مما يمكننا من الوصول إلى التطبيق .

لنعد الآن إلى صورة python:3.10 ونستخدم أمر inspect للتحقق مما إذا كان أمر CMD قد تم تعريفه:

> docker inspect python:3.10 | jq '.[] | .Config.Cmd'
[
  "python3"
]

ملاحظة: استخدمنا مكتبة jqمرة أخرى لتحليل بيانات تعريف CMD من إخراج JSON.

كما ترون، تم تعيين CMD في صورة python:3.10 لتشغيل أمر إطلاق Python الافتراضي – python3، الذي يقوم بتشغيل Python أثناء وقت التشغيل. لنقم الآن بإضافة خياري --interactive و --tty لتشغيل الحاوية في الوضع التفاعلي:

 docker run --interactive --tty python:3.10 

يؤدي هذا إلى تشغيل إصدار Python الافتراضي على الصورة. يمكننا بعد ذلك اختباره باستخدام أمر print لطباعة Hello World!:

Python 3.10.12 (main, Jun 14 2023, 18:40:54) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print("Hello World!")
Hello World!
>>> 

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

  • هذه ليست بيئة تطوير، ومن الصعب (في رأيي) الحفاظ على التعليمات البرمجية وتطويرها من الطرفية فيما يتعلق بـ Python IDEs مثل PyCharm أو VScode.
  • افتراضيًا، يعد تشغيل  docker run عملية سريعة الزوال، وبالتالي، يتم فقدان التعليمات البرمجية عند إيقاف تشغيل الحاوية.

على الرغم من وجود طرق للتغلب على المشكلات المذكورة أعلاه، إلا أنها لا تزال معقدة وغير فعالة مثل استخدام VScode. في القسم التالي، سنرى كيفية تعيين وتشغيل كود Python باستخدام VScode وملحق Dev Containers.

ضبط ملحق Dev Containers

لقد قمنا حتى الآن بتغطية أساس Docker. لقد رأينا كيفية تعيين وإنشاء صورة باستخدام Dockerfile وأمر build، على التوالي، ثم تشغيلها في حاوية باستخدام أمر run. سيركز هذا القسم على إعداد بيئة تطوير Python باستخدام VScode وملحق Dev Containers.

إذا كنت لا تزال بحاجة إلى تثبيت ملحق Dev Containers أو Docker Desktop، فاتبع تعليمات التثبيت أعلاه. بمجرد تثبيت الامتداد، من المفترض أن تتوقع رؤية رمز شريط حالة الامتداد (><) في أقصى الجانب الأيسر:

رمز شريط الحالة الخاص بامتداد Dev Containers

إعداد ملف devcontainer.json

يمكّن ملحق Dev Containers من فتح مجلد محلي داخل بيئة حاوية. يؤدي هذا إلى حل مشكلة الحاوية المؤقتة ويمكّنك من الحفاظ على التعليمات البرمجية الخاصة بك محليًا أثناء تطويرها واختبارها داخل الحاوية.

لتعيين ملحق Dev Containers على المجلد المحلي الخاص بك، أنشئ مجلدًا باسم .devcontainer وأضف ملف devcontainer.json. بشكل عام، يجب أن يتبع مجلد مشروعك البنية التالية:

.
├── .devcontainer
│   └── devcontainer.json
└── Your Projects Files

يقوم devcontainer.json بتعريف وتخصيص الحاوية وإعدادات VScode، مثل:

  • إعدادات الصورة – تحدد طريقة إنشاء الصورة أو ما إذا كان سيتم سحب طريقة موجودة.
  • إعدادات المشروع مثل الملحقات المطلوب تثبيتها والأوامر المطلوب تنفيذها أثناء وقت تشغيل الحاوية.

لنبدأ بمثال عملي عن طريق ضبط البيئة باستخدام نفس الصورة التي أنشأناها في المثال الأول (على سبيل المثال، rkrispin/vscode-python:ex1). أثناء وقت إطلاق البيئة، يتبع ملحق Dev Containers الإدخالات الموجودة في devcontainer.json ويضبط البيئة وفقًا لذلك:

.devcontainer/devcontainer.json
{
    "name": "Example 3",
    "build":{
        "dockerfile": "Dockerfile",
        "context": "../"
    }, 
    "customizations": {
        "vscode": {
            "extensions": [
                "quarto.quarto",
                "ms-azuretools.vscode-docker",
                "ms-python.python",
                "ms-vscode-remote.remote-containers",
                "yzhang.markdown-all-in-one",
                "redhat.vscode-yaml",
                "ms-toolsai.jupyter",
                "hediet.vscode-drawio"
            ]
        }
    }  
}

ملاحظة: يجب تخزين ملف devcontainer.json ضمن مجلد .devcontainer أو في المجلد الجذر للمشروع. لتشغيل المثال أعلاه، سيتعين عليك فتح المجلد ./examples/exp-3 في VScode كمجلد المشروع باستخدام خيارات File -> Open Folde.

كما ترون في devcontainer.json، يحدد قسم build عملية بناء الصورة. تشير وسيطة dockerfile إلى Dockerfile لاستخدامه في عملية الإنشاء. تحدد وسيطة context مسار نظام الملفات Dockerfile. على الرغم من أننا لا نستخدم حاليًا وسيطة context في وقت الإنشاء، إلا أننا سنرى تطبيقاتها لاحقًا. بالإضافة إلى ذلك، يمكّنك قسم customizations من تخصيص خيارات VScode، مثل الامتدادات المراد تثبيتها، ومترجم Python الافتراضي، والملفات التي سيتم تنفيذها أثناء تشغيل الحاوية.

إطلاق المجلد داخل الحاوية

بمجرد تعيين devcontainer.json، لتشغيل المجلد داخل الحاوية، انتقل إلى الجانب الأيسر السفلي من شاشة VScode وانقر فوق شريط حالة Dev Containers ()><. سيؤدي هذا إلى فتح لوحة أوامر VScode في الجزء العلوي من الشاشة، ومن المفترض أن ترى الأوامر الشائعة لملحق Dev Containers. حدد خيارات Reopen in Container في الحاوية (انظر لقطة الشاشة أدناه):

لوحة أوامر ملحقات Dev Containers

يوضح الفيديو الموالي العملية الكاملة لإطلاق بيئة Python داخل حاوية بملحق Dev Containers:

افتح مجلدًا داخل حاوية بملحق Dev Containers

يركز القسم التالي على تخصيص بيئة بايثون. بيئة بايثون

إعداد بيئة بايثون

في هذا القسم، سنقوم بربط جميع النقاط معًا وبناء بيئة تطوير بايثون باستخدام البنية التالية:

سنبدأ بإعداد الصورة باستخدام الملفات التالية:

قم بإنشاء Dockerfile لتحديد إعدادات البيئة (على سبيل المثال، إصدار Python، الحزم المطلوب تثبيتها، وما إلى ذلك). بالإضافة إلى ذلك، سوف نستخدم الملفات المساعدة التالية:

  • أحب أن أبقي Dockerfile موجزًا قدر الإمكان باستخدام برنامج bash مساعد (install_dependeency.sh) لتثبيت جميع تبعيات البيئة، مثل حزم Debian، وتثبيت بيئة Python وإعدادها باستخدام Conda (أو حل مشابه)، وما إلى ذلك.
  • بالإضافة إلى ذلك، سنستخدم ملف requirements.txt لتحديد قائمة حزم Python التي سيتم تثبيتها في البيئة.

الخطوة التالية هي إعداد ملحق Dev Containers:

  • سنستخدم ملف devcontainer.json لتحديد إعدادات VScode لبيئة التطوير. يتضمن ذلك طريقة build، وقائمة الامتدادات المراد تعيينها، ووحدات التخزين المحلية المراد تحميلها، وتحديد متغيرات البيئة، وما إلى ذلك.
  • بالإضافة إلى ذلك، سوف نستخدم ملف devcontainer.env لتعيين متغيرات البيئة الإضافية. لاحظ أن هذه المتغيرات لا تكون متاحة أثناء وقت الإنشاء ولا يمكن استدعاؤها بواسطة ملف devcontainer.json.

يجب أن يحتوي مجلد .devcontainer على الملفات التالية:

.
├── Dockerfile
├── devcontainer.env
├── devcontainer.json
├── install_dependencies.sh
└── requirements.txt

قبل البدء، دعونا نحدد متطلبات البيئة لدينا:

  • نسخة بايثون 3.10.
  • قم بتثبيت الحزم التالية: pandas v2.0.3 و plotly v5.15.0
  • كوندا لإعداد البيئة الافتراضية.
  • قم بتثبيت الامتدادات التالية:
  • Docker support
  • Python language support
  • Markdown editor
  • Quarto editor
  • YAML language support
  • Jupyter notebook support
  • أخيرًا وليس آخرًا، نود تركيب مجلد محلي لتحميل ملفات CSV.

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

  • ENV_NAME – سنستخدم هذا المتغير لتعيين اسم بيئة Conda ولضبط المسار إلى مترجم Python الافتراضي.
  • PYTHON_VER – قم بتعيين إصدار Python لبيئة conda.
  • CSV_PATH – المسار المحلي لمجلد يحتوي على ملفات CSV.
  • MY_VAR – متغير عام سنستخدمه كمثال لإعداد متغيرات البيئة.

في نظامي التشغيل Mac وLinux، يمكنك استخدام الملف ‎.zshrc لتعيين هذه المتغيرات:

# Setting env variables for VScode
export ENV_NAME=python_tutorial
export PYTHON_VER=3.10
export CSV_PATH=$HOME/Desktop/CSV
export MY_VAR=some_var

بالنسبة لمستخدمي Windows، يمكنك استخدام الأمر setx لمتغيرات البيئة:

setx variable_name "variable_value"

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

إعداد الصورة

سنستخدم Dockerfile أدناه لبناء بيئة Python الخاصة بنا:

FROM python:3.10

# Arguments
ARG PYTHON_VER
ARG ENV_NAME

# Environment variables
ENV ENV_NAME=$ENV_NAME
ENV PYTHON_VER=$PYTHON_VER

# Copy files
RUN mkdir requirements
COPY requirements.txt requirements/
COPY install_dependencies.sh requirements/

# Install dependencies
RUN bash requirements/install_dependencies.sh $ENV_NAME $PYTHON_VER

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

يتيح لنا استخدام الوسائط تحديد معلمات إعدادات البيئة الخاصة بنا. في هذه الحالة، يمكن للمستخدم تعديل إصدار Python واسم البيئة باستخدام الوسيطتين PYTHON_VER و ENV_NAME. ثم أقوم بتعيين هذه الوسائط كمتغيرات البيئة للراحة (تبقى متاحة بعد الإنشاء).

أخيرًا وليس آخرًا، نقوم بإنشاء مجلد محلي ((requirements) داخل الصورة ونسخ الملفات من محرك الأقراص المحلي الخاص بنا بناءً على المسار الذي تم تحديده بواسطة وسيطة السياق في ملف devcontainer.json. يعد install_dependeency.sh برنامج bash مساعد يقوم بتثبيت التبعيات (conda وvim وما إلى ذلك)، ويضبط بيئة conda، ويثبت حزم Python باستخدام القائمة الموجودة في ملف requirements.txt.

أثناء قيامنا بضبط بيئة Python باستخدام conda، يمكنك تعديل البرنامج النصي أدناه إلى بدائل أخرى مثل venv و Poetry في البرنامج النصي أدناه:

#!/bin/bash

CONDA_ENV=$1
PYTHON_VER=$2
CPU=$(uname -m)


# Installing prerequisites
apt-get update && \
    apt-get install -y \
    python3-launchpadlib \
    vim \
    && apt update 


# Install miniconda
apt update && apt-get install -y --no-install-recommends \
    software-properties-common \
    && add-apt-repository -y ppa:deadsnakes/ppa \
    && apt update 

wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-${CPU}.sh -O ~/miniconda.sh \
    && /bin/bash ~/miniconda.sh -b -p /opt/conda \
    && export PATH=/opt/conda/bin:$PATH \
    && conda init bash \
    && conda install conda-build

# Set environment
. /root/.bashrc \
    && conda create -y --name $CONDA_ENV python=$PYTHON_VER 

echo "conda activate $CONDA_ENV" >> ~/.bashrc

conda activate $CONDA_ENV

# Install the Python packages
pip3 install -r requirements/requirements.txt

ملاحظة: نستخدم الأمر uname -m لاستخراج بنية وحدة المعالجة المركزية (على سبيل المثال، Intel، M1/2، وما إلى ذلك) واختيار بنية conda وفقًا لذلك.

سنقوم بتعيين الحزم المطلوبة لبيئة بايثون باستخدام ملف requirements.txt:

wheel==0.40.0
pandas==2.0.3
plotly==5.15.0
plotly-express==0.4.1

إعداد ملف devcontainer.json

بمجرد تعيين الصورة، فإن الخطوة التالية هي تعيين ملف devcontainer.json. لقد قمنا بدمج متغيرات البيئة في الإعدادات التالية لتمكين الإنشاء السلس لبيئات متعددة:

{
    "name": "${localEnv:ENV_NAME}",
    "build": {
        "dockerfile": "Dockerfile",
        "args": {"ENV_NAME": "${localEnv:ENV_NAME}",
                 "PYTHON_VER": "${localEnv:PYTHON_VER}"}, 
        "context": "."
    },
    "customizations": {
        "settings": {
            "python.defaultInterpreterPath": "/opt/conda/envs/${localEnv:ENV_NAME}/bin/python"
        },
        "vscode": {
            "extensions": [
                "quarto.quarto",
                "ms-azuretools.vscode-docker",
                "ms-python.python",
                "ms-vscode-remote.remote-containers",
                "yzhang.markdown-all-in-one",
                "redhat.vscode-yaml",
                "ms-toolsai.jupyter"
            ]
        }
    },

    "mounts": [
            "source=${localEnv:CSV_PATH},target=/home/csv,type=bind,consistency=cache"
    ],
    "remoteEnv": {
        "MY_VAR": "${localEnv:MY_VAR}"
    },
    "runArgs": ["--env-file",".devcontainer/devcontainer.env"],
    "postCreateCommand": "python3 tests/test1.py"
}

بالنسبة للإنشاء، نستخدم dockerfile و args و context لتحديد Dockerfile والوسائط (على سبيل المثال، إصدار Python واسم البيئة) أثناء الإنشاء، على التوالي.

نستخدم الوسيطة python.defaultInterpreterPath لتعيين مسار مترجم Python الافتراضي إلى بيئة conda التي قمنا بتعيينها أثناء الإنشاء.

باستخدام الوسيطة mounts، نقوم بتركيب مجلد محلي (خارج المجلد الحالي) بمسار داخل الحاوية (على سبيل المثال، home/csv). بشكل عام، يمكنك استخدام هذا الخيار عندما ترغب في تحميل ملف أو بيانات من مجلد خارج مجلد العمل الخاص بك أو إجراء الفصل بين بياناتك والتعليمات البرمجية. في هذه الحالة، يحدد متغير البيئة CSV_PATH مسار المجلد المحلي.

يمكّن RemoteEnv من ضبط متغيرات البيئة باستخدام الحاوية. وبدلاً من ذلك، يمكنك إضافة ملف .env مع قائمة متغيرات البيئة باستخدام الوسيطة runArgs.

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

import pandas as pd
import plotly as py
import plotly.express as px

print("Hello World!")

هذا كل شيء! نحن على استعداد لإطلاق البيئة بامتداد Dev Containers:

قم بتشغيل بيئة Python بامتداد Dev Containers

تناول هذا الدليل أسس إعداد بيئة تطوير dockerized لـ Python باستخدام VScode وDocker. لقد قمنا بمراجعة عملية إعداد بيئة Python باستخدام ملحق Dev Containers. على الرغم من أن هذا الدليل لا يركز على Docker، إلا أنه يغطي أساسياته بهدف تقليل حاجز الدخول للمستخدمين الجدد. بالإضافة إلى ذلك، رأينا كيفية إعداد وإطلاق بيئة تطوير Python داخل حاوية باستخدام ملحق Dev Containers.

يتيح لنا استخدام متغيرات البيئة تحديد معايير البيئة وتعديلها وتقدير تكلفتها بسلاسة. يستخدم المثال أعلاه conda لتعيين بيئة Python ولكن يمكنك اختيار أي طريقة أخرى تناسب احتياجاتك بشكل أفضل.

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

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

اكتشاف المزيد من بايثون العربي

اشترك الآن للاستمرار في القراءة والحصول على حق الوصول إلى الأرشيف الكامل.

Continue reading

Scroll to Top