מחולל Dockerfile
בוחרים runtime ומקבלים Dockerfile ב-multi-stage ו-.dockerignore שרצים כמשתמש שאינו root, מצמידים את ה-images הבסיסיים ושומרים את התלויות ב-cache, עם הסבר לכל שורה. ה-Dockerfile Linter בודק את התוצאה כאן בעמוד.
מה הכלי עושה
המחולל כותב Dockerfile ו-.dockerignore לחמישה runtimes נפוצים, לפי ה-best practices של Docker עצמו: שלב build ו-image סופי רזה, התקנת תלויות מקובץ הנעילה לפני העתקת קוד המקור כדי שה-cache ישרוד שינויי קוד, cache mounts של BuildKit שמאיצים בנייה בלי להגדיל את ה-image, images בסיס מוצמדים לתג גרסה, משתמש שאינו root, HEALTHCHECK, ו-CMD או ENTRYPOINT בצורת exec כדי שהתהליך יקבל אותות עצירה. לכל שורה מצורפת הערה שמסבירה מה היא עושה ולמה, וה-Dockerfile Linter בודק את התוצאה בעמוד הזה.
איך זה עובד
- הקבצים נכתבים בעמוד הזה מתבניות מוקלדות; שום דבר לא נשלח לשום מקום, ושום דבר לא נבנה או נמשך.
- כל runtime מציע את הגרסאות שהוא תומך בהן, מוצמדות לתגי גרסה שנקראו מה-registries הרשמיים; ברירות המחדל הן קווי התמיכה הארוכה הנוכחיים.
- ה-Linter בודק את הפלט בכללים שלו יחד עם ה-.dockerignore שמגיע איתו, והממצאים, בדרך כלל אף אחד, מוצגים מתחת לקבצים.
- לפני פרסום העמוד, כל שילוב של runtime ואפשרויות שבבדיקות המחולל נבנה והורץ עם Docker על אפליקציית hello-world: הוא נבנה, רץ כמשתמש שאינו root, דיווח healthy ונעצר ב-SIGTERM.
מה כל runtime מקבל
- Node.js
- node:<version>-alpine, npm ci או pnpm install --frozen-lockfile בלי תלויות פיתוח בשלב נפרד, NODE_ENV=production, המשתמש node של ה-image ובדיקת בריאות עם wget.
- Python
- python:<version>-slim, סביבה וירטואלית שנבנית עם pip מ-requirements.txt או עם uv מ-uv.lock, משתמש ייעודי עם uid קבוע ובדיקת בריאות עם urllib של Python.
- Go
- golang:<version>-alpine בונה קובץ הרצה סטטי עם מודולים ב-cache; הוא רץ על distroless (nonroot, בלי shell) או על Alpine עם משתמש ייעודי ובדיקת בריאות עם wget.
- אתר סטטי
- נבנה עם npm או pnpm על Node.js 24, או מועתק כפי שהוא, ומוגש על ידי nginxinc/nginx-unprivileged בפורט 8080 כ-uid 101.
- Java (Maven)
- Maven עם JDK מלא פותר את התלויות ל-cache ובונה את ה-jar; הוא רץ על eclipse-temurin:<version>-jre-alpine כמשתמש ייעודי, עם heap בגודל שמתאים ל-container.
דוגמה
שירות Node.js עם npm וברירות המחדל, כפי שהמחולל כותב אותו עם ההסברים:
# syntax=docker/dockerfile:1
# השורה שמעל חייבת להישאר ראשונה: היא גורמת ל-BuildKit לקרוא את הקובץ בתחביר
# ה-Dockerfile העדכני, שנדרש ל-cache mounts שבהמשך.
# שלב 1 מתקין את התלויות ב-node:24-alpine, תג גרסה ולא latest, כך שבנייה חוזרת
# משתמשת באותה גרסת Node.js.
FROM node:24-alpine AS deps
# עבודה בתיקייה /app בשלב הזה.
WORKDIR /app
# קודם רק package.json ו-package-lock.json: השכבה הזו, וההתקנה שאחריה, נבנות
# מחדש רק כשהתלויות משתנות.
COPY package.json package-lock.json ./
# מתקין בדיוק את מה שבקובץ הנעילה, בלי devDependencies. ה-cache של npm הוא cache
# mount של BuildKit, כך שהוא מאיץ את הבנייה הבאה בלי להישאר ב-image.
RUN --mount=type=cache,target=/root/.npm npm ci --omit=dev
# ה-image הסופי מתחיל שוב מ-node:24-alpine, בלי ה-caches והכלים של שלב ה-build.
FROM node:24-alpine
# מצב production לספריות Node.js שקוראות את NODE_ENV (Express, למשל, שומר אז
# views ב-cache ומסתיר stack traces).
ENV NODE_ENV=production
# הפורט שהאפליקציה צריכה להאזין לו. מסגרות רבות קוראות את PORT; אם שלכם לא, יש
# להגדיר בתצורה שלה את הפורט 3000.
ENV PORT=3000
# האפליקציה נמצאת ב-/app.
WORKDIR /app
# התלויות שהותקנו בשלב 1. מנהל החבילות וה-cache שלו נשארים מאחור.
COPY --from=deps /app ./
# קוד המקור, אחרי התלויות כדי ששינוי בקוד לא יתקין אותן מחדש. הקבצים נשארים
# בבעלות root, כך שהאפליקציה לא יכולה לשנות את הקוד של עצמה; .dockerignore משאיר
# בחוץ את .git, .env ו-builds מקומיים.
COPY . .
# ב-image הרשמי של Node.js יש משתמש בלי הרשאות, node (uid 1000); התהליך רץ
# כמשתמש הזה ולא כ-root.
USER node
# מתעד שהאפליקציה מאזינה לפורט 3000. זה לא מפרסם כלום: את זה עושים docker run -p
# או ports: ב-Compose.
EXPOSE 3000
# Docker מסמן את ה-container כלא בריא כש-http://127.0.0.1:3000/ מפסיק לענות.
# נעשה שימוש ב-wget של BusyBox, שכבר קיים ב-image.
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
CMD ["wget", "-q", "--spider", "http://127.0.0.1:3000/"]
# מפעיל את server.js בצורת exec: התהליך הוא PID 1 ומקבל SIGTERM ב-docker stop.
CMD ["node", "server.js"]
# היסטוריית Git: גדולה, ועלולה להכיל סודות שהוסרו מהקוד.
.git
# קובצי סביבה ומפתחות: אחרת COPY . . מכניס אותם ל-image, שם כל מי שמושך אותו
# יכול לקרוא אותם.
.env
.env.*
*.pem
*.key
# קובצי ה-Docker עצמם: האפליקציה לא צריכה אותם, ושינוי בהם היה מבטל את ה-cache
# של שכבת קוד המקור.
Dockerfile
.dockerignore
compose*.y*ml
docker-compose*.y*ml
# לוגים וקובצי עורך.
*.log
.DS_Store
.idea
.vscode
# תלויות שהותקנו במחשב שלכם: ה-image מתקין משלו, עבור הפלטפורמה שלו.
node_modules
npm-debug.log*
coverage
הממצאים של ה-Dockerfile Linter עליו:
ממצאים
0 ממצאים: 0 שגיאה, 0 גבוהה, 0 בינונית, 0 נמוכה, 0 מידע.
אין ממצאים.
מגבלות
- המחולל כותב את הקבצים; הוא לא בונה אותם, ולא קורא את ה-repository שלכם כדי לזהות את ה-runtime או את ה-framework.
- הפרויקט צריך להתאים למה שה-Dockerfile מצפה לו (קובץ נעילה, הקובץ להרצה, סקריפט build); ההערות שמתחת לפלט מפרטות זאת לפי הבחירות שלכם.
- תגים כמו node:24-alpine מקבלים עדכוני אבטחה בתוך קו הגרסה שלהם. כדי להקפיא image מדויק, מוסיפים את ה-digest שלו ומעדכנים אותו במכוון.
- service אחד לכל Dockerfile: monorepos, תלויות build נייטיב, registries פרטיים ו-build secrets דורשים שינויים שהמחולל לא עושה.
מתודולוגיה: איך מחושבים המספרים
מקורות
- Docker Docs: Dockerfile reference
- Docker Docs: Building best practices
- Docker Docs: Build checks
- Docker Docs: Build secrets
- Docker Docs: Build context and .dockerignore
- Docker Docs: Multi-stage builds
- Docker Docs: Optimize cache usage
- Node.js: Release schedule
- Python: Status of Python versions
- Go: Release policy
- uv: Using uv in Docker
- Distroless container images
- nginx: unprivileged image
- Eclipse Temurin: Docker images
קשורים
הצעד הבא
כלי ציבורי חינמי של אנרוק, חברה שבונה תשתיות מחשוב. מה אנרוק בונה