Docker compose restart policy
Restart policy and health checks for Docker Compose services.
- series
- Docker Workshop
- episode
- ตอนที่ 12 จาก 17
- read
- อ่าน 3 นาที
Restart policy
ใน docker compose services หาก service ตายไป เราสามารถให้ docker restart ตัวเองกลับมาได้ด้วย
networks: my_bridge2: external: true name: my_bridge1
services: next: build: context: . environment: NODE_ENV: production ports: - 3001:3000 restart: unless-stopped networks: - my_bridge2 backend: container_name: hono image: hono environment: NODE_ENV: production ports: - 3333:3333 volumes: - ./uploads:/app/uploads restart: unless-stopped networks: - my_bridge2โดย option ที่ใส่ได้ก็จะมี
noคือไม่ต้อง restartalwaysจะ restart เสมอ จนกว่ามันจะถูกลบออกไปon-failure[:max number of retries]จะ restart เมื่อ container ตาย ระบุจำนวนการ restart ได้ด้วยunless-stoppedจะ restart เมื่อ container ตาย แต่ถ้าเรา stop ไว้ มันจะไม่ restart กลับมาเองนะ
Health check
จากการที่เราใส่ restart policy เข้าไปนั้น มันจะ restart ก็ต่อเมื่อ container มันตายไป หรือได้ exit code มา
การใส่ Health check คือการที่เราบอก docker ถึงวิธีการที่จะทำให้ docker รู้ว่า container เรายังทำงานอยู่ดีไหม เมื่อ health check failed ก็จะไป restart container ไปตาม restart policy ที่ตั้งไว้
เราสามารถใส่ Health check แบบนี้
networks: my_bridge2: external: true name: my_bridge1
services: next: build: context: . environment: NODE_ENV: production ports: - 3001:3000 restart: unless-stopped healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:3000 || exit 1"] interval: 1m timeout: 10s retries: 3 start_period: 0s networks: - my_bridge2 backend: container_name: hono image: hono environment: NODE_ENV: production ports: - 3333:3333 volumes: - ./uploads:/app/uploads restart: unless-stopped healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:3333/healthz || exit 1"] interval: 1m timeout: 10s retries: 3 start_period: 20s networks: - my_bridge2จะเห็นว่าเราใช้ curl ในการ check container health
ฉนั้นเราต้องใส่ curl package ลงไปใน container ด้วย
ยกตัวอย่างส่วนของ backend ละกัน
# Dockerfile# syntax=docker/dockerfile:1ARG NODE_VERSION=22.2.0ARG PNPM_VERSION=8.15.5
# BuildFROM node:${NODE_VERSION}-alpine AS build
# Install pnpm.RUN --mount=type=cache,target=/root/.npm \ npm install -g pnpm@${PNPM_VERSION}
WORKDIR /app
RUN --mount=type=bind,source=package.json,target=package.json \ --mount=type=bind,source=pnpm-lock.yaml,target=pnpm-lock.yaml \ --mount=type=cache,target=/root/.local/share/pnpm/store \ pnpm install --frozen-lockfile
COPY . .
RUN pnpm run build && pnpm prune --prod
# FinalFROM node:${NODE_VERSION}-alpine AS runner
ENV NODE_ENV=productionWORKDIR /app
RUN apk --no-cache add curl
# add nonroot user and groupRUN addgroup --system --gid 1001 nodejs && adduser --system --uid 1001 nonroot
# make uploads folderRUN mkdir -p ./uploads && chmod 700 ./uploads && chown -R nonroot:nodejs ./uploads
# when copy use flag --chown=<user>:<group>COPY --from=build --chown=nonroot:nodejs /app/dist ./distCOPY --from=build --chown=nonroot:nodejs /app/node_modules ./node_modulesCOPY --from=build --chown=nonroot:nodejs /app/package.json ./package.json
# finally use nonroot userUSER nonroot
EXPOSE 3333
CMD ["node", "dist/index.js"]