تطوير الحاويات باستخدام ملفات Dockerfiles

1. نظرة عامة

Docker هو نظام أساسي مفتوح لتطوير التطبيقات وشحنها وتشغيلها. باستخدام Docker، يمكنك فصل التطبيقات عن البنية الأساسية والتعامل مع البنية الأساسية كتطبيق مُدار. تساعدك Docker على شحن الرموز بشكل أسرع واختبارها ونشرها بشكل أسرع وتقصير الدورة بين كتابة الرمز وتشغيل الرمز.

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

يمكن استخدام حاويات Docker مباشرةً في Kubernetes، ما يتيح تشغيلها في Kubernetes Engine بسهولة. بعد تعلّم أساسيات Docker، ستتوفر لديك مجموعة المهارات اللازمة للبدء في تطوير Kubernetes وتطبيقات حاويات.

ما ستتعرَّف عليه

ستتعلم في هذا التمرين المعملي كيفية القيام بما يلي:

  • إنشاء ملف Dockerfile لنموذج تطبيق
  • إنشاء صورة
  • تشغيل الصورة كحاوية محليًا
  • تغيير سلوك الحاوية
  • إرسال الصورة إلى Artifact Registry

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

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

إعداد بيئة ذاتية

  1. سجِّل الدخول إلى Google Cloud Console وأنشئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. إذا لم يكن لديك حساب على Gmail أو Google Workspace، عليك إنشاء حساب.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • اسم المشروع هو الاسم المعروض للمشاركين في هذا المشروع. وهي عبارة عن سلسلة أحرف لا تستخدمها Google APIs، ويمكنك تحديثها في أي وقت.
  • يجب أن يكون رقم تعريف المشروع فريدًا في جميع مشاريع Google Cloud وغير قابل للتغيير (لا يمكن تغييره بعد ضبطه). تنشئ Cloud Console سلسلة فريدة تلقائيًا. فعادةً لا تهتم بما هو. في معظم الدروس التطبيقية حول الترميز، يجب الرجوع إلى رقم تعريف المشروع (والذي يتم تحديده عادةً على أنّه PROJECT_ID). لذلك، إذا لم يعجبك، يمكنك إنشاء رقم تعريف عشوائي آخر أو يمكنك تجربة رقم تعريف المشروع الخاص بك ومعرفة ما إذا كان متاحًا. بعد ذلك تكون الحالة "مجمّدة". بعد إنشاء المشروع.
  • هناك قيمة ثالثة، وهي رقم المشروع الذي تستخدمه بعض واجهات برمجة التطبيقات. اطّلِع على مزيد من المعلومات حول هذه القيم الثلاث في المستندات.
  1. بعد ذلك، عليك تفعيل الفوترة في Cloud Console لاستخدام الموارد/واجهات برمجة التطبيقات في Cloud. إنّ تنفيذ هذا الدرس التطبيقي حول الترميز لن يكون مكلفًا أو مكلفًا على الإطلاق. لإيقاف تشغيل الموارد حتى لا تتحمل الفوترة بعد أكثر من هذا البرنامج التعليمي، اتبع أي عملية "تنظيف". التعليمات الموجودة في نهاية الدرس التطبيقي حول الترميز. يكون مستخدمو Google Cloud الجدد مؤهَّلون للانضمام إلى برنامج فترة تجريبية مجانية بقيمة 300 دولار أمريكي.

2. تطبيق نموذجي

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

رمز المصدر

يتوفّر رمز المصدر لهذا الدرس التطبيقي في مستودع GoogleCloudPlatform/container-developer-workshop إلى جانب نموذج مستندات التطبيقات.

ضبط git

git config --global user.name ${USER}
git config --global user.email ${USER}@qwiklabs.net

استنساخ نموذج مستودع مصدر السحابة الإلكترونية للتطبيق

gcloud source repos clone sample-app ${HOME}/sample-app &&
cd ${HOME}/sample-app &&
git checkout main

الناتج

Cloning into '/home/student_03_49720296e995/sample-app'...
remote: Finding sources: 100% (16/16)
remote: Total 16 (delta 0), reused 16 (delta 0)
Receiving objects: 100% (16/16), 47.23 KiB | 681.00 KiB/s, done.
warning: remote HEAD refers to nonexistent ref, unable to checkout.

Project [qwiklabs-gcp-02-4327c4e03d82] repository [sample-app] was cloned to [/home/student_03_49720296e995/sample-app].
Branch 'main' set up to track remote branch 'main' from 'origin'.
Switched to a new branch 'main'

إنشاء نموذج التطبيق

cd ${HOME}/sample-app
./mvnw compile

الناتج

[INFO] Scanning for projects...
...
[INFO] Compiling 1 source file to /home/student_03_49720296e995/sample-app/target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  10.080 s
[INFO] Finished at: 2022-02-23T17:14:30Z
[INFO] ------------------------------------------------------------------------

تشغيل نموذج التطبيق

cd ${HOME}/sample-app
./mvnw exec:java

الناتج

[INFO] Scanning for projects...
...
Listening at http://localhost:8080

