✕ סגור 
צור קשר
תודה על ההתעניינות .

Thank you! Your submission has been received!

Oops! Something went wrong while submitting the form

איך להתחיל לעבוד עם דוקר: יצירת קובץ הגדרות (Image)

רן בר זיק
|
קלה
|
Dec 6, 2018
alt="facebook"alt="linkedin"
להרשמה לניוזלטר

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

docker run -d -p 80:80 --name my-apache-php-app -v /c/temp:/var/www/html php:7.0-apache

המחרוזת php:7.0-apache מגיעה מהפצה רשמית של PHP שנמצאת בדוקר. ההפצה הרשמית היא PHP וה’ענף’ הוא 7.0-apache. מה שנמצא מאחורי ההפצה הזו הוא קובץ הגדרות שקובע שעל הקונטיינר להתקין apache למשל, ו-PHP מגרסה 7 ועוד כל מיני דברים. כאמור, אני יכול להסתמך על קובץ הגדרות רשמי ומוכר וזה טוב בדרך כלל לתסריטים פשוטים, או לחלופין, אני יכול ליצור קובץ הגדרות מיוחד שמכיל את ההגדרות שלי. קובץ ההגדרות הזה נקרא image. מה-image הזה אנחנו יוצרים קונטיינרים.

למה שארצה ליצור image משלי? יש מיליון תסריטים – למשל אפליקציה שיש בה גם PHP וגם Python מגרסאות ספציפיות, או מודולים ספציפיים של PHP. אם אני מתחזק אתרים, סביבת הפיתוח צריכה להיות תואמת לסביבת הפרודקשן. לפעמים אני רוצה להרים קונטיינר לצורך מאוד ספציפי שיעשה עבודה אחת מאוד פשוטה. הדוגמה הכי טובה ומעשית שאני יכול לציין היא הרצת static code analysis על קבצי PHP. לא מעט פעמים אני צריך לבדוק תוספים מסוימים שנכתבו ב-PHP ולראות שהם תואמים לסטנדרט והמפתח שפיתח אותם יודע מה הוא עושה. לצורך זה אני צריך להפעיל את PHP code sniffer שההתקנה שלו על מחשב מקומי יכולה להיות מאתגרת. למה לשבור את הראש כשאני יכול להרים קונטיינר מיידי ולהריץ את בדיקת הקוד ממנו?

?מה המטרה

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

?IMAGE איך יוצרים

קל להבין שאני לא יכול להשתמש במשהו רשמי כמו PHP. כלומר זה יהיה הבסיס שלי מן הסתם כי אני צריך קונטיינר שמריץ PHP. אבל אני צריך עוד דברים ובראשם PHPCS, הכלי שבו אני משתמש. הוא נשען על PHP אבל אין לו זכר במאגרים הרשמיים. בשביל להכניס אותו לקונטיינר, אני יכול או להתקין אותו ידנית בכל פעם שאני יוצר קונטיינר מקובץ ‘רשמי’ (רעיון רע) או להכין קובץ הגדרות שפשוט בא ואומר: “קח את הקונטיינר, התקן עליו PHPCS ואולי עוד משהו וזהו”.

על מנת לעשות זאת, אני אצור קובץ שנקרא Dockerfile (עם D גדולה) ואציב אותו בפרויקט שלי. הקובץ הזה הוא סוג של ‘תבנית’ שבתוכו אני יכול להכניס הוראות שונות שיעבדו ממש כאילו אני בתוך המכונה. הנה הדוקר שלי:

FROM php:7-alpine

RUN cd /usr/local/bin \

   && curl -sL http://cs.sensiolabs.org/download/php-cs-fixer-v2.phar -o php-cs-fixer \

   && chmod +x php-cs-fixer \

   && curl -sL https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar -o phpcs \

   && chmod +x phpcs

WORKDIR /app

FROM

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

RUN

זו פקודה שמשמעותה היא הרצה. כל מה שבא אחריה ירוץ. שימו לב שאני משתמש פה בסינטקס של שרשור &&. בלינוקס שרשור זה אומר לבצע את הפקודה שאחרי ה-&& מיד אחרי שקודמתה מסתיימת. אבל זה מקביל ל:

RUN cd /usr/local/bin \

RUN curl -sL http://cs.sensiolabs.org/download/php-cs-fixer-v2.phar -o php-cs-fixer \

RUN chmod +x php-cs-fixer \

RUN curl -sL https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar -o phpcs \

RUN chmod +x phpcs

