Docker
Docker 컨테이너가 계속 재시작될 때 로그에서 찾는 것
컨테이너가 restart loop에 빠졌을 때 어디서부터 봐야 할지, 자주 마주치는 원인과 확인 순서를 정리했다.
배포 직후 컨테이너가 올라왔다 내려갔다를 반복하는 상황은 생각보다 자주 생긴다. docker ps로 보면 STATUS 컬럼에 Restarting (1) 5 seconds ago 같은 메시지가 보이면서 숫자가 계속 올라간다.
이 상태에서 이미지를 다시 빌드하거나 compose 파일을 고치는 건 원인을 모르고 건드리는 것이다. 로그를 먼저 봐야 한다.
먼저 로그를 본다
docker logs --tail=50 <container_name>
# Swarm 서비스라면
docker service logs --tail=50 <service_name>
컨테이너가 재시작하더라도 직전 실행의 로그는 남아 있다. 마지막 에러 메시지를 보면 원인의 대부분은 바로 드러난다. 내가 자주 본 패턴은 세 가지다.
- 환경변수 누락 — 앱이 시작 시점에 필수 변수를 읽고 없으면 바로 죽는다.
DATABASE_URL,SECRET_KEY같은 것들. - 헬스체크 실패 —
HEALTHCHECK설정이 있으면 응답 지연이나 엔드포인트 오류로 컨테이너가 unhealthy 상태에서 계속 재시작된다. - OOM — 메모리 제한에 걸려 커널이 프로세스를 종료한 경우. 이때는 로그에 아무것도 안 남는다.
OOM인지 확인하는 방법:
docker inspect <container_name> --format='{{.State.OOMKilled}}'
true가 출력되면 메모리 제한을 올리거나 앱의 메모리 사용량을 줄여야 한다.
환경변수와 볼륨 마운트 점검
로그에서 명확한 에러가 없으면 환경변수와 볼륨 마운트를 확인한다.
docker inspect <container_name> | python3 -c "
import sys, json
d = json.load(sys.stdin)[0]
print('Env:', d['Config']['Env'])
print('Mounts:', d['Mounts'])
"
로컬에서 .env 파일로 주입하던 값이 운영 환경에 없는 경우가 자주 있다. 볼륨 마운트는 호스트 경로가 실제로 존재하는지, 파일 내용이 컨테이너가 기대하는 형식인지를 확인한다.
한 번에 하나만 수정한다
원인을 추정했으면 딱 하나만 바꾸고 다시 올린다. 환경변수·이미지 태그·볼륨 경로를 동시에 건드리면 어떤 변경이 효과가 있었는지 알 수 없게 된다. 수정 전후 로그를 비교하면 어느 부분이 달라졌는지 금방 보인다.
재시작이 멈추면 docker ps에서 STATUS가 Up X minutes로 안정된 것을 확인한 뒤 끝낸다.