Docker / Docker шилдэг туршлага

Docker шилдэг туршлага

Энэ хичээлд курсын туршид үзсэн бүх ойлголтыг нэгтгэнэ. Dockerfile бичих, container ажиллуулах, production-д бэлдэх — бүгдийн шилдэг туршлагуудыг checklist хэлбэрт оруулав.

Dockerfile шилдэг туршлага

1. Minimal base image сонгох

dockerfile
# ❌ Хэт том
FROM ubuntu:22.04
FROM node:20

# ✅ Зөвхөн шаардлагатай
FROM node:20-alpine
FROM python:3.12-slim

Жижиг image = хурдан pull, бага attack surface, бага диск зай.

2. Layer тоог цөөлөх

dockerfile
# ❌ Олон давхарга
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y git
RUN rm -rf /var/lib/apt/lists/*

# ✅ Нэг давхарга
RUN apt-get update && \
    apt-get install -y curl git && \
    rm -rf /var/lib/apt/lists/*

Давхарга бүр image-ийн хэмжээнд нэмэгддэг. Cache устгах нь зөвхөн тэр давхарга дотор хийгдвэл л ажиллана.

3. Layer cache-ийг ухаалаг ашиглах

dockerfile
# ❌ Буруу дараалал — src өөрчлөгдөх бүрт npm install дахин ажиллана
COPY . .
RUN npm ci

# ✅ Зөв дараалал — package.json өөрчлөгдөхгүй бол npm install алгасна
COPY package*.json ./
RUN npm ci
COPY . .

Цөөн өөрчлөгддөг файл эхэнд, их өөрчлөгддөг файл арад.

4. .dockerignore ашиглах

код
node_modules
dist
.git
.env
.env.*
*.md
coverage/
.nyc_output/
__pycache__
*.pyc
venv/

node_modules болон .git хуулагдвал image томорч, build удаашрана.

5. Multi-stage build ашиглах

dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine AS production
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/index.js"]

Dev tool, source file, compiler — production image-д оруулахгүй.

6. Root биш хэрэглэгч

dockerfile
RUN addgroup -S app && adduser -S app -G app
COPY --chown=app:app . .
USER app

7. HEALTHCHECK тавих

dockerfile
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
  CMD wget -qO- http://localhost:3000/health || exit 1

8. Тодорхой tag ашиглах

dockerfile
# ❌ latest өөрчлөгдөж болно
FROM node:latest
FROM postgres:latest

# ✅ Тодорхой version
FROM node:20-alpine
FROM postgres:16-alpine

Dockerfile checklist

код
□ Minimal base image (alpine / slim)
□ .dockerignore файл байна
□ Package файл эхэнд COPY хийгдсэн (cache оновчлол)
□ Cache устгах нь RUN-тай нэг давхарга дотор
□ Multi-stage build ашигласан (build tool production-д байхгүй)
□ Root биш USER тохируулсан
□ HEALTHCHECK байна
□ EXPOSE зааж өгсөн
□ CMD / ENTRYPOINT тодорхой
□ Нууц мэдээлэл Dockerfile-д байхгүй

Container ажиллуулах шилдэг туршлага

Нөөцийн хязгаарлалт

bash
docker run -d \
  --memory 512m \
  --cpus 0.5 \
  --restart unless-stopped \
  myapp

Restart policy

bash
# Container унавал автоматаар дахин эхлэх
docker run -d --restart unless-stopped myapp

# Зөвхөн алдаатай зогсвол дахин эхлэх (хамгийн ихдээ 3 удаа)
docker run -d --restart on-failure:3 myapp

Read-only файл систем

bash
docker run -d --read-only --tmpfs /tmp myapp

Docker Compose шилдэг туршлага

yaml
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    image: myapp:latest # build хийсний дараа нэр өгнө
    restart: unless-stopped
    mem_limit: 512m
    cpus: 0.5
    environment:
      - NODE_ENV=production
    env_file:
      - .env # нууц мэдээлэл тусдаа файлд
    ports:
      - "3000:3000"
    depends_on:
      db:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
      interval: 30s
      timeout: 5s
      start_period: 15s
      retries: 3
    networks:
      - backend

  db:
    image: postgres:16-alpine
    restart: unless-stopped
    mem_limit: 1g
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - backend

volumes:
  pgdata:

networks:
  backend:
    driver: bridge

Image удирдах шилдэг туршлага

bash
# Тодорхой version tag — latest биш
docker pull myapp:1.2.3

# Ашиглагдаагүй image цэвэрлэх
docker image prune -f

# Ашиглагдаагүй бүх зүйл цэвэрлэх
docker system prune -f

# Volume-тай хамт
docker system prune -f --volumes

Аюулгүй байдлын checklist

код
□ Base image тогтмол шинэчлэгддэг
□ Image scan (Trivy / docker scout) CI-д орсон
□ Нууц мэдээлэл environment variable-аар дамжуулагддаг
□ .env файл .gitignore-д орсон
□ Root биш USER ашиглаж байна
□ --read-only боломжтой бол тохируулсан
□ --memory, --cpus хязгаарлалт байна
□ Port хамгийн бага зайлшгүй шаардлагатай нь л нээлттэй

Production-ийн нэгдсэн checklist

код
□ Dockerfile
   □ alpine / slim base image
   □ .dockerignore байна
   □ Multi-stage build
   □ Non-root USER
   □ HEALTHCHECK

□ Container ажиллуулалт
   □ --restart unless-stopped
   □ --memory хязгаарлалт
   □ --cpus хязгаарлалт
   □ Environment variable-аар нууц мэдээлэл

□ Docker Compose
   □ healthcheck бүх сервист
   □ depends_on + condition
   □ Named volume (data persist)
   □ Custom network
   □ env_file

□ Registry ба CI/CD
   □ Тодорхой version tag (latest биш)
   □ Git SHA tag
   □ CI дахь cache
   □ Нууц мэдээлэл GitHub Secrets-т

Дараагийн хичээлд:

Эцсийн төсөл — Node.js + PostgreSQL + Nginx stack-ийг Docker Compose-оор ажиллуулна. Курсын туршид үзсэн бүх зүйлийг нэгтгэнэ.