Docker를 활용하여 웹 서버나 API 서버를 컨테이너로 실행할 때, 가장 흔히 마주하는 문제 중 하나는 외부에서 컨테이너에 접근할 수 없는 상황입니다. 예를 들어, nginx 컨테이너를 실행했지만 브라우저에서 localhost로 접속이 되지 않는 경우가 바로 그것입니다.
이 문제를 해결하기 위한 핵심 개념이 바로 포트 매핑(port mapping)입니다.
Docker 컨테이너는 기본적으로 호스트 시스템과 네트워크가 격리된 상태로 실행됩니다. 즉, 컨테이너 내부에서 실행 중인 웹 서버는 외부(예: 브라우저, 외부 클라이언트)에서 직접 접근할 수 없습니다.
컨테이너에서 실행되는 애플리케이션은 일반적으로 컨테이너 내부의 특정 포트를 통해 외부와 통신합니다. 하지만 이를 외부에서 접근 가능하게 하려면, 호스트의 포트를 컨테이너의 포트와 매핑하는 작업이 필요합니다.
예를 들어, 아래 명령어로 nginx 컨테이너를 실행하면:
$ docker run -d nginx
컨테이너는 실행되지만 외부에서는 접근할 수 없습니다. 왜냐하면 포트 매핑 설정이 없기 때문입니다.
포트 매핑은 호스트 시스템의 특정 포트를 컨테이너의 포트에 연결하는 설정입니다. 이를 통해 외부 사용자가 호스트의 포트를 통해 컨테이너 내부의 애플리케이션에 접근할 수 있습니다.
도커의 네트워크 구조상, 컨테이너는 외부로부터 격리되어 있어 기본적으로 외부에서 직접 접근할 수 없습니다. 이를 해결하기 위해 호스트의 특정 포트를 컨테이너의 포트와 연결시켜야 하며, 이 작업이 바로 포트 매핑입니다.
$ docker run -d -p [호스트 포트]:[컨테이너 포트] [이미지명]
$ docker run -d -p 8080:80 nginx
http://localhost:8080으로 접속 시, 컨테이너의 웹 서버(Nginx)에 접근할 수 있습니다.Docker는 보안과 격리를 기본 원칙으로 하기 때문에, 포트 매핑을 하지 않으면 외부에서 컨테이너에 접근할 수 없습니다. 즉, 컨테이너 내부의 웹 서버, API 서버 등에 접속하려면 반드시 포트 매핑이 필요합니다.
-p 옵션을 지정하지 않으면, 기본적으로 컨테이너는 외부에서 접근할 수 없는 상태로 실행됩니다. 외부 사용자가 웹 서버(Nginx 등)에 접근하려면, 호스트의 특정 포트와 컨테이너의 포트를 명시적으로 매핑해야 외부 요청을 허용할 수 있습니다.
여러 개의 컨테이너가 동일한 내부 포트(예: 80번)를 사용하더라도, 각각 다른 호스트 포트에 연결하면 동시에 실행이 가능합니다.
# 첫 번째 컨테이너
$ docker run -d -p 8080:80 nginx
# 두 번째 컨테이너
$ docker run -d -p 8081:80 nginx
포트 매핑이 제대로 되었는지 확인하려면 다음 명령어를 사용할 수 있습니다:
# 컨테이너의 포트 매핑 정보 확인
$ docker port [컨테이너_ID 또는 이름]
# 전체 컨테이너의 상세 정보 확인
$ docker ps
Docker가 자동으로 호스트의 포트를 선택하도록 설정할 수도 있습니다:
$ docker run -d -p 80 nginx
특정 네트워크 인터페이스에만 포트를 바인딩할 수 있습니다:
$ docker run -d -p 127.0.0.1:8080:80 nginx
| 서비스 | 컨테이너 포트 | 외부 포트 예시 |
|---|---|---|
| 웹 서버 | 80 | 8080, 4000 |
| HTTPS 서버 | 443 | 8443 |
| MySQL | 3306 | 3307, 13306 |
| PostgreSQL | 5432 | 5433 |
-p 옵션을 사용하여 호스트와 컨테이너의 포트를 연결해야 합니다.