PracticU

Dockerfile Multi-Stage

בלי כתוביותעם כתוביות
PracticU › קורס Docker - עם Swarm Cluster › Dockerfile Multi-Stage
מילון מושגים:
Dockerfile - קובץ טקסט עם הוראות לבניית Docker Image, המגדיר את הבסיס, הקבצים והפקודות שיירוצו.
Docker Image - תבנית לקריאה בלבד שמכילה אפליקציה ותלויותיה, וממנה מריצים קונטיינרים ב-Docker.
SDK - ערכת כלים לפיתוח: אוסף ספריות, כלים ותיעוד שמאפשרים לבנות תוכנה לפלטפורמה או שירות מסוימים.
.NET - פלטפורמת פיתוח של מיקרוסופט להרצת יישומים בשפות כמו C#, הכוללת ספריות וסביבת ריצה משותפות.
מטמון - אחסון זמני ומהיר של נתונים שנדרשים שוב, כדי להאיץ גישה ולהפחית עומס מהמקור המקורי.
DLL - קובץ ספרייה ב-Windows המכיל קוד ופונקציות שתוכנות שונות יכולות לטעון ולהשתמש בהן במשותף.
Docker - פלטפורמה להרצת אפליקציות בתוך קונטיינרים מבודדים וקלים, כדי שירוצו באופן אחיד בכל סביבה.
דיבאג - תהליך של איתור, הבנה ותיקון תקלות בקוד, לעיתים בעזרת כלי שמאפשר לעצור ולעקוב אחר ריצת התוכנית.

Dockerfile Multi-Stage
ההרצאה מסבירה Dockerfile רב-שלבי (multi-stage): קובץ אחד שבונה את האפליקציה בתוך אימג' גדול שמכיל כלי פיתוח, ומעתיק לאימג' הסופי קטן רק את התוצר המקומפל. הדוגמה היא אפליקציית ASP.NET Core מתוך המדריך של מייקרוסופט.
השלבים העיקריים
1. שלב הבנייה: השורה הראשונה FROM מביאה אימג' SDK של .NET Core ונותנת לו את השם build (AS build). האימג' הזה כולל את כלי הקומפילציה וגדול מאוד, כמעט ג'יגה וחצי.
2. שחזור החבילות: קודם מעתיקים רק את קובץ הפרויקט (csproj) ומריצים dotnet restore. החבילות החיצוניות נשמרות במטמון, כי הן לא משתנות לעיתים קרובות.
3. העתקת הקוד והפרסום: רק אחר כך מעתיקים את שאר קוד המקור ומריצים dotnet publish בתצורת Release, והתוצר נכתב לתיקיית out.
4. שלב הריצה: FROM נוסף מביא אימג' runtime קטן, בלי כלי הפיתוח.
5. העתקה מהשלב הקודם: COPY --from=build מעתיק את תיקיית ה-out לתוך האימג' החדש. ההעתקה לא מגיעה מהמחשב המקומי אלא מהשלב build.
6. נקודת כניסה: ENTRYPOINT מפעיל את קובץ ה-DLL של האפליקציה דרך dotnet.
7. גודל התוצאה: אימג' ה-SDK גדול, אימג' ה-runtime כ-400 מגה, והאימג' הסופי כ-411 מגה. כלי הפיתוח לא נשארים בתוצר הסופי.
8. בנייה חוזרת: אחרי שינוי קטן בקוד הבנייה חוזרת מהר, כי השלבים שלא השתנו נלקחים מהמטמון.
פקודות והגדרות
docker build -t <שם-אימג'>:test . מריץ את הבנייה מהתיקייה הנוכחית. docker events מציג בזמן אמת את הפעולות שהבנייה מבצעת, ועוזר לראות על איזו פקודה נפלה בנייה.
שימו לב
בפעם הראשונה הבנייה מושכת את אימג' ה-SDK מהאינטרנט, וזה לוקח זמן. תצורת Debug מפרטת הרבה מידע טכני בשגיאות, ותצורת Release נותנת תוצר סופי בלבד ולכן מתאימה לפרסום.
השיעור הבא בקורס: Linux Container on Server 2019

