# מה זה Docker — Image מול Container📖 שיעור

## מה זה?

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

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

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

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

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

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

```bash
# 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](https://docs.docker.com/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 מוכנים מהאינטרנט.