معاينة التطبيق قيد التشغيل

  • انقر على زر معاينة الويب في Cloud Shell
  • النقر على "معاينة" في المنفذ 8080

عند الانتهاء

  • اضغط على CTRL + c في Cloud Shell لإيقاف التطبيق قيد التشغيل.

3- ملف شامل

إحاطة التطبيق باستخدام ملف Dockerfile

تتمثل إحدى طرق تجميع تطبيق في حاوية باستخدام ملف Dockerfile. يشبه ملف Dockerfile نصًا برمجيًا يوجه البرنامج الخفي إلى كيفية تجميع صورة الحاوية. اطّلِع على المستندات المرجعية لملفات Dockerfile) للحصول على المزيد من المعلومات.

إنشاء ملف Dockerfile فارغ في نموذج مستودع التطبيقات.

touch ${HOME}/sample-app/Dockerfile

افتح الملف الشامل في المحرِّر الذي تختاره.

vi ${HOME}/sample-app/Dockerfile

اختيار صورة البداية

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

تبدأ تعليمات FROM مرحلة إنشاء جديدة وتضبط الصورة الأساسية للأوامر التسلسلية اللاحقة. وبالتالي، تكون تعليمات FROM عادةً أول تعليمات في الملف الشامل ولا يمكن أن يسبقها سوى تعليمات ARG اختيارية لإتاحة المتغيّرات.

البنية: FROM <image>[:<tag> | @<digest>] [AS <name>]

تنسيق الصورة هو <image>:<tag> أو <image>@<digest>. في حال عدم تحديد علامة أو ملخّص، سيتم ضبطه تلقائيًا على العلامة :latest. يختلف تنسيق <image> حسب قاعدة بيانات المسجّلين المستخدمة لتخزين الصورة. بالنسبة إلى Artifact Registry، يكون تنسيق <image> هو <region>-docker.pkg.dev/<project ID>/<repository name>/<image name>:<image tag>.

في هذا التمرين، نستخدم صورة openjdk:11.0-jdk العلنية، ثم أضِف السطر التالي إلى ملف Dockerfile.

FROM openjdk:11.0-jdk

ضبط دليل العمل

تضبط تعليمات WORKDIR دليل العمل لأي تعليمات تسلسلية تتبعها في الملف الشامل. لمزيد من المعلومات، راجِع قسم WORKDIR في المستندات المرجعية لملفات Docker.

البنية: WORKDIR <path>

في هذا التمرين المعملي، نستخدم دليل /app بوصفه WORKDIR، ثم نضيف السطر التالي إلى أسفل ملف Dockerfile.

WORKDIR /app

نسخ ملفات التطبيق

تنسخ تعليمات COPY الأدلّة أو الملفات من موقع <source> إلى المسار <destination> في نظام ملفات الصور. يمكن تحديد موارد <source> متعددة، وجميعها ذات صلة بسياق الإصدار. ستتم مناقشة سياق الإصدار بمزيد من التفصيل في قسم "الإصدار". لمزيد من المعلومات، راجِع قسم "النسخ" في المستندات المرجعية لملف Docker.

البنية: COPY <source>... <destination>

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

COPY . /app

تجميع التطبيق

تُنفِّذ تعليمات RUN الأوامر في طبقة صورة جديدة أعلى الصورة الحالية وتنفّذ النتائج. سيتم استخدام الصورة الملتزمة الناتجة في الخطوات المتسلسلة في ملف Dockerfile. لمزيد من المعلومات، راجِع قسم "تشغيل" في المستندات المرجعية لملف Docker.

البنية: RUN <command>

في هذا التمرين المعملي، سنستخدم Maven لتجميع التطبيق في ملف JAR، وإضافة السطر التالي إلى أسفل ملف Dockerfile.

RUN ./mvnw compile assembly:single

تشغيل التطبيق

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

البنية: CMD ["executable","param1","param2"]

في هذا التمرين المعملي، نقوم بتشغيل ملف JAR الذي جمعناه، ونضيف السطر التالي إلى أسفل ملف Dockerfile.

CMD ["java","-jar","/app/target/sample-app-1.0.0-jar-with-dependencies.jar"]

الملف الشامل النهائي

سيتم إنشاء الملف الشامل النهائي

FROM openjdk:11.0-jdk
WORKDIR /app
COPY . /app
RUN ./mvnw compile assembly:single
CMD ["java","-jar","/app/target/sample-app-1.0.0-jar-with-dependencies.jar"]

إكمال الملف الشامل محليًا

cd ${HOME}/sample-app
git add Dockerfile
git commit -m "Added Dockerfile"

4. إنشاء

سننشئ الآن الصورة من ملف Dockerfile باستخدام الأمر docker build. يوجه هذا الأمر البرنامج الخفي لـ Docker لإنشاء الصورة باستخدام التعليمات الواردة من ملف Dockerfile. للحصول على المزيد من المعلومات، يمكنك الاطّلاع على المستندات المرجعية لإصدار Docker.

إنشاء الصورة

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker build --tag sample-app:${IMAGE_TAG} .

الناتج