מקובל בדרך כלל לקשר כל RUN לשורת פקודות שרלוונטיות לנושא. למשל RUN אחד להתקנת ה-PHPCS ו-RUN אחר להתקנת רכיב נוסף כשבכל RUN הפקודות הרלוונטיות לו יהיו משורשרות באמצעות &&. אם זה נשמע לכם כמו סינית אז זה בסדר. רק תזכרו ש-&& זה שרשור (כמו לכתוב, אחרי שההוא מסתיים, תריץ את זה).

WORKDIR

הגדרה של סביבת העבודה. במקרה הזה אני מכוון את הקונטיינר, מייד אחרי שה-phpcs מסתיים להתקנה, להגיע אל תיקית app/

אז בעצם שלוש הפקודות האלו הן פשוטות – FROM אומרת לנו – אתה מתבסס על הגרסה הרשמית של PHP שנקראת php:7-alpine (אותה לקחתי כמובן מהגרסה הרשמית של PHP שיש בדוקר, אבל אני יכול לקחת כל גרסה). פקודת RUN אומרת לנו להריץ שורה של פקודות שמתקינות את PHPCS שאותה לקחתי מהגרסה הרשמית שלהם ולבסוף פקודת WORKDIR מחזירה את הקונטקסט של הקונטיינר לתיקיית app. למה?

נשמור את הקובץ בספריה כלשהי ונמשיך.

אחרי שיצרתי את הקובץ, אני צריך ‘לבנות’ אותו וזה השינוי הגדול ביותר שיש בין שימוש ב-image רשמי ל-Docker file. הבנייה בעצם עוקבת אחר כל ההוראות שיש בקובץ ומריצה אותו. אם הכל מצליח אנחנו יכולים ליצור קונטיינר מה-Image הזה בדיוק כמו כל image רשמי.

:הבניה נעשית כך

docker build -t ran-lint-machine .

הפקודה הראשונה היא docker build שאומרת שאנחנו בונים. הפלאג t- ומה שבא אחריו זה השם. שימו לב שזה חשוב אחרת תצטרכו להשתמש ב-hash של ה-image וזה לא נחמד. הנקודה שיש בסוף היא הנתיב לקובץ ה-docker שאותו ממש הכנו ושמרנו בשם Dockerfile. במקרה הזה אני מריץ את הפקודה ממש מאיפה שהקובץ נמצא.

עכשיו נראה בקונסולה את כל השלבים של ההתקנות. כן! אם יש תקלה כלשהי, נראה אותה וכך נוכל לתקן את הקובץ. אם הכל תקין, נראה את ה-output הבא:

Successfully built c77653df3672

Successfully tagged ran-lint-machine:latest

עכשיו יש לי image שאני יכול להריץ. שמו בישראל יהיה ran-lint-machine. אני יכול לבדוק אותו באמצעות הקלדה של:

docker images --all

אני אקבל רשימה של כל ה-images שהתקנתי אי פעם, כל הרשמיים וביניהם אחד קטן וחביב שיצרתי עכשיו ששמו הוא ran-lint-machine.

עכשיו כשיש לי את שם ה-image אני יכול להשתמש בו באופן הזה:

docker run --rm -it -v /c/Users/barzik/test-docker:/app/ ran-lint-machine phpcs PATH/TO/PHP/FILES/

docker run -it -v PATH/TO/PHP/FILES/:/app/ --rm ran-lint-machine phpcs .

את docker run -it אנחנו מכירים, זו הרצה שלו.

החלק הכי חשוב הוא v-. במאמר הפתיחה על docker כתבתי שהוא עוזר לנו לקשר בין המערכת שלנו לקונטיינר. במקרה הזה הוא קובע מה תיקיית app תהיה! אני אקשר בין התיקייה שבה יש את קבצי ה-PHP ל-app שהוא, כפי שאני קבעתי, תיקיית העבודה המרכזית.

פלאג rm– אומר למחוק את הקונטיינר מיד אחרי ההרצה. כיוון שמדובר בהרצה חד פעמית שלו.

שם ה-image שאותו קבעתי הוא כמובן ran-lint-machine והוא נקבע בתהליך ה-build.

ולבסוף, השורה שמריצה את phpcs ונקודה. כי אני מריץ את phpcs בתיקיה של apps שמקושרת לתיקיה שמכילה את קבצי ה-PHP.

ואם הכל יעבוד כמו שצריך, זה מה שאני אראה:

הרצה מוצלחת של PHPCS דרך דוקר על קבצים מקומיים

