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

הקדמה

שאנחנו מדברים על Image-ים, אנו צריכים להבין קודם כל מה הם כוללים. Image הוא קובץ אשר מהווה Snapshot של מערכת ההפעלה והתוכנות או השירותים שמותקנים בה.

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

נכון לתאריך כתיבת המאמר, ישנם קרוב ל-10 מיליון 😳 קבצי Image רשומים ב-Docker Hub. כיום יש כמעט לכל שירות או סיפרייה קובץ Image אפשר מאפשר לנו להריץ את אותו שירות בבידוד מוחלט ממערכת ההפעלה של המחשב שלנו.
ניתן להריץ שירותים כמו שרת MySQL, שרת TeamSpeak, שרת Enemy Territory ואפילו את Docker בתוך Docker 🤯.

שימוש ב-Dockerfile

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

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

דוגמא פרקטית 💪

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

בתור התחלה ניצור קובץ אשר נקרא Dockerfile, ונכניס בו את הקוד הבא:

FROM php:7.4-fpm
RUN apt-get update && \
    apt-get -y install libmagickwand-dev && \
    pecl install imagick && \
	docker-php-ext-enable imagick
COPY . /usr/src/hello-world
WORKDIR /usr/src/hello-world
CMD ["php", "./app/index.php"]

בתור התחלה אנו מנחים את Docker להשתמש ב-Image של PHP גרסה 7.4 בתור בסיס. לאחר מכן אנו מגדירים לעדכן את מערכת ההפעלה ולהתקין את ImageMagick ולהפעיל אותו. בנוסף אנו מגדירים לו להעתיק את הקוד של האפליקציה שלנו ולבסוף להריץ את הקובץ הראשי של האפליקציה שלנו.

בנוסף, לצורך התרגול ניצור קובץ PHP עם השם index.php תחת תיקיית app עם הקוד הבא:

<?php
echo "Hello World!";

כעת עלינו להנחות את Docker לבנות את ה-Image המיוחד שלנו, נעשה זאת ע״י הרצת הפקודה הבאה כאשר אנו נמצאים בתיקייה בה קיים הקובץ Dockerfile אותו יצרנו.

docker build -t my-app .

ברגע שנריץ את הפקודה נראה שיתחילו להופיע מספר שורות אשר מציינות את הורדת ה-Image של PHP ואז את ההתקדמות של תהליך הבנייה של ה-Image.

לבסוף על מנת להריץ את ה-Image שיצרנו נריץ את הפקודה הבאה:

docker run -it --rm --name hello-world my-app

בהנחה והכל עובר חלק אנו נראה את ההודעה Hello World! בטרמינל 👇.

צילום מסך של הטרמינל המציג את תוצאת הרצת ה-Image שלנו שנבנה עם Dockerfile

מילות מפתח ב-Dockerfile

בדוגמא הנ״ל ראינו שימוש במספר מילות מפתח אשר מתורגמות לפקודות אותן Docker צריך לבצע כאשר הוא בונה את ה-Image שלנו. ישנן מספר מילות מפתח אשר לכל אחת יכולת אחרת, הנפוצות הן:

מילת מפתחתיאור
FROMהשם של ה-Image אשר עליו נרצה להתבסס, לרוב ניתן גם להגדיר איזה גרסה אנו רוצים ע״י הפורמט name:version.
RUNהרצה של פקודה אחת או יותר ב-Shell של מערכת ההפעלה הקיימת ב-Image עליו אנו מתבססים.
COPYהעתקה של קובץ או תיקייה מהמחשב שלנו ל-File System של מערכת ההפעלה הקיימת ב-Image.
ENVהגדרה של משתנה סביבה כלשהו אשר יהיה שמיש בקוד אשר ירוץ בתוך ה-Image או כחלק מתהליך ה-Build.
WORKDIRהגדרת נתיב לתיקייה מסויימת ב-Image אשר תשמש ״כתיקיית העבודה״.

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

סיכום

שימוש ב-Dockerfile הינו כלי מאוד חזק כאשר אנו רוצים להתאים את ״סביבת העבודה״ של האפליקצייה או המערכת שלנו למה שאנחנו באמת צריכים. ע״י שימוש בקובץ זה אנו יכולים להוסיף, לשנות ואף ולהסיר תכונות או ספריות מסויימות מ-Image עליו אנו מתבססים.

בחלק הבא של הסדרה נדבר על Docker Compose ואיך הוא מקל עלינו בעבודה השוטפת.

    כתיבת תגובה

    1. יובל

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

      הגב
      1. דור צוברי

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

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

    שתפו