Quick Reference
docker run -d --restart unless-stopped my-appno는 자동 재시작이 없고, on-failure[:N]은 non-zero 종료만 다시 시도합니다. always와 unless-stopped는 종료 코드를 가리지 않지만, 수동 중지와 Docker daemon 재시작에서 다르게 동작합니다. healthcheck의 unhealthy 상태만으로는 어느 정책도 컨테이너를 재시작하지 않습니다.
정책 선택
no / on-failure / always / unless-stopped 정책의 차이
네 가지 정책은 "언제 재시작하는가"를 기준으로 구분된다. no는 자동 재시작을 하지 않는다. on-failure는 종료 코드가 0이 아닐 때만 재시작한다. always는 종료 이유와 무관하게 항상 재시작하고 Docker 데몬 재시작 후에도 자동으로 올라온다. unless-stopped는 always와 유사하지만 사용자가 명시적으로 중지한 컨테이너는 데몬 재시작 후에도 그 상태를 유지한다.
# 개발 환경: 수동 제어 (기본값)
docker run -d --restart no my-app
# 배치 작업: 실패 시만 재시작
docker run -d --restart on-failure my-job
# 장기 실행 서비스: 항상 재시작
docker run -d --restart always my-server
# 운영 서비스: 명시적 중지는 존중
docker run -d --restart unless-stopped my-servicealways와 unless-stopped의 차이 — docker stop 후 재시작 여부
always는 docker stop으로 컨테이너를 중지하면 daemon이 재시작되거나 사용자가 컨테이너를 다시 시작할 때 재시작된다. unless-stopped는 사용자가 명시적으로 중지한 상태를 기억해 daemon 재시작 후에도 중지 상태를 유지한다. 운영 중 점검이나 단계적 배포 시 unless-stopped가 더 예측 가능한 동작을 한다.
# always: docker stop 후 데몬 재시작하면 컨테이너도 재시작
docker run -d --restart always my-app
docker stop my-app
# systemctl restart docker
# → my-app이 다시 시작됨
# unless-stopped: docker stop 후 데몬 재시작해도 중지 상태 유지
docker run -d --restart unless-stopped my-app
docker stop my-app
# systemctl restart docker
# → my-app은 중지 상태 유지on-failure:N으로 재시작 횟수를 제한하는 이유
무한 재시작은 근본적인 문제를 숨기고 리소스를 낭비한다. on-failure:3처럼 최대 횟수를 지정하면 반복 실패 후 멈추어 알림과 조사를 유도한다. 배치 작업이나 초기화 실패 가능성이 있는 서비스에 적합하다.
# 최대 3회까지만 재시작 시도
docker run -d --restart on-failure:3 my-job
# 재시작 횟수 확인
docker inspect --format='{{.RestartCount}}' my-job재시작 정책이 적용되지 않는 경우
restart policy는 컨테이너가 최소 10초 이상 정상적으로 떠 Docker가 감시를 시작한 뒤 적용됩니다. 수동 docker stop 뒤에는 daemon이 재시작되거나 컨테이너를 다시 시작하기 전까지 policy가 무시됩니다. on-failure는 실패 종료만 대상으로 하며 daemon 재시작만으로 컨테이너를 올리지 않습니다.
HEALTHCHECK의 unhealthy는 종료 이벤트가 아니므로 restart policy를 발동하지 않습니다. health 상태를 보고 애플리케이션을 종료할지, 외부 monitor가 재배포할지는 별도 운영 계약입니다.
Compose의 restart 키와 동일한 동작
Compose의 restart 키는 docker run --restart와 같은 값을 받는다. 서비스별로 다른 정책을 적용할 수 있다.
services:
api:
image: my-api:latest
restart: unless-stopped # 운영 서비스
worker:
image: my-worker:latest
restart: on-failure # 배치 작업
db:
image: postgres:17
restart: always # 데이터베이스는 항상 복구Compose와 운영 경계
| 상황 | 적합한 선택 |
|---|---|
| 개발 환경, 수동 제어 원할 때 | no (기본값) |
| 실패 시만 재시도, 성공 후 종료 허용 | on-failure |
| 항상 떠 있어야 하는 서비스 | always 또는 unless-stopped |
| 점검 중 수동 중지가 필요한 서비스 | unless-stopped |
| 재시작 횟수를 제한하고 싶을 때 | on-failure:N |
장애 대응
restart policy는 장애 원인을 숨기는 도구가 아니다. 앱 버그나 설정 오류로 인한 무한 재시작 루프는 CPU와 메모리를 지속 소모하면서도 로그에 오류가 계속 쌓인다. 재시작 정책과 함께 반드시 로그 모니터링과 알림을 구성해 실제 원인을 놓치지 않아야 한다.
참고 링크
2 sources