זה הבסיס אבל תראו כמה זה קל! במאמר הבא נעמיק מעט לתוך קובץ ה-Dockerfile.

מאת: רן בר זיק, מתכנת ובלוגר

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

docker run -d -p 80:80 --name my-apache-php-app -v /c/temp:/var/www/html php:7.0-apache

המחרוזת php:7.0-apache מגיעה מהפצה רשמית של PHP שנמצאת בדוקר. ההפצה הרשמית היא PHP וה’ענף’ הוא 7.0-apache. מה שנמצא מאחורי ההפצה הזו הוא קובץ הגדרות שקובע שעל הקונטיינר להתקין apache למשל, ו-PHP מגרסה 7 ועוד כל מיני דברים. כאמור, אני יכול להסתמך על קובץ הגדרות רשמי ומוכר וזה טוב בדרך כלל לתסריטים פשוטים, או לחלופין, אני יכול ליצור קובץ הגדרות מיוחד שמכיל את ההגדרות שלי. קובץ ההגדרות הזה נקרא image. מה-image הזה אנחנו יוצרים קונטיינרים.

למה שארצה ליצור image משלי? יש מיליון תסריטים – למשל אפליקציה שיש בה גם PHP וגם Python מגרסאות ספציפיות, או מודולים ספציפיים של PHP. אם אני מתחזק אתרים, סביבת הפיתוח צריכה להיות תואמת לסביבת הפרודקשן. לפעמים אני רוצה להרים קונטיינר לצורך מאוד ספציפי שיעשה עבודה אחת מאוד פשוטה. הדוגמה הכי טובה ומעשית שאני יכול לציין היא הרצת static code analysis על קבצי PHP. לא מעט פעמים אני צריך לבדוק תוספים מסוימים שנכתבו ב-PHP ולראות שהם תואמים לסטנדרט והמפתח שפיתח אותם יודע מה הוא עושה. לצורך זה אני צריך להפעיל את PHP code sniffer שההתקנה שלו על מחשב מקומי יכולה להיות מאתגרת. למה לשבור את הראש כשאני יכול להרים קונטיינר מיידי ולהריץ את בדיקת הקוד ממנו?

?מה המטרה

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

?IMAGE איך יוצרים

קל להבין שאני לא יכול להשתמש במשהו רשמי כמו PHP. כלומר זה יהיה הבסיס שלי מן הסתם כי אני צריך קונטיינר שמריץ PHP. אבל אני צריך עוד דברים ובראשם PHPCS, הכלי שבו אני משתמש. הוא נשען על PHP אבל אין לו זכר במאגרים הרשמיים. בשביל להכניס אותו לקונטיינר, אני יכול או להתקין אותו ידנית בכל פעם שאני יוצר קונטיינר מקובץ ‘רשמי’ (רעיון רע) או להכין קובץ הגדרות שפשוט בא ואומר: “קח את הקונטיינר, התקן עליו PHPCS ואולי עוד משהו וזהו”.

על מנת לעשות זאת, אני אצור קובץ שנקרא Dockerfile (עם D גדולה) ואציב אותו בפרויקט שלי. הקובץ הזה הוא סוג של ‘תבנית’ שבתוכו אני יכול להכניס הוראות שונות שיעבדו ממש כאילו אני בתוך המכונה. הנה הדוקר שלי:

FROM php:7-alpine

RUN cd /usr/local/bin \

   && curl -sL http://cs.sensiolabs.org/download/php-cs-fixer-v2.phar -o php-cs-fixer \

   && chmod +x php-cs-fixer \

   && curl -sL https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar -o phpcs \

   && chmod +x phpcs

WORKDIR /app

FROM

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

RUN

זו פקודה שמשמעותה היא הרצה. כל מה שבא אחריה ירוץ. שימו לב שאני משתמש פה בסינטקס של שרשור &&. בלינוקס שרשור זה אומר לבצע את הפקודה שאחרי ה-&& מיד אחרי שקודמתה מסתיימת. אבל זה מקביל ל:

RUN cd /usr/local/bin \

RUN curl -sL http://cs.sensiolabs.org/download/php-cs-fixer-v2.phar -o php-cs-fixer \

RUN chmod +x php-cs-fixer \

RUN curl -sL https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar -o phpcs \

RUN chmod +x phpcs

מקובל בדרך כלל לקשר כל RUN לשורת פקודות שרלוונטיות לנושא. למשל RUN אחד להתקנת ה-PHPCS ו-RUN אחר להתקנת רכיב נוסף כשבכל RUN הפקודות הרלוונטיות לו יהיו משורשרות באמצעות &&. אם זה נשמע לכם כמו סינית אז זה בסדר. רק תזכרו ש-&& זה שרשור (כמו לכתוב, אחרי שההוא מסתיים, תריץ את זה).

