Quick Syntax
# Docker daemon host의 모든 address에 TCP 8080 공개
docker run -d --name web -p 8080:80 nginx:alpine
# daemon host의 loopback에서만 TCP 8080 공개
docker run -d --name admin -p 127.0.0.1:8080:80 nginx:alpine
# UDP를 명시적으로 공개
docker run -d --name dns -p 5353:53/udp my-dns
# container끼리만 통신할 DB는 publish하지 않음
docker run -d --name db --network appnet -e POSTGRES_PASSWORD=password postgres:17-p [HOST_IP:]HOST_PORT:CONTAINER_PORT[/PROTOCOL]은 daemon host의 port를 container port로 전달합니다. 같은 user-defined network 안의 service끼리만 통신한다면 -p가 필요 없습니다.
bind address와 protocol
-p 8080:80은 기본적으로 daemon host의 모든 address에 TCP port를 publish하므로 host 밖에서도 접근할 수 있습니다. IP를 생략한 publish는 편하지만 공개 범위가 넓습니다. admin UI, DB, cache처럼 host 내부에서만 쓸 서비스에는 loopback address를 명시하거나 port publish 자체를 하지 않습니다.
# 특정 host interface에만 공개
docker run -d -p 192.168.1.100:8080:80 nginx:alpine
# 같은 port 번호라도 TCP와 UDP는 별도 mapping
docker run -d -p 8080:80/tcp -p 8080:80/udp my-serviceDocker Engine은 host에서 container로 traffic을 전달하는 firewall/network rule을 만듭니다. Linux host의 실제 구현은 Engine 설정과 system의 iptables·nftables·userland proxy 구성에 따라 다를 수 있으므로, application에서 host IP나 NAT rule에 의존하지 않습니다.
127.0.0.1 또는 ::1을 넣으면 Docker host만 published port에 접근할 수 있습니다. 다만 Docker Engine 28.0.0 이전에는 같은 L2 network의 다른 host가 localhost publish에 닿을 수 있었으므로, 오래된 Engine은 별도 방화벽 검증이 필요합니다.
EXPOSE와 -P
Dockerfile의 EXPOSE 3000은 image가 사용할 port를 나타내는 metadata이며 host port를 열지 않습니다. 명시적으로 -p를 쓰거나, -P로 EXPOSE된 port를 host의 사용 가능한 port에 자동 publish해야 host에서 접근할 수 있습니다.
EXPOSE 3000# host에는 아직 공개되지 않음
docker run -d --name app my-app
# EXPOSE 3000을 임의 host port에 publish
docker run -d --name app -P my-app
docker port appEXPOSE를 적었다고 application이 실제로 해당 port에 listen하는 것도 아닙니다. container 안 process가 0.0.0.0:3000 또는 적절한 interface에서 listen하는지와 host mapping은 별도로 확인합니다.
내부 통신 범위
사용자 정의 bridge network에서는 같은 network의 container끼리 publish 없이 container port로 직접 통신합니다. 외부 browser가 들어올 web service만 publish하고, DB·Redis 같은 backend service는 내부 network에만 둡니다.
docker network create appnet
docker run -d --name db --network appnet -e POSTGRES_PASSWORD=password postgres:17
docker run -d --name api --network appnet -p 3000:3000 my-api-p는 host나 다른 bridge network에서 들어오는 경로를 만드는 설정이고, service discovery는 내부 DNS·network membership의 문제입니다. container 이름으로 DB를 찾는 기준은 named network와 service discovery 카드에서 다룹니다.
published port는 기본적으로 외부에 열립니다. EXPOSE만으로 안전하다고 판단하거나, 내부 전용 DB에 습관적으로 -p 5432:5432를 붙이지 마십시오. 실제 bind address와 host firewall·cloud security group을 함께 확인해야 합니다.
참고 링크
2 sources