Docker restart policy là lớp “tự phục hồi” cơ bản nhất khi chạy container trên VPS/server nhỏ: container crash thì tự bật lại, host reboot thì service lên theo Docker daemon. Nhưng nếu chọn sai policy, bạn có thể gặp restart loop, job chạy lặp vô hạn, hoặc tưởng healthcheck sẽ tự restart container trong khi Docker standalone không làm vậy.

Docker restart policy giải quyết vấn đề gì?
Restart policy cho Docker biết có nên khởi động lại container khi main process thoát, Docker daemon restart hoặc server reboot hay không. Trên production nhỏ không dùng Kubernetes/Swarm, đây là cách nhanh nhất để service web, reverse proxy, database phụ trợ hoặc worker không nằm chết sau một lỗi tạm thời.
Bài này áp dụng cho Docker Engine và Docker Compose hiện đại trên Ubuntu/Debian/AlmaLinux. Các ví dụ dùng Compose YAML, nhưng logic tương tự với lệnh docker run --restart hoặc docker update --restart.
4 policy chính: no, on-failure, always, unless-stopped
restart: “no”
no là mặc định: container dừng thì Docker không tự restart. Dùng cho migration, command chạy một lần, job backup chạy bằng cron/systemd timer, hoặc task mà chạy lặp lại có thể phá dữ liệu.
services:
migrate:
image: myapp:2026.07
command: php artisan migrate --force
restart: "no"
restart: on-failure[:max-retries]
on-failure chỉ restart khi process thoát với exit code khác 0. Đây là lựa chọn hợp lý cho worker, queue consumer, batch processor hoặc service mà exit 0 nghĩa là “đã hoàn tất”. Nên đặt giới hạn retry nếu lỗi có thể lặp mãi.
services:
worker:
image: myapp:2026.07
command: php artisan queue:work --tries=3
restart: on-failure:10
restart: unless-stopped
unless-stopped thường là default tốt cho service chạy lâu: web app, reverse proxy, Redis, Postgres, monitoring agent. Container sẽ restart sau crash hoặc reboot, nhưng nếu admin chủ động docker stop thì Docker tôn trọng trạng thái stopped đó.
services:
nginx:
image: nginx:1.27-alpine
ports:
- "80:80"
- "443:443"
restart: unless-stopped
restart: always
always restart mạnh tay hơn: nếu container bị stop thủ công, nó vẫn có thể bật lại khi Docker daemon restart. Dùng khi bạn thật sự muốn container luôn chạy bất kể trạng thái trước đó. Với đa số stack nhỏ, unless-stopped dễ vận hành hơn.
Healthcheck không tự restart container: đừng hiểu nhầm
Một nhầm lẫn rất phổ biến: cấu hình healthcheck rồi nghĩ Docker sẽ tự restart khi container chuyển sang unhealthy. Với Docker standalone, restart policy phản ứng khi main process exit, không tự restart chỉ vì healthcheck fail. Healthcheck vẫn rất hữu ích cho quan sát, dependency trong Compose, load balancer/orchestrator và alerting.
services:
api:
image: my-api:2026.07
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:8080/health || exit 1"]
interval: 30s
timeout: 5s
retries: 3
start_period: 40s
Nếu muốn container tự restart khi ứng dụng “kẹt logic” nhưng process vẫn sống, có 3 hướng: sửa app để exit non-zero khi trạng thái không thể phục hồi, dùng orchestrator có cơ chế reschedule, hoặc thêm watchdog/monitor bên ngoài. Đừng kỳ vọng healthcheck đơn lẻ làm việc đó.
Ví dụ Compose production cơ bản
services:
web:
image: nginx:1.27-alpine
restart: unless-stopped
depends_on:
api:
condition: service_healthy
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
api:
image: my-api:2026.07
restart: unless-stopped
environment:
DATABASE_URL: postgres://app:secret@db:5432/app
healthcheck:
test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:8080/health || exit 1"]
interval: 30s
timeout: 5s
retries: 3
start_period: 45s
worker:
image: my-api:2026.07
command: php artisan queue:work --sleep=3 --tries=3
restart: on-failure:10
db:
image: postgres:16-alpine
restart: unless-stopped
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
Ở ví dụ trên: web/api/db là service dài hạn nên dùng unless-stopped; worker dùng on-failure:10 để tránh retry vô hạn nếu code/config hỏng; healthcheck giúp Compose biết khi nào API đủ sẵn sàng cho service phụ thuộc.
Đổi restart policy cho container đang chạy
Nếu container đã chạy bằng docker run, có thể đổi bằng docker update:
docker ps --format 'table {{.Names}}\t{{.Status}}'
docker update --restart unless-stopped nginx
docker inspect -f '{{.HostConfig.RestartPolicy.Name}} {{.HostConfig.RestartPolicy.MaximumRetryCount}}' nginx
Với Compose, nên chỉnh trong compose.yml rồi redeploy để cấu hình nằm trong source:
docker compose config
docker compose up -d
Best practices khi dùng restart policy
- Không đặt always cho mọi thứ: migration/job một lần có thể chạy lặp và gây lỗi dữ liệu.
- Log rotation: container crash loop có thể spam log; cấu hình Docker logging hoặc logrotate. Xem thêm Linux logrotate cho Nginx, Docker và systemd.
- Graceful shutdown: app nên xử lý SIGTERM đúng, tránh mất job hoặc corrupt dữ liệu.
- Healthcheck nhẹ nhưng thật: kiểm tra endpoint nội bộ hoặc dependency quan trọng, không chỉ check port mở.
- Quan sát restart count: restart tự động không thay thế monitoring; cần alert nếu container restart liên tục.
- Backup volume: restart không cứu được mất dữ liệu; tham khảo backup Docker volumes bằng Restic.
Nếu đang xử lý thứ tự khởi động giữa app và database, bài Docker Compose startup order với depends_on + healthcheck sẽ đi sâu hơn về dependency.
Troubleshooting thường gặp
- Container restart liên tục: xem
docker logs --tail=200 container, kiểm tra env, volume permission, port conflict và exit code. - Healthcheck unhealthy nhưng không restart: đây là hành vi bình thường của Docker standalone; cần app exit hoặc monitor bên ngoài.
- Stop tay rồi reboot container vẫn bật: bạn có thể đang dùng
always; đổi sangunless-stoppednếu muốn tôn trọng stop tay. - Worker chạy lại job đã hoàn tất: đừng dùng
alwayscho one-shot job; dùngnohoặcon-failurecó giới hạn.
FAQ về Docker restart policy
Production nên dùng restart policy nào?
Với service chạy lâu, thường dùng unless-stopped. Worker/batch nên dùng on-failure có giới hạn. Job một lần nên dùng no.
Docker healthcheck có restart container không?
Không tự restart trong Docker standalone. Healthcheck chỉ đánh dấu trạng thái healthy/unhealthy; restart policy chỉ chạy khi process exit hoặc daemon/container lifecycle trigger phù hợp.
always khác unless-stopped thế nào?
always có xu hướng bật lại container sau daemon restart kể cả khi bạn từng stop tay. unless-stopped tôn trọng container đã bị stop thủ công.
Có nên dùng restart policy thay systemd không?
Nếu chỉ quản lý container, restart policy của Docker/Compose thường đủ. Nếu cần chạy task định kỳ hoặc quản lý lifecycle phức tạp ở host, có thể dùng systemd timer/service.
Kết luận
Docker restart policy nên được chọn theo mục đích workload: unless-stopped cho service dài hạn, on-failure cho worker, no cho one-shot job và chỉ dùng always khi thật sự cần bật lại vô điều kiện. Kết hợp thêm healthcheck, log rotation và monitoring để container không chỉ “sống” mà còn vận hành đúng.
Nguồn tham khảo: Docker Docs — Start containers automatically; Docker Compose production docs; Dockerfile HEALTHCHECK reference.
