
AS build). האימג' הזה כולל את כלי הקומפילציה וגדול מאוד, כמעט ג'יגה וחצי.COPY --from=build מעתיק את תיקיית ה-out לתוך האימג' החדש. ההעתקה לא מגיעה מהמחשב המקומי אלא מהשלב build.docker build -t <שם-אימג'>:test . מריץ את הבנייה מהתיקייה הנוכחית. docker events מציג בזמן אמת את הפעולות שהבנייה מבצעת, ועוזר לראות על איזו פקודה נפלה בנייה.הטקסט המלא של הדקות הראשונות בהרצאה «Dockerfile Multi-Stage» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
שלום לכולם בהרצאה הזאת אנחנו נדבר על docker file multi stage רב שלבי אנחנו נבין על מה מדובר וננתח דוגמה מוכנה של מייקרוסופט שהורדנו בהרצאות קודמות מי שקפץ ישר להרצאה הזאת יכול לעבור על לינק כזה של docker images for sp.net core ויש פה טוטוריאל מוכן ואנחנו הולכים לפי הטוטוריאל הזה וכרגע
אנחנו רוצים להבין מה זה קובץ docker file שמייקרוסופט בנו לנו שממנו אנחנו נבנה קונטיינרים כי הוא רב שלבי ואנחנו נפתח אותו עם notepad ונראה ונבין אותו.
דבר ראשון שאני רוצה להסביר לכם שהדבר הכי חשוב לדעת שכאשר אומרים רב שלבי מתכוונים שיש לא רק from אחד אלא שני from זאת אומרת שאנחנו בונים שני אימג'ים זה נקרא רב שלבי שיש לנו שלב ראשון שלב שני פה פה בשלב השני אנחנו מתחילים מ-0 לבנות אימג' חדש לגמרי.
כן, בונים אימג' אחד, אחרי זה בונים עוד אחד. עכשיו, תשאלו איך קושרים ביניהם, שזה הדבר הכי יפה. אחרי From איזה אימג' אנחנו רוצים?
יש פה As. As זה כינוי לאימג', ואנחנו נקרא לו נניח בילד. יותר נכון, מייקרוסופט קראו לו בילד. אני מזכיר לכם, בילד זה אימג' שהופך קוד בשפת C-Sharp לקוד מקומפל, בשפת מכונה ופה אנחנו דרך אגב רואים את הפקודה שעושה את זה .NET Publish והיא עושה את זה
לתיקיית Out, אוקיי? עכשיו אחרי שהאימג' הזה, האימג' הזה הראשון לפני ה-From השני עשה את הפעולה שלו, אנחנו עושים From אימג' נקי ועל האימג' הנקי אנחנו עושים קופי, מאיפה אנחנו עושים לו קופי?
מתוך ה-Build הקודם, זוכרים? מתוך from build הזה אנחנו מעתיקים אותו למעשה ככה אנחנו יודעים להעתיק מהקונטיינר הקודם מהאימג' הקודם את התוכן שלו אתם רואים מינוס מינוס from build תיקח את זה לא מהhard disk הלוקאלי שלה אלא מבילד ההוא ומאיפה לקחת את זה מתוך תיקיית האאוט אתם זוכרים את האאוט
זה האאוט נכון ולאן להעתיק לתיקייה הנוכחית אז עוד פעם מולטי סטייג' זה רב שלבים כאשר השלב הראשון הוא פרום משהו כרגיל ונותנים לו איזשהו כינוי בילד לא חייבים לתת לו את הכינוי הזה וגם אפשר בכלל לא לתת לו כינוי אלא לעשות לו מספר ואז לעשות לו פה פרום 0 אפשר היה לכתוב פה פרום 0 ולא לתת לבילד הזה שום שם כאילו אם הייתי עושה את זה ככה מוחק את הכל ושם פה 0
זה גם היה עובד אבל זה לא יפה אנחנו מעדיפים לעבוד עם שמות אז אנחנו כותבים פה as build. יפה מאוד. אז נותנים לזה כינוי ל-image הראשון, call זה image הראשון.
From השני, זה השלב השני. מתחיל אימג' חדש, זה פיצ'ר שעשו אותו לאחרונה, לפני כן לא הייתה אפשרות כזאת. ומתחילים אימג' חדש לגמרי, מ-0, ורק עושים קרופי, אבל במקום להעתיק מהתיקייה הלוקאלית שלי, נכון?
בארדיסק הלוקאלי שלי, by default, אני עושה לו תעתיק מ-image הקודם, from build, אז שני סלשים from build אומר לו, הדבר הבא שיהיה זה מתיקי ה-E ולא מהתיקי הנוכחית שלי, ולאן להעתיק?
לתיקי הנוכחית כאן, מה זה כאן? work directory קבע שהתיקי הנוכחית יהיה slash up. דרך אגב, אם אנחנו עולים למעלה, גם פה work directory slash up, אז מה קורה ב-image הזה?
בואו ננתח אותו. ה-image הראשון נקרא build, שזה למעשה sdk, לוקחים sdk, שימו לב מ-repository של מיקרוסופט, ממאגר מרכזי של מייקרוסופט לוקחים אימץ' שנקרא sdk שיש בו את כל הכלים לקומפילציה ואנחנו נראה שהוא ענק יחסית ל-run time הפשוט אז sdk הזה הוא ענק וה-sp.net הזה שיש בו רק את ה-run time הוא קטנצ'יק.
למה sdk ענק? כי יש לו את הכלים לקומפילציה, לדיבאגינג, להפוך את הכל לשפת מכונה, לחפש שגיאות. גרסה של .NET Core, הפלטפורמה שעליו הוא רץ, .NET 22. Work Directory קובעים תיקייה הנוכחית שתהיה slash up שימו לב אי אפשר לעשות cd slash up כי כל פקודה מתבצעת בקונטיינר נפרד וזה שניכנס לאיזושהי תיקייה בקונטיינר
כלשהו לא יעזור לנו כי אנחנו בפקודה הבאה כבר נהיה בקונטיינר חדש ולכן חייבים לעשות work directory שזה יהיה משהו שיעבור דרך כל הקונטיינרים אני מזכיר לכם כל פקודת קרופי מייצרת לחדש image חדש קונטיינר חדש אז תדעו את זה קודם כל מעתיקים קובץ מסוג sln solution לתוך תיקייה נוכחית של slash app אחרי זה מעתיקים את כל
מה שיש לנו בתוך sp.net app slash csproj זוכרים csproj מה זה? זה קובץ של פרויקט ראינו אותו בהרצאה הקודמת ששם כתוב כל מה שנדרש כל הספריות החיצוניות שנדרשות בשביל להריץ את הפרויקט הנוכחי שלי ואני מעתיק אותו לתוך בתוך הקונטיינר שנקראת ASP.NET App, שהקובץ גם יהיה שם CS Project.
עכשיו שימו לב, אני לא מעתיק את כל הקוד, אני מעתיק רק את הקובץ של ה-Project. למה? כי רק בו כתובות כל ההתניות, כל ה-Dependencies, כל הספריות החיצוניות שנדרשות לי לפרויקט, ואחרי זה אני מריץ .NET Restore.
.NET Restore בעצם משחזר את כל מה שנדרש לפרויקט, מוריד את כל הפקאג'ים החיצוניים שנקראים מבחוץ אז זה כובד של הפרויקט אם יש לי כמה פרויקטים הם יהיו כתובים תחת סולושן אחד זה לא באמת חשוב מה שחשוב זה הכובד של CSproge אחרי שהעתקנו יותר נכון אחרי ששחזרנו את כל הספריות החיצוניות אנחנו עכשיו מעתיקים את כל קוד המקור מאותה תיקייה זאת אומרת את כל מה שהמתכנתים כתבו
עכשיו תשאלו אותי בשביל מה העתקת קוד עם CSproge היית כבר ישר מעתיק את הכל למה? כי ההתניות האלו הן לא משתנות כל הזמן.
מה שמשתנה כל הזמן זה איזו פקודה קטנה בתוך קובץ מקור. ולכן אני אעשה הרבה בירדים, ואני רוצה שכל פעם שאני עושה בירד הוא ישתמש בקאש.
על מה יהיה לו קאש? על הדפנדנסיז, על ה-DLNים החיצוניים, על הפקאג'ים החיצוניים. אז בגלל שהפקאג'ים האלו לרוב לא משתנים, אז אני רוצה לעשות אותם בלר נפרד כדי שיוכל להשתמש בקאש, ומרגע שמשהו ישתנה בו בקובץ מקור הוא רק יעתיק את השינויים האלו.
אני לא אצליח לחכות הרבה זמן שעוד פעם יקים לי את הקונטיינר ועוד פעם יוריד לי את כל הדוטנט ריסטור לו, שיקח את זה מהקאש. מה זה קאש?
כל פקודה זה לר נפרד, זה אימג' נפרד. אז שישתמש באימג' ישן, הרי כל מה שלא השתנה עד לפקודה מסוימת, שבה משהו כן השתנה, אז עד אותה פקודה הכל נלקח מקאש.
עכשיו, אז בגלל זה תיקייה שמשתנה לעיתים קרובות, אני שם אותה בסוף, אני מעתיק אותה בסוף כדי שכל מה שלא משתנה לא יעשה בילד מחדש ולא יעשה ריסטור מחדש.
אז העתקנו בעצם את כל השאר הדברים שהיינו צריכים. קבענו שהתיקייה הנוכחית, שימו לב, משתנה. לפני כן הייתה תיקייה נוכחית סלאש אפ, עכשיו נכנסנו לתוך הפרויקט עצמו.
וכשאנחנו כבר בתיקיית פרויקט אנחנו עושים מה שנקרא בילד, בונים אותו, מקמפלים אותו, כן, הבדל גדול בין פאבליש לבילד, זה למעשה די אותו דבר.
אז אנחנו אומרים לו, תקמפל את הכל, תעשה את זה בצורת לא דיבאג אלא ריליז. דיבאג וריליז זה די אותו דבר, ההבדל ביניהם שכל מיני מידע טכני פנימי לא נחשף החוצה כשיש תקלה כלשהי או שגיאה כלשהי.
זאת אומרת, במצב של שגיאה הוא ייתן שגיאה וזהו, הוא לא יפרט מה הבעיה. כל מיני דברים טכניים שלי לא יפורטו, ולכן יש תצורת דיבאג שמפרטת הרבה פלט, ותצורת ריליסט שהיא יותר לתוצאה סופית.
זה שינויים קטנים, ו-O זה Out, ולכן זה עובר לתיקיית Out, אז התיקייה הסופית היא app.asp.netapp/out. פה יהיה בעצם הבין המקומפל, אוקיי? יפה מאוד.
עכשיו, אחרי שיש לי את המקומפל הזה, אני יכול להריץ אותו פשוט וזהו. אבל לא, אני לא רוצה לסחוב איתי ללקוחות קצה שלי את כל ה-SDK, את כל הכלי פיתוח, אני כבר קימפלתי אותו ואני כבר לא צריך אותו.
אז אני מתחיל אימג' חדש מאפס, אני יכול לקרוא לו runtime, אני יכול לא לקרוא לו בכלל, אני קובע לו שאני עובד בתיקיית ה-app, אם היא לא קיימת הוא ייצור אותה, ומעתיק לתוך תיקיית ה-app, לתוך התיקייה הנוכחית, את כל מה שהיה בהוא בתיקיית ה-out שלו.
איך אני יודע שזה אצלו ולא אצלי לוקאלית? כי יש פה מינוס מינוס from build הבילד הזה אמרנו שזה הבילד הזה ואז הוא מעתיק אותו ודבר אחרון הוא קובע לי entry point entry point זה איזה פקודה להריץ כשמריצים את הקונטיינר איך שבן אדם יריץ לי את הקונטיינר זה פקודת .NET וה-DLL שלי בגלל הworking directory הוא יושב פה בשורש זה
למעשה לקחתי תיקיית בין העתקתי אותה לקונטיינר חדש ואני מריץ אותה עם .NET רווח השם של ה-DLL כמו שעשינו ידנית אז הבנו מה זה מולטי סטייג' בואו נראה את זה וגם אני אראה לכם עוד משהו מגניב, איך רואים שגיאות, איך רואים את כל הדברים האלו, זה עשינו בהרצאות קודמות.
נעשה לזה cls, נצא לתיקייה אחת, לעוד אחת, לעוד אחת, כן.
אנחנו צריכים להיות בתיקייה של פרויקט, כן, הנה הפרויקט שלי, לא, למעשה אני צריך להיות בתיקייה לא של הפרויקט אלא של הדוקר פייל. יפה, פה זה הדוקר פייל, והדוקר פייל הזה, בואו נראה, דוקר פייל הזה, נכון, זה הכל יחסית לקופי SP/CS Project, יחסית לדוקר פייל הזה, נכון.
יופי, אז אנחנו הולכים לעשות פה בילד ולראות איך כל זה קורה, הלאה. עכשיו אני רוצה גם להראות לכם איך עוקבים אחרי כל מיני אירועים שקורים בדוקר, זה נקרא דוקר איבנטס, דוקר איבנטס, נתחיל לעקוב אחרי כל הפקודות שהולכות לקרות, ומה אנחנו עושים?
אנחנו נעשה בעצם פקודת בילד, מה שהסברת לכם נמצא הכל פה באתר ואנחנו נעשה run in windows container ואנחנו עושים build ואחרי זה run אז אני עושה build ופה רץ לי docker events אז אני עושה docker build תבנה לי מינוס t נותן לו איזושהי תגית sp.net app סתם תגית נקודתיים לטסט ותיקח את הכל מתיקי הנוכחית זה הקונטקסט שלך יפה מאוד מתחילים לבנות ושימו
לב הוא מתחיל למשוך את ה.net core sdk כי אין לי אותו, אתם רואים, הוא מושך אותו מאינטרנט, זה לוקח לו זמן, כי אני עוד לא עשיתי את זה פה, אין לו את ה-SDK הזה, ו-Docker Events יתחיל לעבוד ברגע שנבנה קונטיינרים.
אני אשים אותו בפאוזה, אם ניתן לו להוריד, אתם רואים, זה 300 מגה. שימו לב, .NET Core SDK זה 300 וזה עוד 100, הוא ענק, 169. טוב, אני שם פאוזה ואני אשחרר אותה ברגע שהוא יוריד הכל.
הנה הוא מסיים פה להוריד את הקבצים, נשארו לו איזה שני מגה אחרונים אז עכשיו הוא עושה להם אקסטרקטינג, מוציא אותם מהזיפ ועל ידי זה הוא עושה כבר זריז ואחרי שהוא מסיים הוא מתחיל לבנות בעצם את הקונטיינר הראשון של sdk ונראה פה ממש את הפקודות שרצות מה הוא עושה מאחורי הקלעים ואם יש בעיה אנחנו נדע בדיוק על מה הוא נופל
רציתי להראות לכם docker event זה כלי מאוד