Docker و Containerization
Docker انقلابی در deployment ایجاد کرد. هر میکروسرویس را در یک container ایزوله بستهبندی میکنیم که در هر محیطی یکسان اجرا میشود.
۱۰.۱ مقدمه
Docker انقلابی در deployment ایجاد کرد. هر میکروسرویس را در یک container ایزوله بستهبندی میکنیم که در هر محیطی یکسان اجرا میشود.
۱۰.۲ چرا Container؟
قبل از Docker: «روی سیستم من کار میکرد!» — مشکلی که هر developer میشناسد.
Container در مقابل VM
Virtual Machine:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ App A │ │ App B │ │ App C │
│ Bins/Libs │ │ Bins/Libs │ │ Bins/Libs │
│ Guest OS │ │ Guest OS │ │ Guest OS │ ← هر VM یک OS کامل
└─────────────┘ └─────────────┘ └─────────────┘
Hypervisor (VMware, KVM)
Host OS
Hardware
Container:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ App A │ │ App B │ │ App C │
│ Bins/Libs │ │ Bins/Libs │ │ Bins/Libs │ ← فقط application
└─────────────┘ └─────────────┘ └─────────────┘
Docker Engine
Host OS
Hardware
نتیجه:
- Container: شروع در ثانیه، MB حافظه
- VM: شروع در دقیقه، GB حافظه
۱۰.۳ Dockerfile
دستورالعمل ساخت یک image. هر دستور یک layer ایجاد میکند.
Dockerfile پایه برای FastAPI
FROM python:3.11-slim
# Working directory
WORKDIR /app
# Install dependencies (cache-friendly: requirements اول)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy code
COPY . .
# Non-root user
RUN useradd -m -u 1000 appuser
USER appuser
# Expose port
EXPOSE 8000
# Health check
HEALTHCHECK --interval=30s --timeout=3s --retries=3
CMD curl -f http://localhost:8000/health || exit 1
# Start command
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Dockerfile پایه برای Django
FROM python:3.11-slim
# System deps
RUN apt-get update && apt-get install -y --no-install-recommends
build-essential
libpq-dev
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Python deps
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Code
COPY . .
# Static files
RUN python manage.py collectstatic --noinput
# Non-root
RUN useradd -m django
USER django
EXPOSE 8000
CMD ["gunicorn", "myproject.wsgi:application",
"--bind", "0.0.0.0:8000",
"--workers", "4",
"--threads", "2",
"--timeout", "120"]
۱۰.۴ Multi-Stage Build
برای کاهش اندازه image، build و runtime را جدا میکنیم.
# Stage 1: Builder
FROM python:3.11 AS builder
WORKDIR /build
# Install build deps
RUN apt-get update && apt-get install -y
build-essential gcc
# Install python deps در virtualenv
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Stage 2: Runtime (slim)
FROM python:3.11-slim
# Copy فقط virtualenv از builder
COPY --from=builder /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
WORKDIR /app
COPY . .
USER 1000:1000
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0"]
نتیجه: اندازه image از ~1GB به ~150MB کاهش مییابد!
۱۰.۵ بهینهسازی Image
- Base image سبک: alpine، slim، distroless
- Layer ordering: چیزهای کمتر تغییرپذیر اول
- Combine RUN commands: با
&& - .dockerignore: exclude کردن فایلهای غیرضروری
- Multi-stage: build artifacts فقط
- No-cache: apt و pip را با no-cache
- Specific tags: python:3.11.7-slim نه python:latest
.dockerignore
.git
.gitignore
*.md
__pycache__
*.pyc
.pytest_cache
.coverage
.env
.venv
venv/
node_modules/
.idea/
.vscode/
docs/
tests/
۱۰.۶ Docker Compose
برای مدیریت چندین container در محیط dev/test.
docker-compose.yml کامل
version: "3.9"
services:
# PostgreSQL
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: shop
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- pg_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
networks:
- backend
# Redis
redis:
image: redis:7-alpine
command: redis-server --appendonly yes
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
networks:
- backend
# RabbitMQ
rabbitmq:
image: rabbitmq:3.12-management-alpine
environment:
RABBITMQ_DEFAULT_USER: admin
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD}
ports:
- "15672:15672" # Management UI
volumes:
- rabbitmq_data:/var/lib/rabbitmq
healthcheck:
test: rabbitmq-diagnostics check_running
interval: 30s
networks:
- backend
# User Service
user-service:
build:
context: ./services/user
dockerfile: Dockerfile
environment:
DATABASE_URL: postgresql://postgres:${DB_PASSWORD}@postgres/shop_users
REDIS_URL: redis://redis:6379/0
JWT_SECRET: ${JWT_SECRET}
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
deploy:
replicas: 2
restart_policy:
condition: on-failure
networks:
- backend
- frontend
# Product Service
product-service:
build: ./services/product
environment:
DATABASE_URL: postgresql://postgres:${DB_PASSWORD}@postgres/shop_products
REDIS_URL: redis://redis:6379/1
ELASTICSEARCH_URL: http://elasticsearch:9200
depends_on:
- postgres
- redis
networks:
- backend
- frontend
# Order Service
order-service:
build: ./services/order
environment:
DATABASE_URL: postgresql://postgres:${DB_PASSWORD}@postgres/shop_orders
RABBITMQ_URL: amqp://admin:${RABBITMQ_PASSWORD}@rabbitmq
depends_on:
- postgres
- rabbitmq
networks:
- backend
- frontend
# API Gateway (Traefik)
gateway:
image: traefik:v3.0
command:
- "--providers.docker=true"
- "--providers.docker.exposedByDefault=false"
- "--entrypoints.web.address=:80"
- "--api.dashboard=true"
- "--api.insecure=true"
ports:
- "80:80"
- "8080:8080" # Dashboard
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- frontend
labels:
- "traefik.enable=true"
volumes:
pg_data:
redis_data:
rabbitmq_data:
networks:
frontend:
backend:
internal: true # دسترسی از بیرون ندارد
دستورات کلیدی
# Build و start
docker-compose up -d --build
# لاگها
docker-compose logs -f user-service
# اجرای دستور در container
docker-compose exec user-service python manage.py migrate
# Scale
docker-compose up -d --scale user-service=5
# Stop و حذف
docker-compose down -v # -v حجمها را هم پاک میکند
۱۰.۷ Networking
انواع network در Docker
- bridge: پیشفرض، isolated network
- host: استفاده از network host (بدون isolation)
- overlay: برای multi-host (Swarm)
- none: بدون network
- macvlan: هر container IP فیزیکی
دسترسی بین Container ها
در شبکه custom (مثل backend بالا):
- container ها از طریق نام service به هم دسترسی دارند
- user-service میتواند به postgres با اسم `postgres` وصل شود
- DNS خودکار توسط Docker انجام میشود
از خارج:
- فقط ports که با `ports:` expose شدهاند
- تفاوت ports vs expose:
- ports: 8080:80 → دسترسی از host
- expose: 80 → فقط داخل docker network
۱۰.۸ Volumes و Data Persistence
سه نوع mount
- Volume: Docker مدیریت میکند (پیشنهاد)
- Bind mount: path از host (برای dev مناسب)
- tmpfs: در memory
services:
postgres:
volumes:
- pg_data:/var/lib/postgresql/data # named volume
- ./init.sql:/docker-entrypoint-initdb.d/init.sql # bind mount
volumes:
pg_data:
driver: local
driver_opts:
type: none
o: bind
device: /data/postgres # path روی host
۱۰.۹ امنیت Container
- Non-root user: هیچگاه root اجرا نکنید
- Image scanning: Trivy، Snyk، Clair
- Secrets management: از Docker Secrets یا Vault
- Read-only filesystem:
read_only: true - Capabilities: drop unused capabilities
- Limit resources: CPU، memory limits
- No privileged: هرگز
privileged: trueنگذارید - Update images: regularly
services:
user-service:
image: shop/user-service:1.2.3 # specific version
read_only: true
user: "1000:1000"
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
security_opt:
- no-new-privileges:true
deploy:
resources:
limits:
cpus: "0.5"
memory: 512M
reservations:
cpus: "0.25"
memory: 256M
tmpfs:
- /tmp:noexec,nosuid,size=64M
۱۰.۱۰ بهترین تجربیات
- One process per container.
- Stateless containers. state در volume یا DB.
- Use specific tags. هیچگاه latest در production.
- Multi-stage builds.
- .dockerignore.
- Non-root user.
- Health checks.
- Log به stdout/stderr. نه فایل.
- Environment variables برای config.
- Resource limits.
- Image scanning در CI.
- Layer caching بهینه.
۱۰.۱۱ خلاصه فصل
آنچه آموختیم:
- Container vs VM — کاربرد و تفاوتها
- Dockerfile برای Django و FastAPI
- Multi-stage build برای کاهش اندازه
- Docker Compose برای orchestration محلی
- Networking و service discovery داخلی
- Volumes برای data persistence
- امنیت container در production
در فصل بعد: Kubernetes — orchestration در مقیاس production.