저장소 logo 저장소

1. EXPOSE란?

EXPOSE는 Dockerfile에서 컨테이너가 실행될 때 어떤 네트워크 포트를 사용할 예정인지 표시하는 명령이다.

Docker 공식 Dockerfile reference에 따르면 EXPOSE는 컨테이너가 런타임에 지정된 네트워크 포트에서 listen한다는 정보를 Docker에 알려준다. [1]

하지만 EXPOSE는 포트를 실제로 외부에 공개하지 않는다. Docker 공식 문서에서도 EXPOSE는 이미지를 만든 사람과 컨테이너를 실행하는 사람 사이에서 어떤 포트를 publish할 의도인지 알려주는 문서화 역할을 한다고 설명한다. [1]

쉽게 말하면 EXPOSE는 다음과 같은 의미에 가깝다.

이 컨테이너 안의 프로그램은 보통 이 포트를 사용합니다.

예를 들어 Node.js 서버가 컨테이너 내부에서 3000번 포트로 실행된다면 다음처럼 적을 수 있다.

EXPOSE 3000

2. 사용법

EXPOSE의 기본 문법은 다음과 같다.

EXPOSE [포트 번호]

예시는 다음과 같다.

EXPOSE 3000

Docker 공식 문서에 따르면 프로토콜을 따로 적지 않으면 기본값은 TCP이다. [1]

즉, 다음 두 명령은 같은 의미로 볼 수 있다.

EXPOSE 3000
EXPOSE 3000/tcp

UDP 포트를 표시하려면 다음처럼 작성한다.

EXPOSE 3000/udp

TCP와 UDP를 모두 표시하려면 두 줄을 모두 적는다. [1]

EXPOSE 3000/tcp
EXPOSE 3000/udp

3. EXPOSE는 포트를 열어주지 않는다

EXPOSE 3000을 Dockerfile에 적었다고 해서 내 컴퓨터의 3000번 포트로 바로 접속할 수 있는 것은 아니다.

Docker 공식 문서에 따르면 컨테이너 포트를 호스트 포트로 publish하려면 docker run에서 -p 또는 --publish 옵션을 사용해야 한다. [1][2]

예를 들어 컨테이너 내부의 3000번 포트를 호스트의 8080번 포트로 연결하려면 다음처럼 실행한다.

docker run -p 8080:3000 my-server

Docker 공식 문서의 port publishing 설명에 따르면 -p HOST_PORT:CONTAINER_PORT 형식에서 앞의 값은 호스트 포트이고, 뒤의 값은 컨테이너 내부 포트이다. [2]

따라서 위 명령은 다음 의미이다.

즉, EXPOSE-p는 역할이 다르다.

EXPOSE 3000

위 명령은 “이 이미지의 컨테이너는 3000번 포트를 사용할 예정”이라고 기록하는 것이다.

docker run -p 8080:3000 my-server

위 명령은 실제로 호스트 포트와 컨테이너 포트를 연결하는 것이다.


4. EXPOSE가 없어도 -p는 동작한다

EXPOSE가 없어도 docker run -p로 포트를 publish할 수 있다.

Docker 공식 Dockerfile reference는 EXPOSE 설정과 관계없이 런타임에 -p 옵션으로 포트 설정을 override할 수 있다고 설명한다. [1]

예를 들어 Dockerfile에 EXPOSE 3000이 없어도, 컨테이너 안의 프로그램이 실제로 3000번 포트에서 listen하고 있다면 다음 명령으로 호스트 포트와 연결할 수 있다.

docker run -p 8080:3000 my-server

다만 EXPOSE를 적어두면 이 이미지를 사용하는 사람이 “이 컨테이너는 내부적으로 3000번 포트를 쓰는구나”라고 빠르게 파악할 수 있다.


5. 예외: -P 옵션

일반적인 -p 사용에서는 EXPOSE가 없어도 포트를 직접 지정해서 publish할 수 있다.

하지만 docker run -P 또는 docker run --publish-all을 사용할 때는 EXPOSE가 의미를 가진다.

Docker 공식 문서에 따르면 -P 또는 --publish-all 옵션은 이미지에 설정된 exposed port 전체를 임시 호스트 포트에 자동 publish한다. [1][2]

예를 들어 Dockerfile에 다음처럼 적혀 있다고 하자.

EXPOSE 3000

이 이미지를 다음처럼 실행하면 Docker가 호스트의 임시 포트를 하나 골라 컨테이너 내부 3000번 포트에 연결한다.

docker run -P my-server

따라서 정확히 정리하면 다음과 같다.


6. 정리

EXPOSE는 Dockerfile에서 컨테이너 내부 애플리케이션이 사용할 포트를 문서화하는 명령이다.

핵심은 다음과 같다.


참고자료

[1] Docker Docs, Dockerfile reference - EXPOSE: https://docs.docker.com/reference/dockerfile/#expose
[2] Docker Docs, Publishing and exposing ports: https://docs.docker.com/get-started/docker-concepts/running-containers/publishing-ports/


« Dockerfile WORKDIR
Docker Compose를 사용하는 이유 »