WORKDIR

הגדרה של סביבת העבודה. במקרה הזה אני מכוון את הקונטיינר, מייד אחרי שה-phpcs מסתיים להתקנה, להגיע אל תיקית app/

אז בעצם שלוש הפקודות האלו הן פשוטות – FROM אומרת לנו – אתה מתבסס על הגרסה הרשמית של PHP שנקראת php:7-alpine (אותה לקחתי כמובן מהגרסה הרשמית של PHP שיש בדוקר, אבל אני יכול לקחת כל גרסה). פקודת RUN אומרת לנו להריץ שורה של פקודות שמתקינות את PHPCS שאותה לקחתי מהגרסה הרשמית שלהם ולבסוף פקודת WORKDIR מחזירה את הקונטקסט של הקונטיינר לתיקיית app. למה?

נשמור את הקובץ בספריה כלשהי ונמשיך.

אחרי שיצרתי את הקובץ, אני צריך ‘לבנות’ אותו וזה השינוי הגדול ביותר שיש בין שימוש ב-image רשמי ל-Docker file. הבנייה בעצם עוקבת אחר כל ההוראות שיש בקובץ ומריצה אותו. אם הכל מצליח אנחנו יכולים ליצור קונטיינר מה-Image הזה בדיוק כמו כל image רשמי.

:הבניה נעשית כך

docker build -t ran-lint-machine .

הפקודה הראשונה היא docker build שאומרת שאנחנו בונים. הפלאג t- ומה שבא אחריו זה השם. שימו לב שזה חשוב אחרת תצטרכו להשתמש ב-hash של ה-image וזה לא נחמד. הנקודה שיש בסוף היא הנתיב לקובץ ה-docker שאותו ממש הכנו ושמרנו בשם Dockerfile. במקרה הזה אני מריץ את הפקודה ממש מאיפה שהקובץ נמצא.

עכשיו נראה בקונסולה את כל השלבים של ההתקנות. כן! אם יש תקלה כלשהי, נראה אותה וכך נוכל לתקן את הקובץ. אם הכל תקין, נראה את ה-output הבא:

Successfully built c77653df3672

Successfully tagged ran-lint-machine:latest

עכשיו יש לי image שאני יכול להריץ. שמו בישראל יהיה ran-lint-machine. אני יכול לבדוק אותו באמצעות הקלדה של:

docker images --all

אני אקבל רשימה של כל ה-images שהתקנתי אי פעם, כל הרשמיים וביניהם אחד קטן וחביב שיצרתי עכשיו ששמו הוא ran-lint-machine.

עכשיו כשיש לי את שם ה-image אני יכול להשתמש בו באופן הזה:

docker run --rm -it -v /c/Users/barzik/test-docker:/app/ ran-lint-machine phpcs PATH/TO/PHP/FILES/

docker run -it -v PATH/TO/PHP/FILES/:/app/ --rm ran-lint-machine phpcs .

את docker run -it אנחנו מכירים, זו הרצה שלו.

החלק הכי חשוב הוא v-. במאמר הפתיחה על docker כתבתי שהוא עוזר לנו לקשר בין המערכת שלנו לקונטיינר. במקרה הזה הוא קובע מה תיקיית app תהיה! אני אקשר בין התיקייה שבה יש את קבצי ה-PHP ל-app שהוא, כפי שאני קבעתי, תיקיית העבודה המרכזית.

פלאג rm– אומר למחוק את הקונטיינר מיד אחרי ההרצה. כיוון שמדובר בהרצה חד פעמית שלו.

שם ה-image שאותו קבעתי הוא כמובן ran-lint-machine והוא נקבע בתהליך ה-build.

ולבסוף, השורה שמריצה את phpcs ונקודה. כי אני מריץ את phpcs בתיקיה של apps שמקושרת לתיקיה שמכילה את קבצי ה-PHP.

ואם הכל יעבוד כמו שצריך, זה מה שאני אראה:

הרצה מוצלחת של PHPCS דרך דוקר על קבצים מקומיים

זה הבסיס אבל תראו כמה זה קל! במאמר הבא נעמיק מעט לתוך קובץ ה-Dockerfile.

מאת: רן בר זיק, מתכנת ובלוגר

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
רן בר זיק
בואו נעבוד ביחד
צרו קשר