본문 바로가기
소프트웨어개발

Docker 컨테이너가 Restarting을 반복할 때: exit code·로그·재시작 정책 점검

by 아빠띠띠뽀 2026. 9. 23.

docker ps에서 컨테이너 상태가 Restarting으로 반복되면 애플리케이션이 종료되고 재시작 정책이 다시 실행하는 상황일 가능성이 큽니다. 무작정 restart를 반복하면 최초 오류가 로그에서 밀려 원인 파악이 더 어려워집니다. 종료 코드, 로그, 설정, 의존 서비스, 재시작 정책 순서로 확인하면 진단 시간을 줄일 수 있습니다.

1. 재시작 횟수와 마지막 종료 상태를 먼저 기록한다

컨테이너 이름을 확인한 뒤 상태, 종료 코드, OOM 여부, 시작·종료 시각, 재시작 횟수를 한 번에 남기세요. 컨테이너가 잠깐 실행되는 사이에 exec로 들어가려 하기보다 docker inspect로 종료 상태를 읽는 편이 안정적입니다.

docker ps -a --filter status=restarting
docker inspect -f 'exit={{.State.ExitCode}} oom={{.State.OOMKilled}} error={{.State.Error}} restarts={{.RestartCount}}' app
docker inspect -f 'started={{.State.StartedAt}} finished={{.State.FinishedAt}}' app

관찰 결과가능성이 큰 원인다음 확인

exit 1 애플리케이션 설정·실행 오류 최초 stderr와 시작 명령
exit 126 또는 127 권한 또는 명령 없음 ENTRYPOINT·파일 권한·이미지 경로
exit 137, OOMKilled=true 메모리 부족 또는 강제 종료 메모리 제한과 호스트 로그
exit 0 후 반복 정상 종료 프로그램에 always 정책 적용 프로세스 수명과 restart 정책

Restarting 루프는 재시작부터 누르기보다 종료 코드와 최초 오류 로그를 보존하는 것이 해결의 시작입니다.

2. 로그는 최근 구간과 시간 정보로 좁혀 본다

Docker 로그는 컨테이너 프로세스가 stdout과 stderr로 출력한 내용입니다. 수천 줄을 모두 복사하기보다 최근 100~200줄과 타임스탬프를 확인하세요. 비밀번호, 토큰, 연결 문자열이 로그에 포함될 수 있으므로 공유 전에 민감 정보를 지워야 합니다.

docker logs --timestamps --tail 200 app
docker logs --since 10m app

오류가 보이지 않으면 애플리케이션이 파일로만 로그를 쓰는지, 시작 전에 셸에서 실패하는지, 로그 드라이버 설정이 무엇인지 확인합니다.

3. 실행 명령과 환경 설정을 이미지 기준으로 검증한다

잘못된 command나 entrypoint, 누락된 환경 변수, 읽을 수 없는 설정 파일은 시작 직후 종료의 흔한 원인입니다. Compose를 쓴다면 최종 병합 설정을 docker compose config로 펼쳐 확인하세요. 환경 변수 값을 화면에 그대로 출력하지 말고 키 존재 여부와 파일 마운트 경로를 중심으로 점검합니다.

docker inspect -f '{{json .Config.Cmd}} {{json .Config.Entrypoint}}' app
docker compose config
docker inspect -f '{{json .Mounts}}' app

4. DB·Redis·DNS 같은 의존 서비스의 준비 상태를 확인한다

컨테이너가 시작됐다는 사실은 DB나 메시지 브로커가 요청을 받을 준비가 됐다는 뜻이 아닙니다. 연결 거부, 이름 해석 실패, 마이그레이션 충돌이 로그에 보이면 서비스 이름, 네트워크, 포트, 헬스체크를 확인하세요. 단순 depends_on만으로 준비 완료가 보장되는지 Compose 버전과 조건을 함께 봐야 합니다.

5. 재시작 정책은 원인을 가리지 않도록 조정한다

Docker의 no, on-failure, always, unless-stopped는 목적이 다릅니다. 배치 작업이나 한 번 실행 후 끝나는 컨테이너에 always를 쓰면 정상 종료도 재시작 루프로 보일 수 있습니다. 진단 중에는 재시작 횟수를 제한한 on-failure를 검토하고, 원인을 고친 뒤 운영 정책을 다시 설정하세요.

6. 안전한 복구 순서

  1. inspect 결과와 최근 로그를 파일로 보존합니다.
  2. Compose 설정, 이미지 태그, 마운트, 환경 변수 키를 이전 정상 배포와 비교합니다.
  3. DB·Redis·외부 API의 연결성과 준비 상태를 확인합니다.
  4. OOM이면 메모리 사용량과 제한을 조정하고 누수를 조사합니다.
  5. 수정한 이미지를 새 태그로 빌드해 단일 컨테이너에서 검증합니다.
  6. 정상 기동 뒤 재시작 정책과 헬스체크를 운영값으로 복구합니다.

서비스 시작 순서가 원인이라면 Docker Compose healthcheck로 시작 순서 제어하기를 함께 확인하세요.

7. 자주 묻는 질문

Q. exit 137이면 무조건 OOM인가요?
SIGKILL로 종료된 상태를 뜻할 수 있으므로 .State.OOMKilled와 호스트 이벤트를 함께 확인해야 합니다.

Q. restart: always를 제거하면 해결되나요?
증상이 멈출 뿐 애플리케이션 종료 원인은 남습니다. 로그와 종료 상태를 먼저 확인하세요.

Q. 컨테이너가 너무 빨리 꺼져서 exec가 안 됩니다.
docker inspect와 docker logs로 종료 후 상태를 읽고, 필요하면 동일 이미지의 진입점을 셸이나 진단 명령으로 바꾼 별도 컨테이너에서 확인합니다.

공식 자료: Docker 재시작 정책 · docker container inspect · 컨테이너 로그 보기 · 컨테이너 상태와 exit 필터 (확인일: 2026-09-23)