Docker שינה את הדרך שבה אנחנו בונים, מפיצים ומריצים תוכנה. במקום "עובד על המחשב שלי", Docker מבטיח שהאפליקציה שלכם רצה באותו אופן בכל מקום - על הלפטופ שלכם, על המחשב של עמית, ב-CI/CD ובפרודקשן. במדריך זה, נעבור מאפס ועד לדיפלוי של אפליקציה אמיתית.
מה זה Docker?
Docker הוא פלטפורמה שאורזת את האפליקציה שלכם ואת כל התלויות שלה ליחידה סטנדרטית שנקראת קונטיינר. קונטיינר הוא תהליך מבודד וקל משקל שחולק את הקרנל של מערכת ההפעלה המארחת אבל יש לו מערכת קבצים, רשת ומרחב תהליכים משלו.
קונטיינרים לעומת מכונות וירטואליות
| היבט | קונטיינרים | מכונות וירטואליות |
|---|---|---|
| הפעלה | שניות | דקות |
| גודל | MB | GB |
| מערכת הפעלה | חולק קרנל מארח | מערכת הפעלה אורחת מלאה |
| בידוד | ברמת תהליך | ברמת חומרה |
| ביצועים | כמעט נייטיב | תקורה מהיפרוויזור |
| צפיפות | מאות למארח | עשרות למארח |
התקנת Docker
# macOS brew install --cask docker # Ubuntu/Debian curl -fsSL https://get.docker.com | sh sudo usermod -aG docker $USER # Verify installation docker --version docker run hello-world
מושגי יסוד
אימג׳ים
אימג׳ הוא תבנית לקריאה בלבד עם הוראות ליצירת קונטיינר. חשבו על זה כתמונת מצב של האפליקציה והסביבה שלה.
# Pull an image from Docker Hub docker pull node:20-alpine # List local images docker images # Remove an image docker rmi node:20-alpine
קונטיינרים
קונטיינר הוא מופע פעיל של אימג׳. אתם יכולים ליצור, להפעיל, לעצור ולמחוק קונטיינרים.
# Run a container docker run -d --name my-app -p 3000:3000 node:20-alpine # List running containers docker ps # List all containers (including stopped) docker ps -a # Stop a container docker stop my-app # Remove a container docker rm my-app # View logs docker logs my-app # Execute a command inside a running container docker exec -it my-app sh
כתיבת Dockerfile
Dockerfile הוא קובץ טקסט עם הוראות לבניית אימג׳. כל הוראה יוצרת שכבה.
Dockerfile בסיסי לאפליקציית Node.js
# Use an official Node.js runtime as base image FROM node:20-alpine # Set working directory WORKDIR /app # Copy package files first (better caching) COPY package.json package-lock.json ./ # Install dependencies RUN npm ci --only=production # Copy application code COPY . . # Expose the port the app runs on EXPOSE 3000 # Command to run the application CMD ["node", "server.js"]
בנייה והרצה
# Build the image docker build -t my-node-app . # Run the container docker run -d -p 3000:3000 my-node-app # Visit http://localhost:3000
בנייה רב-שלבית
בנייה רב-שלבית שומרת על אימג׳י הפרודקשן קטנים על ידי הפרדת סביבת הבנייה מסביבת הריצה.
# Stage 1: Build FROM node:20-alpine AS builder WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci COPY . . RUN npm run build # Stage 2: Production FROM node:20-alpine AS runner WORKDIR /app COPY /app/dist ./dist COPY /app/node_modules ./node_modules COPY /app/package.json ./ EXPOSE 3000 CMD ["node", "dist/server.js"]
זה מייצר אימג׳ עם רק הפלט המקומפל ותלויות הפרודקשן - ללא קוד מקור, ללא תלויות פיתוח, ללא כלי בנייה.
דוגמה רב-שלבית ל-Next.js
FROM node:20-alpine AS deps WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci FROM node:20-alpine AS builder WORKDIR /app COPY /app/node_modules ./node_modules COPY . . RUN npm run build FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production COPY /app/public ./public COPY /app/.next/standalone ./ COPY /app/.next/static ./.next/static EXPOSE 3000 CMD ["node", "server.js"]
ווליומים: נתונים קבועים
כברירת מחדל, נתונים בתוך קונטיינר אובדים כאשר הקונטיינר מוסר. ווליומים פותרים את זה.
# Create a named volume docker volume create my-data # Run with a volume docker run -d -v my-data:/app/data my-app # Bind mount (map host directory to container) docker run -d -v $(pwd)/data:/app/data my-app # List volumes docker volume ls
רשתות
Docker יוצר רשתות מבודדות כדי שקונטיינרים יוכלו לתקשר.
# Create a custom network docker network create my-network # Run containers on the same network docker run -d --name api --network my-network my-api docker run -d --name db --network my-network postgres:16 # Containers can reach each other by name # From "api" container: postgres://db:5432
Docker Compose
Docker Compose מאפשר לכם להגדיר ולהריץ אפליקציות רב-קונטיינריות עם קובץ YAML אחד.
docker-compose.yml
services: api: build: ./api ports: - "3000:3000" environment: - DATABASE_URL=postgres://user:pass@db:5432/mydb depends_on: - db db: image: postgres:16-alpine environment: - POSTGRES_USER=user - POSTGRES_PASSWORD=pass - POSTGRES_DB=mydb volumes: - pgdata:/var/lib/postgresql/data ports: - "5432:5432" redis: image: redis:7-alpine ports: - "6379:6379" volumes: pgdata:
פקודות
# Start all services docker compose up -d # View logs docker compose logs -f # Stop all services docker compose down # Rebuild and restart docker compose up -d --build # Scale a service docker compose up -d --scale api=3
.dockerignore
כמו .gitignore, קובץ זה מונע מקבצים מיותרים להיות מועתקים לאימג׳.
node_modules .git .env *.md .next dist coverage
שיטות עבודה מומלצות לפרודקשן
1. השתמשו באימג׳י בסיס קטנים
# Bad: 1GB+ FROM node:20 # Good: ~180MB FROM node:20-alpine
2. אל תריצו כ-Root
FROM node:20-alpine RUN addgroup -S app && adduser -S app -G app USER app WORKDIR /home/app COPY . .
3. השתמשו בתגיות אימג׳ ספציפיות
# Bad: can change unexpectedly FROM node:latest # Good: pinned version FROM node:20.11-alpine3.19
4. נצלו את מטמון הבנייה
סדרו את הוראות ה-Dockerfile מהפחות לכי יותר משתנות:
FROM node:20-alpine WORKDIR /app # These change rarely - cached COPY package.json package-lock.json ./ RUN npm ci --only=production # This changes often - not cached COPY . .
5. בדיקות תקינות
HEALTHCHECK \ CMD wget -qO- http://localhost:3000/health || exit 1
6. השתמשו במשתני סביבה
ENV NODE_ENV=production ENV PORT=3000
דף עזר לפקודות Docker נפוצות
# Images docker build -t name:tag . # Build image docker images # List images docker rmi image_name # Remove image docker image prune # Remove unused images # Containers docker run -d -p 3000:3000 image # Run detached docker ps # List running docker stop container_name # Stop docker rm container_name # Remove docker logs -f container_name # Follow logs docker exec -it container sh # Shell into container # Compose docker compose up -d # Start services docker compose down # Stop services docker compose logs -f # Follow all logs docker compose ps # List services # Cleanup docker system prune -a # Remove everything unused
מ-Docker ל-Kubernetes
Docker מנהל קונטיינרים בודדים. כאשר אתם צריכים לתזמר מאות קונטיינרים על פני מספר שרתים, אתם צריכים Kubernetes. Docker ו-Kubernetes משלימים זה את זה:
- Docker: בונה ומריץ קונטיינרים
- Kubernetes: מתזמר קונטיינרים בקנה מידה (תזמון, שינוי קנה מידה, ריפוי עצמי)
אם אתם מעוניינים בצעד הבא, בדקו את המאמר שלי על מבוא ל-Kubernetes.
סיכום
Docker הוא מיומנות בסיסית למפתחים מודרניים. הוא מבטל חוסר עקביות בסביבות, מפשט את הדיפלוי, ומהווה את הבסיס לתזמור קונטיינרים עם Kubernetes. התחילו עם Dockerfile פשוט, עברו ל-Docker Compose לאפליקציות רב-שירותיות, ואמצו בנייה רב-שלבית ושיטות עבודה מומלצות לאבטחה ככל שתתקדמו.
הדרך הטובה ביותר ללמוד Docker היא לקנטיינר פרויקט שאתם כבר עובדים עליו. התחילו היום.