Docker Compose startup order với depends_on và healthcheck trên Linux server

Docker Compose startup order đúng cách: depends_on + healthcheck để tránh app crash

Bạn chạy docker compose up cho stack app + database, container app lên trước vài giây và fail ngay vì DB chưa ready. Đây là lỗi rất phổ biến khi triển khai local lẫn production nhỏ. Bài này hướng dẫn cách xử lý chuẩn bằng depends_on kết hợp healthcheck để startup order hoạt động đúng như kỳ vọng.

Vì sao depends_on một mình chưa đủ?

Trong Docker Compose, depends_on giúp xác định thứ tự tạo service, nhưng mặc định chỉ đảm bảo service phụ thuộc đã “running”, không đảm bảo “ready”.

Ví dụ DB container đã chạy nhưng Postgres vẫn đang khởi tạo WAL, apply config hoặc tạo user. Nếu app connect ngay lúc đó, bạn gặp lỗi:

  • connection refused
  • timeout expired
  • database system is starting up

Prerequisites

  • Docker Engine + Docker Compose plugin mới
  • File compose.yaml
  • App có cơ chế retry kết nối DB (khuyến nghị)

Cấu hình mẫu: web phụ thuộc Postgres và Redis

services:
  web:
    build: .
    depends_on:
      db:
        condition: service_healthy
        restart: true
      redis:
        condition: service_started
    environment:
      DB_HOST: db
      REDIS_HOST: redis

  db:
    image: postgres:16
    environment:
      POSTGRES_DB: appdb
      POSTGRES_USER: appuser
      POSTGRES_PASSWORD: supersecret
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 20s

  redis:
    image: redis:7

Ý nghĩa nhanh

  • service_healthy: chờ DB pass healthcheck rồi mới start web
  • service_started: chỉ cần Redis đã chạy
  • restart: true dưới dependency: khi bạn chủ động restart/update db qua Compose operation, web cũng được restart để reconnect sạch

Startup order khuyến nghị cho stack phổ biến

  1. Stateful services: DB, queue, cache
  2. Migration job (nếu có)
  3. API service
  4. Worker/cron service

Nếu có migration riêng, dùng service_completed_successfully cho migration job để API chỉ chạy khi migrate thành công.

Mẫu với migration service

services:
  migrate:
    image: myapp:latest
    command: ["sh", "-c", "./migrate.sh"]
    depends_on:
      db:
        condition: service_healthy

  api:
    image: myapp:latest
    depends_on:
      migrate:
        condition: service_completed_successfully

Cách này giảm tình trạng API lên trước khi schema sẵn sàng.

Troubleshooting: app vẫn lỗi dù đã có healthcheck

1) Healthcheck “pass giả”

pg_isready pass nhưng schema/changelog chưa xong. Cách xử lý:

  • Tách migration service riêng
  • App có startup retry 30-60 giây

2) start_period quá ngắn

DB nặng dữ liệu có thể cần lâu hơn để ổn định. Tăng start_periodretries.

3) App fail-fast không retry

Compose không thay thế retry logic trong app. Nên cấu hình:

  • Exponential backoff
  • Max retry hợp lý
  • Log rõ nguyên nhân kết nối

4) Nhầm biến môi trường trong healthcheck

Dùng $$ trong YAML để escape biến shell đúng cách:

  • Đúng: $${POSTGRES_USER}
  • Sai: ${POSTGRES_USER} (có thể bị compose interpolate sai ngữ cảnh)

Best practices production nhỏ

  • Luôn có healthcheck cho DB, cache, API
  • Tách migration thành service riêng
  • Không hardcode secret trong compose file
  • Dùng .env hoặc secret manager
  • Theo dõi log startup bằng docker compose logs -f

FAQ — docker compose startup order

1) depends_on có chờ service ready không?

Mặc định không. Cần condition: service_healthy + healthcheck.

2) Có cần retry trong app nữa không?

Có. Retry trong app vẫn cần để chống network jitter và race condition hiếm.

3) Khi nào dùng service_completed_successfully?

Khi service phụ thuộc là one-shot job như migrate schema hoặc init data.

4) restart: true trong depends_on dùng để làm gì?

Giúp service phụ thuộc (ví dụ web) restart theo khi dependency bị restart/update qua thao tác Compose.

5) Có nên dùng script wait-for-it.sh thay healthcheck?

Có thể dùng, nhưng healthcheck + condition là cách native, rõ ràng và dễ maintain hơn.

Kết luận

Nếu bạn muốn stack ổn định ngay từ lệnh docker compose up, hãy xem startup order như một phần thiết kế hệ thống, không phải vá lỗi sau cùng. Cặp depends_on + healthcheck giải quyết phần lớn lỗi kết nối lúc boot, còn retry trong app giúp hệ thống “chịu đựng” tốt khi môi trường thực tế biến động.

# IMAGE PLAN

  • Featured keyword: docker containers monitoring dashboard on laptop, server room background
  • Inline 1 keyword: postgres database server rack blue lighting
  • Inline 2 keyword: software engineer terminal docker compose logs
  • Inline 3 keyword: microservices architecture diagram no text minimal
  • Alt text mẫu:

– docker compose startup order – giám sát container khi khởi động – docker compose startup order – postgres healthcheck trước khi app chạy – docker compose startup order – kiến trúc service phụ thuộc trong stack

# SOURCES

  • Docker Docs: https://docs.docker.com/compose/how-tos/startup-order/

Leave a Comment

Your email address will not be published. Required fields are marked *