← 전체 글로 돌아가기

Docker

Docker 컨테이너가 서버에서만 실패할 때

로컬에서는 정상 작동하는 Docker 컨테이너가 서버 배포 후 에러를 일으킬 때 로그를 읽고 원인을 찾는 방법.

Docker를 로컬에서 빌드해서 서버에서 실행하면, 예상치 못한 환경 차이가 드러난다. 로그 없이는 무엇이 문제인지 알 수 없다.

컨테이너 로그 확인

가장 먼저 할 일은 컨테이너가 왜 멈췄는지 보는 것이다:

# 실행 중인 컨테이너 목록
docker ps

# 최근 출력된 로그 (마지막 100줄)
docker logs --tail=100 container-name

# 실시간으로 로그 보기
docker logs -f container-name

에러 메시지가 명확하다면 거기서부터 시작한다.

컨테이너 실행 상태 검사

컨테이너가 실행 중이나 계속 재시작되는가?

# 컨테이너 상세 정보
docker inspect container-name

# State.Running: true인가?
# State.ExitCode가 0이 아니면 비정상 종료

만약 컨테이너가 계속 재시작된다면 시작 커맨드에서 문제가 생기는 것이다.

환경 변수 확인

Dockerfile이나 docker-compose에서 정의한 환경 변수가 실제로 전달되었나?

# 컨테이너 내부에 진입해서 환경 변수 확인
docker exec container-name env | grep YOUR_VAR

# 환경 변수가 없다면 docker run이나 docker-compose.yml에서 확인

특히 데이터베이스 접속 정보나 API 키 같은 중요 환경 변수를 확인한다.

포트 바인딩

Dockerfile의 EXPOSE와 실제 포트 매핑이 일치하나?

# 컨테이너가 어느 포트에서 listen 중인가?
netstat -tlnp | grep container-pid

# 호스트의 포트 매핑 확인
docker port container-name

예를 들어 Dockerfile에서 EXPOSE 8080이지만, 스크립트에서는 5000으로 실행 중이면 문제가 생긴다.

네트워크와 DNS

Docker 네트워크 설정이 서버에서 다를 수 있다:

# 컨테이너 내부에서 외부 서비스 접근 테스트
docker exec container-name curl https://api.example.com

# DNS 해석 확인
docker exec container-name nslookup example.com

로컬 PC에서는 DNS가 잘 작동하지만, 서버 환경에서 DNS 설정이 없을 수 있다.

볼륨과 파일 시스템

volume 마운트를 사용한다면 서버에서 그 경로가 존재하나?

# 컨테이너가 마운트한 경로 확인
docker inspect container-name | grep Mounts -A 10

# 호스트의 해당 경로가 존재하고 권한은?
ls -la /path/to/volume

로컬에서는 ./data:/app/data 경로가 있지만, 서버에 ./data 디렉토리가 없으면 마운트가 실패한다.

이미지 태그와 버전

로컬에서는 최신 이미지로 빌드했지만, 서버에서는 오래된 버전을 사용하고 있지는 않나?

# 현재 실행 중인 이미지 확인
docker ps --no-trunc | grep container-name

# 이미지 ID와 태그 확인
docker images

배포 파이프라인에서 올바른 버전의 이미지를 배포하고 있는지 확인한다.

컨테이너 직접 실행해보기

서버에서 직접 컨테이너를 실행해본다:

# 로컬과 같은 방식으로 실행
docker run -it -e VAR=value -p 8080:8080 image-name

그러면 로그가 터미널에 바로 나타나고, 무엇이 문제인지 명확해진다.