שימוש בהוראות ENTRYPOINT ו-CMD בקובץ ה-Dockerfile

אם אי פעם נדרשת לך להפעיל פקודה או שתיים בתוך הקונטיינר שלך בהפעלה, המדריך הזה בשבילך. באמצעות ההוראות Dockerfile ENTRYPOINT ו־CMD, ניתן להריץ כמה פקודות התחלה כמו שתרצה.

במדריך זה, תלמד איך להשתמש בהוראות ENTRYPOINT ו־CMD כדי להריץ פקודות התחלה ב־Dockerfile ולהבין את ההבדלים ביניהם.

דרישות מוקדמות

מאחר שהמדריך הזה יהיה מצגת פרקטית, וודא שיש לך את הדברים הבאים במקום:

  • A Windows 10 PC – Windows 10 v10.0.19042 was used in this tutorial.
  • Docker Desktop – המדריך הזה משתמש ב־Docker Desktop גרסה 3.3.1.

יצירת Dockerfile

לפני שתוכל להריץ פקודות התחלה של קונטיינר Docker, עליך תחילה ליצור Dockerfile. Dockerfile הוא מסמך טקסט המכיל רשימה של פקודות לבניית קונטיינרים, תמונות Docker ומגדיר כיצד נוצרת תמונת Docker.

1. ראשית, פתח PowerShell כמנהל.

2. צור תיקייה חדשה לאחסון קובץ Dockerfile וכל הקבצים הקשורים שישמשו במדריך זה והחלף אליה. במדריך זה משתמשים ב־~/docker.

mkdir ~/docker
cd docker

3. עכשיו, צור קובץ טקסט ריק בשם Dockerfile בעזרת הפקודה הבאה.

cd > Dockerfile

באופן אלטרנטיבי, תוכל ליצור Dockerfile עם הפקודה הבאה אם אתה במערכת הפעלה Linux או Mac OS.

touch Dockerfile

4. לבסוף, הוסף את התוכן הבא לתוך ה־Dockerfile.

FROM ubuntu:20.04

כעת יש לך קובץ Dockerfile שהוא בדרך להיות קיים!

בניית תמונת Docker

עכשיו שיצרת את קובץ ה־Dockerfile שלך, עליך לבנות תמונת Docker כדי להריץ את הפקודות שנכתבו בהוראות ה־ENTRYPOINT ו־CMD של Dockerfile שלך. אחת הדרכים לבנות תמונה היא על ידי שימוש ב־build command.

כאשר אתה נמצא בתיקיית ~/docker, הרץ את הפקודה הבאה. הפקודה למטה יוצרת תמונת Docker בשם demo (-t demo) מתוך קובץ ה־Dockerfile ב־~/docker על ידי ציון תיקיית העבודה הנוכחית (.).

docker build -t demo .
Building a Docker Image

הרצת תכונת Docker

לאחר שבנית את תמונת ה־Docker, תצטרך תוכנית לריץ את תמונת ה־Docker שתבצע את הפקודות מהוראות ה־ENTRYPOINT ו־CMD של Dockerfile.

להריץ תכולת Docker container, הפעל את פקודת run כדי ליצור שכבת כתיבה שעל התמונה של Docker (demo). הדוגמה למטה משתמשת בפרמטר -it כדי להתחבר באופן אינטראקטיבי לתוך ה-container כך שתוכל לראות את הפלט הדוגמתי.

docker run -it demo
Running a Docker Container

צורת Exec מול צורת Shell

כאשר אתה מתחיל לעבוד עם Dockerfile ומבין איך להריץ פקודות התחלה, ייתכן שתתקל בשני שיטות שונות להגדרת הפקודות הללו. כל שיטה תפעל פקודות, אך תעשה זאת בדרך קצת שונה.

כאשר Docker מפעיל פקודות, הוא יכול לעשות זאת ישירות באמצעות exec או לעבור דרך של סורק ה-container (/bin/sh -c ב-Linux או cmd /S /C ב-Windows) שנקרא shell.

תשימו לב שפקודות שנפעלות באמצעות exec מכילות הוראה שעוקבת אחריה התוכניות להפעלה ואז אחת או יותר מקרים לפקודת שורת פקודה, כפי שמוצג למטה.