Sending build context to Docker daemon  221.2kB
Step 1/4 : FROM openjdk:11.0-jdk
11.0-jdk: Pulling from library/openjdk
0c6b8ff8c37e: Pull complete
412caad352a3: Pull complete
e6d3e61f7a50: Pull complete
461bb1d8c517: Pull complete
e442ee9d8dd9: Pull complete
542c9fe4a7ba: Pull complete
41de18d1833d: Pull complete
Digest: sha256:d72b1b9e94e07278649d91c635e34737ae8f181c191b771bde6816f9bb4bd08a
Status: Downloaded newer image for openjdk:11.0-jdk
---> 2924126f1829
Step 2/4 : WORKDIR /app
---> Running in ea037abb273d
Removing intermediate container ea037abb273d
---> bd9b6d078082
Step 3/4 : COPY . /app
---> b9aec2b5de51
Step 4/4 : RUN ./mvnw compile jar:jar
---> Running in 3f5ff737b7fd
[INFO] Scanning for projects...
...
[INFO] Building jar: /app/target/sample-app-1.0.0.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  22.952 s
[INFO] Finished at: 2022-02-23T18:09:08Z
[INFO] ------------------------------------------------------------------------
Removing intermediate container 331443caebd3
---> 152f65cc441e
Step 5/5 : CMD ["java", "-jar", "/app/target/sample-app-1.0.0.jar"]
---> Running in 3d595a72231c
Removing intermediate container 3d595a72231c
---> 0e40d7548cab
Successfully built 0e40d7548cab
Successfully tagged sample-app:aaa8895

5- تشغيل

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

تشغيل حاوية باستخدام الصورة

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker run \
  --rm \
  -p 8080:8080 \
  sample-app:${IMAGE_TAG}

الناتج

Listening at http://localhost:8080

معاينة التطبيق الذي يتم تشغيله في الحاوية

  • انقر على زر معاينة الويب في Cloud Shell
  • النقر على "معاينة" في المنفذ 8080
  • اضغط على CTRL + c في Cloud Shell لإيقاف الحاويات.

تغيير سلوك الحاوية

يستخدم تنفيذ Docker Run الإعدادات التلقائية في ملف Dockerfile. يمكن إضافة تعليمات ومَعلمات إضافية لتعديل هذا السلوك.

تفعيل تسجيل TRACE

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker run \
  --rm \
  -p 8080:8080 \
  sample-app:${IMAGE_TAG} \
  java -Dorg.slf4j.simpleLogger.defaultLogLevel=trace -jar /app/target/sample-app-1.0.0-jar-with-dependencies.jar

معاينة التطبيق الذي يتم تشغيله في الحاوية

  • انقر على زر معاينة الويب في Cloud Shell
  • النقر على "معاينة" في المنفذ 8080
  • انتقِل إلى علامة تبويب Cloud Shell واطّلِع على هذا التسجيل الإضافي
  • اضغط على CTRL + c في Cloud Shell لإيقاف الحاوية.

تغيير المنفذ

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker run \
--rm \
-e PORT=8081 \
-p 8081:8081 \
sample-app:${IMAGE_TAG}

معاينة التطبيق الذي يتم تشغيله في الحاوية

  • انقر على زر معاينة الويب في Cloud Shell
  • انقر على "تغيير المنفذ".
  • أدخِل الرقم 8081.
  • انقر على "تغيير ومعاينة"
  • اضغط على CTRL + c في Cloud Shell لإيقاف الحاوية.

6- بث

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

دفع الالتزام بـ Dockerfile إلى مستودع نموذج التطبيق

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
git push

وضع علامة على الصورة في Artifact Registry

docker tag sample-app:${IMAGE_TAG} \
    us-central1-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/apps/sample-app:${IMAGE_TAG}

إعداد بيانات الاعتماد لـ Artifact Registry

gcloud auth configure-docker us-central1-docker.pkg.dev

اضغط على Enter عندما يُطلب منك الإجابة "Do you want to continue (Y/n)?": أجب y.

إرسال الصورة إلى Artifact Registry

docker push us-central1-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/apps/sample-app:${IMAGE_TAG}

الناتج

 The push refers to repository [us-central1-docker.pkg.dev/qwiklabs-gcp-04-b47ced695a3c/apps/sample-app]
  453b97f86449: Pushed
  e86791aa0382: Pushed
  d404c7ee0850: Pushed
  fe4f44af763d: Pushed
  7c072cee6a29: Pushed
  1e5fdc3d671c: Pushed
  613ab28cf833: Pushed
  bed676ceab7a: Pushed
  6398d5cccd2c: Pushed
  0b0f2f2f5279: Pushed
  aaa8895: digest: sha256:459de00f86f159cc63f98687f7c9563fd65a2eb9bcc71c23dda3351baf13607a size: 2424

7. تهانينا!

تهانينا، لقد أنهيت الدرس التطبيقي حول الترميز.

المواضيع التي شملتها

  • إنشاء ملف Dockerfile لنموذج تطبيق
  • إنشاء صورة
  • تم تشغيل الصورة كحاوية على الجهاز.
  • تم تغيير سلوك الحاوية
  • تم نقل الصورة إلى Artifact Registry.