Docker
Docker 컨테이너는 떠 있는데 접속이 안 될 때
docker ps에서는 running 상태인데 curl이나 browser에서 연결이 안 되는 경우가 있다. 확인해야 할 순서를 정리했다.
컨테이너가 실행 중이라고 해서 항상 접속 가능한 것은 아니다. 포트 매핑, 환경 변수, 네트워크 설정 중 하나라도 틀리면 외부에서는 도달할 수 없다.
컨테이너 상태 확인
먼저 기본을 본다.
docker ps
# CONTAINER ID, STATUS, PORTS 열을 확인
docker inspect <container_id>
# State.Running 이 true인지, Port 바인딩이 맞는지 확인
STATUS가 "Up" 상태여야 하고, PORTS 열에 포트 매핑이 제대로 표시되어야 한다. 예를 들어 0.0.0.0:8080->3000/tcp라면 호스트의 8080 포트가 컨테이너의 3000 포트로 매핑된 것이다.
로그 확인
컨테이너 내부에서 실제로 서버가 떴는지 확인한다.
docker logs <container_id>
# 최근 100줄만 보려면
docker logs --tail=100 <container_id>
# 실시간으로 보려면
docker logs -f <container_id>
Application이 실제로 시작된 것으로 보이는 로그가 있는지, 에러 메시지가 없는지 본다.
환경 변수 확인
컨테이너가 필요한 환경 변수를 받지 못했을 수도 있다.
docker inspect <container_id> | jq '.[].Config.Env'
또는 컨테이너 내부에서 직접 확인:
docker exec <container_id> env | grep -i <변수명>
필요한 환경 변수가 없거나 값이 잘못되어 있으면, 애플리케이션이 시작할 때 바인드 포트를 잘못 설정하거나 데이터베이스 연결에 실패할 수 있다.
호스트에서 직접 테스트
호스트에서 포트 접근이 되는지 확인한다.
# 호스트에서 컨테이너 포트로 직접 접속
curl -v http://localhost:8080
# 또는 nc로 포트가 열려 있는지만 확인
nc -zv localhost 8080
Timeout이 나면 포트 매핑이 제대로 안 된 것이고, Connection refused가 나면 컨테이너 내부의 애플리케이션이 해당 포트에서 listen하지 않고 있다는 뜻이다.
컨테이너 내부에서 테스트
호스트에서는 안 되는데 컨테이너 내부에서는 된다면, 포트 매핑이나 네트워크 문제다.
docker exec <container_id> curl -v http://localhost:3000
이게 되면 컨테이너 자체는 정상이고, 호스트-컨테이너 간 네트워크 설정을 확인해야 한다.
포트 매핑 재확인
docker ps나 docker inspect에서 본 포트 바인딩이 정말 그대로 적용됐는지 확인한다.
sudo ss -lntp | grep <포트번호>
# 호스트의 포트가 docker-proxy에 바인드되어 있어야 한다
만약 바인드되지 않았다면, 컨테이너를 --publish 옵션과 함께 다시 시작해야 할 수도 있다.