המבנה המינימלי
Dockerfile הוא הוראות בנייה, שורה אחר שורה. כל הוראה שינוי במערכת הקבצים יוצרת שכבה חדשה.
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
זה כל מה שצריך כדי לארוז אפליקציית Node. נקרא אותו מלמטה:
CMD— הפקודה שתרוץ כשהמכולה עולה. בצורת מערך (exec form) ולא כמחרוזת, כדי שה-PID 1 יהיה התהליך עצמו ולא מעטפת shell שלא מעבירה אותות.EXPOSE— תיעוד שהאפליקציה מאזינה על הפורט הזה. הוא לא פותח כלום בפועל; את הפורט מפרסמים ב-docker run -p.COPY . .— מעתיק את הקוד. שימו לב שהוא אחריnpm ci, וזה בכוונה (בשיעור הבא).RUN npm ci— מתקין תלויות בזמן הבנייה, לא בזמן ההרצה.WORKDIR— קובע את תיקיית העבודה לכל ההוראות שאחריו.FROM— נקודת ההתחלה: תמונת בסיס.
.dockerignore הוא לא אופציה
לפני שה-build הראשון רץ, צרו .dockerignore. בלעדיו COPY . . מעתיק node_modules, .git וקבצי סביבה — בנייה איטית, ולפעמים גם סודות שנכנסים לאימג'.
node_modules
.git
.next
data
.env*
*.log
שגיאות שראיתם ומה הן אומרות
| הודעה | הסיבה האמיתית |
|---|---|
exec format error |
בניתם ל-ARM והרצתם ב-x86 (או ההפך) |
Cannot find module |
הקוד הועתק אבל התלויות לא — או שהנתיב ב-CMD שגוי |
permission denied |
קובץ בלי הרשאת הרצה, או תהליך שרץ כ-root וכותב לנתיב מוגן |
cannot connect to the Docker daemon |
הדמון לא רץ, או שאין הרשאה למשתמש |
לבדוק שהצליח
docker build -t myapp:dev .
docker run --rm -p 3000:3000 myapp:dev
curl -I http://localhost:3000
-t נותן שם לתג. בלי זה יש לכם דימוי עלום שאפשר להריץ רק לפי hash. תמיד תנו שם וגרסה.
מה עוד לא בסדר כאן
הבנייה הזו עובדת, אבל היא נושאת איתה את כל תלויות הפיתוח, וכל שינוי בקוד מפיל את הקאש של התקנת התלויות. זה השיעור הבא.