Docker аюулгүй байдал
Container нь тусгаарлалт үүсгэдэг ч буруу тохируулбал аюулгүй байдлын нүх үүсч болно. Энэ хичээлд production-д заавал мөрдөх дүрмүүдийг үзнэ.
Root-аар ажиллуулахгүй байх
Анхдагч байдлаар Docker container нь root хэрэглэгчээр ажиллана. Container дотор root эрхтэй байх нь аюулгүй биш:
docker run -it node:20 whoami
# root ← аюулгүй биш!
Хэрэв аппликейшнийг тасалдуулаад container дотор орвол root эрхтэй байх болно.
USER instruction
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY dist/ ./dist/
# Тусгай хэрэглэгч үүсгэх
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# Файлуудын өмчлөгчийг тохируулах
RUN chown -R appuser:appgroup /app
# Root биш хэрэглэгч болгон солих
USER appuser
EXPOSE 3000
CMD ["node", "dist/index.js"]
docker run myapp whoami
# appuser ← аюулгүй
node image-ийн бэлэн хэрэглэгч
node:20 image-д node нэртэй хэрэглэгч аль хэдийн байдаг:
FROM node:20-alpine
WORKDIR /app
COPY --chown=node:node package*.json ./
RUN npm ci --only=production
COPY --chown=node:node dist/ ./dist/
USER node
CMD ["node", "dist/index.js"]
--chown=node:node — COPY хийхэд шууд өмчлөгч тавих.
Minimal base image
Image-д байгаа бүх package нь потенциал аюулгүй байдлын нүх. Хэрэглэгдэхгүй зүйлс байхгүй байх нь дээр:
# ❌ Хэтэрхий том — олон шаардлагагүй хэрэгсэл
FROM ubuntu:22.04
# ✅ Зөвхөн шаардлагатай зүйл агуулсан
FROM node:20-alpine
# ✅ Хамгийн жижиг — зөвхөн compiled binary
FROM scratch
Alpine-д shell хязгаарлагдмал тул attack surface багасна.
Дистроллес image (Google):
FROM gcr.io/distroless/nodejs20-debian12
Shell огт байхгүй — docker exec ажиллахгүй. Production-д хамгийн аюулгүй, debugging хэцүү.
Нууц мэдээлэл зохицуулах
Dockerfile-д нууц мэдээлэл оруулахгүй
# ❌ Image-д орно — history-д үлдэнэ!
ENV DATABASE_URL=postgresql://user:password@db/myapp
ENV API_KEY=sk-1234567890abcdef
# ❌ Build үед нууц мэдээлэл оруулах
RUN curl -H "Authorization: Bearer hardcoded-token" https://api.example.com
Image-ийн history-г хэн ч харж болно:
docker history myimage
# IMAGE layer бүрийн команд харагдана
Зөв арга: Runtime environment variable
# Container ажиллуулахдаа дамжуулна
docker run -e DATABASE_URL=postgresql://... -e API_KEY=sk-... myapp
# docker-compose.yml
services:
app:
image: myapp
environment:
- DATABASE_URL=${DATABASE_URL}
- API_KEY=${API_KEY}
env_file:
- .env
.env файлыг .gitignore-д нэмнэ — Git-т ороогүй байна.
Docker secrets (Swarm)
echo "mysecretpassword" | docker secret create db_password -
docker service create \
--name myapp \
--secret db_password \
myimage
Container доторх /run/secrets/db_password файлаас унших.
Multi-stage build-д нууц мэдээлэл
# ✅ BuildKit-ийн secret mount — final image-д орохгүй
FROM node:20-alpine AS builder
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc \
npm ci
docker build --secret id=npmrc,src=.npmrc .
Image scan
docker scout (орчин үеийн)
# Scout суулгагдсан бол
docker scout cves myimage
# Зөвлөмж авах
docker scout recommendations myimage
Trivy (гуравдагч хэрэгсэл)
# Trivy суулгах (Alpine)
docker run aquasec/trivy image myimage
# Зөвхөн HIGH, CRITICAL эмзэг байдал
docker run aquasec/trivy image --severity HIGH,CRITICAL myimage
Гаралт:
myimage (alpine 3.19.0)
Total: 3 (HIGH: 2, CRITICAL: 1)
┌────────────────┬────────────────┬──────────┬──────────────────┐
│ Library │ Vulnerability │ Severity │ Installed Version│
├────────────────┼────────────────┼──────────┼──────────────────┤
│ openssl │ CVE-2024-0001 │ CRITICAL │ 3.1.4-r1 │
└────────────────┴────────────────┴──────────┴──────────────────┘
Read-only файл систем
Container-ийн файл системийг зөвхөн унших горимд тавих:
docker run --read-only myapp
services:
app:
image: myapp
read_only: true
tmpfs:
- /tmp # бичих шаардлагатай бол tmpfs
Capabilities хязгаарлах
Linux capabilities-ийг хязгаарлаж, зөвхөн шаардлагатайг нь үлдээнэ:
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE myapp
Аюулгүй байдлын хураангуй дүрмүүд
# 1. Minimal base image
FROM node:20-alpine
# 2. Root биш хэрэглэгч
RUN addgroup -S app && adduser -S app -G app
USER app
# 3. Зөвхөн шаардлагатай файл хуулах
COPY --chown=app:app dist/ ./dist/
COPY --chown=app:app package*.json ./
RUN npm ci --only=production
# 4. Нууц мэдээлэл Dockerfile-д огт байхгүй
# (runtime -e flag эсвэл env_file ашиглана)
# 5. Healthcheck
HEALTHCHECK --interval=30s CMD wget -qO- http://localhost:3000/health || exit 1
Дараагийн хичээлд:
HEALTHCHECK instruction-ийг дэлгэрэнгүй үзнэ — container эрүүл эсэхийг автоматаар шалгах.