פרקי ההרצאה: Dockerfile Multi-Stage

  1. 00:00

    הכרת Dockerfile רב שלבי

  2. 00:58

    שני שלבי FROM בתוך קובץ אחד

  3. 02:16

    העתקת תוצרי הבנייה עם COPY --from

  4. 03:34

    שלב הריצה מאימג' חדש ונקי

  5. 04:25

    אימג' ה-SDK וכלי הקומפילציה

  6. 05:43

    העתקת קובץ הפרויקט והרצת dotnet restore

  7. 07:22

    שכבות קאש להאצת הבנייה

  8. 08:50

    הידור הפרויקט במצב Release

תמלול ההרצאה: Dockerfile Multi-Stage

הטקסט המלא של הדקות הראשונות בהרצאה «Dockerfile Multi-Stage» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.

  1. 00:02

    שלום לכולם בהרצאה הזאת אנחנו נדבר על docker file multi stage רב שלבי אנחנו נבין על מה מדובר וננתח דוגמה מוכנה של מייקרוסופט שהורדנו בהרצאות קודמות מי שקפץ ישר להרצאה הזאת יכול לעבור על לינק כזה של docker images for sp.net core ויש פה טוטוריאל מוכן ואנחנו הולכים לפי הטוטוריאל הזה וכרגע

  2. 00:34

    אנחנו רוצים להבין מה זה קובץ docker file שמייקרוסופט בנו לנו שממנו אנחנו נבנה קונטיינרים כי הוא רב שלבי ואנחנו נפתח אותו עם notepad ונראה ונבין אותו.

  3. 00:52

    דבר ראשון שאני רוצה להסביר לכם שהדבר הכי חשוב לדעת שכאשר אומרים רב שלבי מתכוונים שיש לא רק from אחד אלא שני from זאת אומרת שאנחנו בונים שני אימג'ים זה נקרא רב שלבי שיש לנו שלב ראשון שלב שני פה פה בשלב השני אנחנו מתחילים מ-0 לבנות אימג' חדש לגמרי.

  4. 01:18

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

  5. 01:31

    יש פה As. As זה כינוי לאימג', ואנחנו נקרא לו נניח בילד. יותר נכון, מייקרוסופט קראו לו בילד. אני מזכיר לכם, בילד זה אימג' שהופך קוד בשפת C-Sharp לקוד מקומפל, בשפת מכונה ופה אנחנו דרך אגב רואים את הפקודה שעושה את זה .NET Publish והיא עושה את זה

  6. 01:58

    לתיקיית Out, אוקיי? עכשיו אחרי שהאימג' הזה, האימג' הזה הראשון לפני ה-From השני עשה את הפעולה שלו, אנחנו עושים From אימג' נקי ועל האימג' הנקי אנחנו עושים קופי, מאיפה אנחנו עושים לו קופי?

  7. 02:21

    מתוך ה-Build הקודם, זוכרים? מתוך from build הזה אנחנו מעתיקים אותו למעשה ככה אנחנו יודעים להעתיק מהקונטיינר הקודם מהאימג' הקודם את התוכן שלו אתם רואים מינוס מינוס from build תיקח את זה לא מהhard disk הלוקאלי שלה אלא מבילד ההוא ומאיפה לקחת את זה מתוך תיקיית האאוט אתם זוכרים את האאוט

  8. 02:44

    זה האאוט נכון ולאן להעתיק לתיקייה הנוכחית אז עוד פעם מולטי סטייג' זה רב שלבים כאשר השלב הראשון הוא פרום משהו כרגיל ונותנים לו איזשהו כינוי בילד לא חייבים לתת לו את הכינוי הזה וגם אפשר בכלל לא לתת לו כינוי אלא לעשות לו מספר ואז לעשות לו פה פרום 0 אפשר היה לכתוב פה פרום 0 ולא לתת לבילד הזה שום שם כאילו אם הייתי עושה את זה ככה מוחק את הכל ושם פה 0

  9. 03:19

    זה גם היה עובד אבל זה לא יפה אנחנו מעדיפים לעבוד עם שמות אז אנחנו כותבים פה as build. יפה מאוד. אז נותנים לזה כינוי ל-image הראשון, call זה image הראשון.

  10. 03:37

    From השני, זה השלב השני. מתחיל אימג' חדש, זה פיצ'ר שעשו אותו לאחרונה, לפני כן לא הייתה אפשרות כזאת. ומתחילים אימג' חדש לגמרי, מ-0, ורק עושים קרופי, אבל במקום להעתיק מהתיקייה הלוקאלית שלי, נכון?

  11. 03:52

    בארדיסק הלוקאלי שלי, by default, אני עושה לו תעתיק מ-image הקודם, from build, אז שני סלשים from build אומר לו, הדבר הבא שיהיה זה מתיקי ה-E ולא מהתיקי הנוכחית שלי, ולאן להעתיק?

  12. 04:08

    לתיקי הנוכחית כאן, מה זה כאן? work directory קבע שהתיקי הנוכחית יהיה slash up. דרך אגב, אם אנחנו עולים למעלה, גם פה work directory slash up, אז מה קורה ב-image הזה?

  13. 04:23

    בואו ננתח אותו. ה-image הראשון נקרא build, שזה למעשה sdk, לוקחים sdk, שימו לב מ-repository של מיקרוסופט, ממאגר מרכזי של מייקרוסופט לוקחים אימץ' שנקרא sdk שיש בו את כל הכלים לקומפילציה ואנחנו נראה שהוא ענק יחסית ל-run time הפשוט אז sdk הזה הוא ענק וה-sp.net הזה שיש בו רק את ה-run time הוא קטנצ'יק.

  14. 04:51

    למה sdk ענק? כי יש לו את הכלים לקומפילציה, לדיבאגינג, להפוך את הכל לשפת מכונה, לחפש שגיאות. גרסה של .NET Core, הפלטפורמה שעליו הוא רץ, .NET 22. Work Directory קובעים תיקייה הנוכחית שתהיה slash up שימו לב אי אפשר לעשות cd slash up כי כל פקודה מתבצעת בקונטיינר נפרד וזה שניכנס לאיזושהי תיקייה בקונטיינר

  15. 05:16

    כלשהו לא יעזור לנו כי אנחנו בפקודה הבאה כבר נהיה בקונטיינר חדש ולכן חייבים לעשות work directory שזה יהיה משהו שיעבור דרך כל הקונטיינרים אני מזכיר לכם כל פקודת קרופי מייצרת לחדש image חדש קונטיינר חדש אז תדעו את זה קודם כל מעתיקים קובץ מסוג sln solution לתוך תיקייה נוכחית של slash app אחרי זה מעתיקים את כל

  16. 05:47

    מה שיש לנו בתוך sp.net app slash csproj זוכרים csproj מה זה? זה קובץ של פרויקט ראינו אותו בהרצאה הקודמת ששם כתוב כל מה שנדרש כל הספריות החיצוניות שנדרשות בשביל להריץ את הפרויקט הנוכחי שלי ואני מעתיק אותו לתוך בתוך הקונטיינר שנקראת ASP.NET App, שהקובץ גם יהיה שם CS Project.

  17. 06:17

    עכשיו שימו לב, אני לא מעתיק את כל הקוד, אני מעתיק רק את הקובץ של ה-Project. למה? כי רק בו כתובות כל ההתניות, כל ה-Dependencies, כל הספריות החיצוניות שנדרשות לי לפרויקט, ואחרי זה אני מריץ .NET Restore.

  18. 06:33

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

  19. 07:15

    עכשיו תשאלו אותי בשביל מה העתקת קוד עם CSproge היית כבר ישר מעתיק את הכל למה? כי ההתניות האלו הן לא משתנות כל הזמן.

  20. 07:26

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

  21. 07:39

    על מה יהיה לו קאש? על הדפנדנסיז, על ה-DLNים החיצוניים, על הפקאג'ים החיצוניים. אז בגלל שהפקאג'ים האלו לרוב לא משתנים, אז אני רוצה לעשות אותם בלר נפרד כדי שיוכל להשתמש בקאש, ומרגע שמשהו ישתנה בו בקובץ מקור הוא רק יעתיק את השינויים האלו.

  22. 08:05

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

  23. 08:14

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

  24. 08:31

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

  25. 08:47

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

  26. 09:00

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

  27. 09:13

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

  28. 09:29

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

  29. 09:46

    זה שינויים קטנים, ו-O זה Out, ולכן זה עובר לתיקיית Out, אז התיקייה הסופית היא app.asp.netapp/out. פה יהיה בעצם הבין המקומפל, אוקיי? יפה מאוד.

  30. 10:07

    עכשיו, אחרי שיש לי את המקומפל הזה, אני יכול להריץ אותו פשוט וזהו. אבל לא, אני לא רוצה לסחוב איתי ללקוחות קצה שלי את כל ה-SDK, את כל הכלי פיתוח, אני כבר קימפלתי אותו ואני כבר לא צריך אותו.

  31. 10:22

    אז אני מתחיל אימג' חדש מאפס, אני יכול לקרוא לו runtime, אני יכול לא לקרוא לו בכלל, אני קובע לו שאני עובד בתיקיית ה-app, אם היא לא קיימת הוא ייצור אותה, ומעתיק לתוך תיקיית ה-app, לתוך התיקייה הנוכחית, את כל מה שהיה בהוא בתיקיית ה-out שלו.

  32. 10:43

    איך אני יודע שזה אצלו ולא אצלי לוקאלית? כי יש פה מינוס מינוס from build הבילד הזה אמרנו שזה הבילד הזה ואז הוא מעתיק אותו ודבר אחרון הוא קובע לי entry point entry point זה איזה פקודה להריץ כשמריצים את הקונטיינר איך שבן אדם יריץ לי את הקונטיינר זה פקודת .NET וה-DLL שלי בגלל הworking directory הוא יושב פה בשורש זה

  33. 11:06

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

  34. 11:31

    נעשה לזה cls, נצא לתיקייה אחת, לעוד אחת, לעוד אחת, כן.

  35. 11:45

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

  36. 12:24

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

  37. 12:50

    אנחנו נעשה בעצם פקודת בילד, מה שהסברת לכם נמצא הכל פה באתר ואנחנו נעשה run in windows container ואנחנו עושים build ואחרי זה run אז אני עושה build ופה רץ לי docker events אז אני עושה docker build תבנה לי מינוס t נותן לו איזושהי תגית sp.net app סתם תגית נקודתיים לטסט ותיקח את הכל מתיקי הנוכחית זה הקונטקסט שלך יפה מאוד מתחילים לבנות ושימו

  38. 13:30

    לב הוא מתחיל למשוך את ה.net core sdk כי אין לי אותו, אתם רואים, הוא מושך אותו מאינטרנט, זה לוקח לו זמן, כי אני עוד לא עשיתי את זה פה, אין לו את ה-SDK הזה, ו-Docker Events יתחיל לעבוד ברגע שנבנה קונטיינרים.

  39. 13:55

    אני אשים אותו בפאוזה, אם ניתן לו להוריד, אתם רואים, זה 300 מגה. שימו לב, .NET Core SDK זה 300 וזה עוד 100, הוא ענק, 169. טוב, אני שם פאוזה ואני אשחרר אותה ברגע שהוא יוריד הכל.

  40. 14:11

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

  41. 14:43

    רציתי להראות לכם docker event זה כלי מאוד

לקורס המלא: קורס Docker עם Swarm Cluster

ההרצאה הקודמת: Build .NET app on Docker

ההרצאה הבאה: Linux Container on Server 2019

הרצאות קשורות מקורסים אחרים

  • פונקצית Multi Statement
  • אופיס 365 Multi-Factor Authentication
  • Azure MFA - Multi-Factor Authentication
  • מבחן RHCE - שרת SAMBA במצב Multi User

קורסים נוספים במסלול

  • קורס AWS - ניהול מכונה וירטואלית בענן
  • קורס Terraform - DevOps - Azure & AWS
  • קורס קוברנטיקס - Kubernetes
  • קורס DevOps - Ansible
  • קורס PowerShell
  • קורס Git ו-GitHub עם Visual Studio