ENTRYPOINT ["executables", "parameter1", "parameter2", ...]
CMD ["executables", "parameter1", "parameter2:, ...]

כתיבת פקודות בצורת shell, מצד שני, אינה דורשת עטיפת הפקודות בסוגריים מרובעים, כפי שמוצג למטה.

ENTRYPOINT <command> "parameter1"
CMD <command> "parameter1"

אם אינך מפרט פרמטר ל- CMD, Docker תמיד תבצע את הפקודה בצורת exec, לדוגמה CMD <פקודה>.

אם אתה מתחיל רק, ההבדל בין שתי ההפעלות של הפקודות האלו לא יהיה חשוב כל כך אך ככל שתתקדם יותר, בטומן מהירויות וחסרונות לכל אחת מהן.

הרצת פקודות התחלה

בואו נכנס עכשיו לתוכן העיקרי של המדריך ונתחיל לעבוד על ידי הליכה דרך מספר דוגמאות של הרצת פקודות הפעלה בתוך קובץ Dockerfile ENTRYPOINT וההוראות CMD.

1. פתחו את קובץ ה-Dockerfile שיצרתם בקודעם העדיף שלכם.

2. העתיקו והדביקו את תוכן דוגמת ה-Dockerfile לתוך קובץ ה-Dockerfile שלכם, כפי שמוצג למטה, ושמרו אותו.

קובץ ה-Dockerfile הזה יוצר שכבה באמצעות התמונה הבסיסית ubuntu:20.04. לאחר מכן הוא אומר ל-Docker להפעיל את פקודת ה-echo ולהעביר לה את הארגומנט Hello world עבור שתי ההוראות CMD ו-ENTRYPOINT ב-Dockerfile באמצעות צורת exec ו-shell.

FROM ubuntu:20.04
# הוראת CMD
CMD ["echo", "Hello world"] # Exec Form
CMD echo "Hello world"      # Shell Form
# הוראת ENTRYPOINT
ENTRYPOINT ["echo", "Hello world"] # Exec Form
ENTRYPOINT echo "Hello world"      # Shell Form

3. בעודכם בתיקיית ~/docker, בנו את התמונה החדשה על ידי הרצת docker build ותנו לה שם demo. הפקודה למטה מסמנת את התמונה בשם demo ומחפשת את קובץ ה-Dockerfile בתיקיית העבודה הנוכחית (.).

docker build -t demo .
Building a Docker image with docker build

4. כעת, הריצו תוכן באמצעות התמונה ואז הריצו תוכן בהתבסס על התמונה שנוצרה קודם. תראו כעת שהתוצאה מחזירה Hello world שבא מההוראת CMD שסופקה ב-Dockerfile.

docker run -it demo
Running a Docker container with docker run

שימוש במשתנים בקובץ Dockerfile

לפעמים אולי לא תדע את הארגומנטים המדויקים לשורת הפקודה שצריך להעביר לפקודה מראש. הארגומנטים שאתה צריך להעביר לפקודה נחשפים רק בזמן ריצה. במקום להקצות ארגומנטים לפקודה באופן סטטי, תוכל ללכוד ולהעביר את הארגומנטים הללו לפקודות באמצעות משתנים.

ניתן להשתמש במשתני Dockerfile רק בצורת shell. Docker לא תומך במשתנים בפקודה שנקראת דרך exec.

פתח את ה-Dockerfile שוב בעורך הטקסט המועדף עליך, החלף הכל בתוך זה בסדרת הפקודות הבאה ושמור אותו.

תשים לב הפעם, ה-Dockerfile משתמש במשתני סביבה ומראה אותם באמצעות ENV. בדוגמה למטה, ה-Dockerfile מגדיר משתנה סביבה בשם name עם ערך של friend. לאחר יצירתו, משתנה סביבה זה מתייחס אז דרך $name.

כאשר Docker מריץ קונטיינר מבוסס על ה-Dockerfile הזה, הוא יקרא לפקודת echo ויעביר את הארגומנט Welcome, friend.

FROM ubuntu:20.04
ENV name friend

CMD echo "Welcome, $name"
# או
## ENTRYPOINT echo "Welcome, $name"

עכשיו, צור את תמונת ה-Docker והרץ את הקונטיינר שוב באופציה לספק שם תג של shellform. תשים לב ש-Docker קרא לפקודת echo והחזיר את הפלט המצופה.

Building a Docker Image (shellform) and Running a Docker Container

שילוב הוראות ENTRYPOINT ו-CMD של Dockerfile

**ברוב הזמן, יש לך צורך להפעיל פקודות התחלה ב- CMD או בהוראת ENTRYPOINT. לבסוף, תוכל להפעיל כמה פקודות כפי שתרצה באמצעות כל אחת מהשיטות. אבל יש גם את האפשרות להפעיל פקודה יחידה ו"לבנות עליה" באמצעות שני ההוראות.**

**מבוסס על הדוגמאות הקודמות, אולי יש לך Dockerfile שנראה כמו הדוגמה למטה. כפי שהוא כרגע, אם תיצור תמונה ותריץ קונטיינר מתוך התמונה, Docker יפעיל את הפקודה echo ויחזיר Hello.**

FROM ubuntu:20.04
ENTRYPOINT ["echo", "Hello"]

**ייתכן ויש לך ערך נוסף שתרצה להעביר לפקודה echo אך לא מיד. אולי תרצה לעשות זאת באמצעות הקובץ Dockerfile למטה. באמצעות הפעלת ההוראה CMD ללא פקודה, תוכל לעשות זאת.**

**כאשר אתה מציין פקודה להפעלה דרך ההוראה ENTRYPOINT באמצעות ההוראה CMD שאחריה, Docker מניח באופן אוטומטי שהערך שמועבר ל- CMD הוא ארגומנט ולא פקודה.**

**עכשיו, הוסף הפניה להוראת CMD ללא פקודה, אלא רק ארגומנט בשם world, כפי שמוצג למטה.**

FROM ubuntu:20.04
ENTRYPOINT ["echo", "Hello"]
CMD ["world"]

**הוראות משולבות תמיד יש לכתוב בפורמט exec עקבי לגורמן התנהגות "דומה למערך" של הגדרת ערכים יחידים מופרדים בפסיקים לעומת כתיבה במחרוזת אחת.**

**לאחר בניית התמונה והרצת הקונטיינר מתוך התמונה, תוכל לראות שבמקום שני שורות פלט (Hello ו-world), Docker מחזיר רק שורה אחת, הוא יפעיל פקודת echo יחידה בלבד.**

Building a Docker Image (demo3) and Running a Docker Container

**מסקנה**

אתה צריך כעת להבין טוב איך להריץ פקודות התחלה של קונטיינרים של Docker דרך ההוראות של CMD ו- ENTRYPOINT בקובץ Dockerfile. כל הוראה קצת שונה אך מבצעת את אותה המשימה ואפשר גם להשתמש בהן ביחד.

האם תוכל לחשוב על תרחיש שבו תעדיף להשתמש ב- CMD על פני ENTRYPOINT כדי להריץ פקודת התחלה?

Source:
https://adamtheautomator.com/dockerfile-entrypoint/