מה זה?

“אצלי זה עובד” — משפט שכל מפתח מכיר: הקוד רץ מצוין על המחשב שלכם, אבל נכשל אצל חבר לצוות (גרסת .NET אחרת, תלות חסרה) או בשרת production (מערכת הפעלה שונה). Docker פותר את זה: אורזים את האפליקציה יחד עם כל מה שהיא צריכה (runtime, תלויות, קונפיגורציה) ל"קונטיינר" נייד אחד, שרץ זהה לחלוטין בכל מקום שיש בו Docker — המחשב שלכם, של חבר הצוות, או שרת production.

מילות מפתח שחשוב לזכור

• Container — סביבת הרצה מבודדת וארוזה, כוללת את האפליקציה + כל מה שהיא צריכה כדי לרוץ

• Image — “תבנית” קפואה וניתנת-לשכפול שממנה יוצרים Containers — כמו class לעומת Object מיחידת ה-OOP

• Docker Engine — התוכנה שמריצה Images ל-Containers בפועל, על כל מערכת הפעלה שתתקין אותה

• Isolation (בידוד) — כל Container רץ בסביבה משלו, לא “רואה” או מתנגש בתלויות של Containers אחרים באותו מחשב

# Running the first Container — downloads the Image (if not present locally) and runs a Container from it
docker run hello-world

# Running a real server — mapping an external port (8080) to a port inside the container (80)
docker run -p 8080:80 my-api-image

# List running Containers
docker ps

# Stop a Container
docker stop <container-id>

הסבר עיקרי

Image מול Container — בדיוק כמו Class מול Object מיחידת ה-OOP: Image הוא ה"מתכון" הקפוא (בלתי-ניתן-לשינוי) — אילו קבצים, אילו תלויות, איזה קוד. Container הוא מופע רץ של אותו Image — אפשר להריץ כמה Containers שונים מאותו Image בו-זמנית, כל אחד עצמאי לגמרי (כמו כמה מופעי Student מאותה מחלקה).

Isolation פותר בדיוק את “אצלי זה עובד” — בלי Docker, שני פרויקטים על אותו מחשב עלולים לדרוש גרסאות שונות של .NET שמתנגשות. כל Container מגיע עם כל מה שהוא צריך בפנים (כולל גרסת runtime מדויקת) — אין תלות בסביבה החיצונית של המחשב המארח, מעבר ל-Docker Engine עצמו.

-p 8080:80 — מיפוי פורטים — קונטיינר רץ בבידוד, כולל רשת — הוא לא “נגיש” אוטומטית מבחוץ. -p <מבחוץ>:<מבפנים> פותח חלון ספציפי: בקשות ל-localhost:8080 על המחשב המארח מועברות לפורט 80 בתוך הקונטיינר, שם השרת בפועל מאזין.

יתרונות

Docker פותר “אצלי זה עובד” — סביבת ההרצה זהה בכל מקום; אפשר להריץ כמה גרסאות/פרויקטים שונים באותו מחשב בלי התנגשות תלויות; פריסה (Deployment) לשרת production זהה בדיוק לסביבת הפיתוח המקומית.

חסרונות

לומדים תחביר וכלים נוספים (Dockerfile, docker run flags); Image שלא נבנה בקפידה עלול להיות גדול מיותר בגודל, ולהאט הורדה/פריסה.

נקודות חשובות

• Image = תבנית קפואה; Container = מופע רץ ממנה, בדיוק כמו Class↔Object

• Isolation מבטיח שכל Container לא מתנגש בתלויות של Containers אחרים

• docker run יוצר ומריץ Container מ-Image; docker ps מציג Containers פעילים

• -p host:container ממפה פורט מבחוץ לפנים — בלעדיו הקונטיינר לא נגיש

טעויות נפוצות

• לחשוב ש-Image ו-Container הם אותו דבר — Image הוא סטטי, Container הוא ריצה בפועל שלו

• לשכוח מיפוי פורט (-p) ולתהות למה השרת “לא נגיש” למרות שהקונטיינר רץ (docker ps מראה אותו כפעיל)

• לצפות ששינוי קובץ בתוך קונטיינר רץ ישפיע על ה-Image המקורי — הוא לא, השינוי נעלם כשהקונטיינר נעצר (אלא אם משתמשים ב-Volumes, נושא מתקדם יותר)

סיכום

Docker אורז אפליקציה יחד עם כל תלויותיה ל-Image — תבנית קפואה שממנה מריצים Containers, מופעים עצמאיים ומבודדים. הבידוד הזה פותר את בעיית “אצלי זה עובד”: סביבת ההרצה זהה בכל מקום שיש בו Docker Engine, מהמחשב האישי ועד שרת production. מיפוי פורטים (-p host:container) הוא מה שהופך שירות בתוך קונטיינר לנגיש מבחוץ.

דוקומנטציה רשמית

Docker — Get Started


תרגילים

תרגיל 1 — הרצת Container ראשון

המשימה: הריצו docker run hello-world, וקראו את הפלט שמוסבר בו על מה קרה מאחורי הקלעים.

בדיקה: ההודעה מודפסת בהצלחה, ומסבירה את התהליך (הורדת Image, יצירת Container, הרצה).

תרגיל 2 — מיפוי פורטים

המשימה: הריצו Image ציבורי כלשהו (למשל nginx) עם -p 8080:80, וגשו אליו מהדפדפן דרך localhost:8080.

בדיקה: דף ברירת המחדל של השרת מוצג בדפדפן — הוכחה שהמיפוי עבד.


פרויקט מסכם

המשימה: הריצו שלושה Containers שונים בו-זמנית מאותו Image (nginx או דומה), כל אחד עם פורט חיצוני שונה.

דרישות:

  1. docker run -p 8081:80 nginx, docker run -p 8082:80 nginx, docker run -p 8083:80 nginx — שלושה Containers עצמאיים
  2. docker ps מראה את שלושתם רצים בו-זמנית
  3. גישה לכל אחד מהפורטים בדפדפן מציגה תגובה זהה, אך מכל Container בנפרד

בדיקה: עצירת אחד מה-Containers (docker stop) לא משפיעה על השניים האחרים — הוכחה לבידוד מלא בין Containers עצמאיים מאותו Image.

מה בפרק הבא

בפרק הבא — Dockerfile: איך בונים Image משלכם, במקום להשתמש רק ב-Images מוכנים מהאינטרנט.