Docker 포트 충돌 해결법은 사용 중인 호스트 포트를 찾고, Compose에서 충돌하는 공개 포트를 바꾸는 것입니다. 컨테이너를 실행했는데 port is already allocated 오류가 나타났다면, 애플리케이션 코드보다 포트 매핑을 먼저 확인하는 편이 빠릅니다. 기존 서비스를 유지해야 한다면 8080:80을 8081:80으로 바꾸는 방식으로 해결할 수 있습니다.
확인 순서는 점유 컨테이너 조회, 운영체제 프로세스 확인, Compose 수정, 재생성 후 접속 검증입니다. 아래 설명은 일반적인 Docker 브리지 네트워크와 Compose의 ports 설정을 기준으로 하며, 2026년 10월 확인한 Docker·Microsoft 공식 문서의 동작 설명을 반영했습니다.
1. Docker 포트 충돌 원인: 호스트 포트와 컨테이너 포트 구분하기
Docker 포트 충돌은 컨테이너에 연결하려는 호스트의 주소·포트·프로토콜 조합을 다른 컨테이너나 프로그램이 이미 사용해 바인딩하지 못하는 상황입니다. 오류에 port is already allocated 또는 address already in use가 보이면, 메시지에 표시된 호스트 포트부터 확인합니다.
포트 매핑의 기본 순서는 HOST_PORT:CONTAINER_PORT입니다. 8080:80은 호스트의 8080번으로 들어온 연결을 컨테이너의 80번으로 전달한다는 뜻입니다. 따라서 호스트 8080번이 충돌할 때는 왼쪽 값을 바꾸며, 오른쪽 값은 컨테이너 안에서 서버가 실제로 수신하는 포트와 일치해야 합니다.
| 매핑 설정 | 연결 의미 |
|---|---|
8080:80 |
호스트 8080번 → 컨테이너 80번 |
8081:80 |
호스트 접속 포트만 8081번으로 변경 |
127.0.0.1:8081:80 |
호스트의 IPv4 루프백 주소에 8081번 공개 |
서로 다른 컨테이너가 내부에서 각각 80번을 사용하는 것은 일반적으로 문제가 없습니다. 각 컨테이너는 별도 네트워크 환경을 가지므로, 같은 호스트 공개 포트를 중복 요청하는지 확인하는 것이 핵심입니다. 출처: Docker 공식 문서 「Port publishing and mapping」.
1. Docker 포트 충돌 원인: 호스트 포트와 컨테이너 포트 구분하기

2. 사용 중인 Docker 포트 확인: docker ps와 docker port
먼저 Docker가 어떤 포트를 공개하고 있는지 조회합니다. 다음 명령은 실행 중인 컨테이너의 이름과 포트 정보를 함께 보여 줍니다.
docker ps --format "}\t{{.Ports}}"
PORTS 열에서 0.0.0.0:8080->80/tcp처럼 표시된 항목을 찾습니다. 이는 해당 컨테이너가 호스트의 IPv4 전체 주소에서 TCP 8080번을 공개하고 있다는 의미입니다. 반면 80/tcp만 표시된다면, 그 표시만으로 호스트의 80번 포트를 점유한다고 판단할 수 없습니다.
특정 컨테이너의 연결 관계는 docker port로 좁혀 확인합니다. 아래의 my-web은 예시 이름이므로, 실제 조회된 컨테이너 이름으로 바꿔 실행합니다.
docker port my-web
docker port my-web 80/tcp
두 번째 명령은 컨테이너 내부의 TCP 80번에 연결된 공개 주소와 포트만 조회합니다. Compose 프로젝트가 여러 개라면 현재 프로젝트 밖의 컨테이너가 같은 호스트 포트를 사용하고 있을 수 있으므로, 처음에는 전체 실행 목록을 보는 편이 좋습니다. 출처: Docker 공식 명령 문서 「docker container port」.
점유 컨테이너가 더 이상 필요하지 않다는 사실을 확인했다면 docker stop my-web으로 정상 중지할 수 있습니다. 계속 사용해야 하는 서비스라면 유지하고, 새로 실행할 서비스의 호스트 포트를 변경합니다. 이미지나 볼륨을 일괄 삭제하는 정리 작업은 포트 충돌 해결에 필요한 절차가 아닙니다.
2. 사용 중인 Docker 포트 확인: docker ps와 doc… 바로가기
3. Windows 포트 점유 프로세스 확인: netstat와 PID 조회
Docker 목록에서 원인이 보이지 않으면 Windows 프로그램이 같은 포트를 사용 중인지 확인합니다. PowerShell이나 명령 프롬프트에서 다음 명령을 실행하면 연결 상태, 수신 포트, PID를 볼 수 있습니다.
netstat -ano
출력이 많으면 8080번이 포함된 행을 먼저 추립니다. 다만 문자열 검색은 원격 주소나 18080번 같은 다른 포트도 함께 잡을 수 있으므로, 반드시 로컬 주소 열의 포트가 정확히 8080인지 확인합니다.
netstat -ano | findstr :8080
TCP 서버의 점유를 찾을 때는 LISTENING 상태와 마지막 열의 PID를 확인합니다. 작업 관리자의 ‘세부 정보’ 탭에서 같은 PID를 찾아 프로그램 이름을 대조하면 됩니다. TIME_WAIT 행이나 원격 포트에만 8080이 나온 결과를 곧바로 점유 서버로 해석하지 않는 것이 중요합니다. 출처: Microsoft Learn 「netstat」.
예를 들어 로컬 개발 서버와 Docker 웹 서버가 모두 8080번을 사용하려 한다면, 필요한 서비스를 남기고 다른 쪽의 포트를 변경합니다. Docker Desktop 관련 프로세스가 보이는 경우에는 그 프로세스를 강제 종료하기보다 앞 단계의 컨테이너 매핑과 함께 판단해야 합니다.
3. Windows 포트 점유 프로세스 확인: netstat와 PI… 신청하기
4. Compose 포트 충돌 해결: 왼쪽 호스트 포트 변경하기
8080번을 계속 사용하는 기존 서비스가 있다면, 새 서비스에 사용할 8081번도 앞선 방법으로 확인합니다. 이후 compose.yaml에서 ports의 호스트 포트를 변경합니다. 다음은 컨테이너 내부 80번에서 웹 서버가 실행되는 경우의 설정 예시입니다.
8080:80을 8081:80으로 수정
services:
web:
image: nginx:stable
ports:
- "8081:80"
8081:80으로 바꾸면 호스트에서 접근하는 번호만 달라집니다. 8080:8081로 수정하면 충돌하는 호스트 8080번이 그대로 남고, 컨테이너 내부의 연결 대상까지 바뀝니다. 내부 서버가 80번을 수신하는 상황에서는 포트 충돌과 접속 실패를 함께 만들 수 있는 실수입니다.
로컬 개발 환경은 localhost 바인딩 검토
같은 컴퓨터에서만 확인할 서비스라면 다음처럼 공개 주소도 명시할 수 있습니다. 일반적인 브리지 네트워크 설정에서 IPv4 루프백 주소로 접근 범위를 제한하는 방식입니다.
services:
web:
image: nginx:stable
ports:
- "127.0.0.1:8081:80"
Docker는 호스트 주소를 생략한 공개 포트가 외부에서도 접근 가능해질 수 있다고 설명합니다. 또한 Docker Engine 28.0.0 미만에서는 같은 L2 네트워크의 다른 호스트가 localhost 공개 포트에 접근할 수 있다는 공식 경고가 있습니다. 구버전 환경은 docker version에서 서버 버전도 확인해야 합니다. 출처: Docker 공식 문서 「Port publishing and mapping」.
진단 관점에서는 포트 번호 변경과 공개 범위 설정을 함께 검토하는 것이 효율적입니다. 충돌을 해결했다는 이유만으로 개발용 관리 화면까지 외부에 열 필요는 없으며, 다른 기기의 접근이 필요한 서비스에만 해당 네트워크 주소와 접근 정책을 적용하는 편이 명확합니다.
4. Compose 포트 충돌 해결: 왼쪽 호스트 포트 변경하기
5. Compose 변경 적용과 접속 검증: 재시작 대신 설정 반영
설정 파일을 저장한 뒤에는 해당 프로젝트 디렉터리에서 아래 명령을 순서대로 실행합니다. 예시의 web은 Compose 서비스 이름이므로 실제 서비스 이름에 맞춥니다.
docker compose config
docker compose up -d web
docker compose ps
docker compose port web 80
docker compose config로 병합·변수 치환된 최종 설정을 살핀 다음, up -d로 변경 사항을 적용합니다. 단순한 restart는 변경된 포트 설정을 적용하는 절차가 아닙니다. 재생성 과정에는 서비스가 잠시 중단될 수 있으므로 운영 환경에서는 반영 시점을 고려합니다.
출력에서 호스트 8081번이 컨테이너 80번에 연결됐는지 확인하고, 웹 브라우저의 주소 입력란에 루프백 주소와 8081번 포트를 지정해 접속합니다. Windows PowerShell에서는 다음 명령으로 HTTP 응답도 확인할 수 있습니다.
Invoke-WebRequest -Uri ('http://' + '127.0.0.1:8081')
기대하는 화면이나 HTTP 응답이 오면 공개 포트 경로가 동작하는 것입니다. 연결은 되지만 404 또는 500 응답이 나온다면 애플리케이션 경로나 서버 상태를 추가로 점검합니다. 연결 자체가 거부되면 docker compose logs --tail 100 web으로 서버 시작 여부와 내부 수신 포트를 확인합니다.
재생성 후에도 이전 포트가 보인다면 다른 디렉터리의 프로젝트를 실행했거나, 추가 Compose 파일 또는 환경변수가 설정을 덮어썼을 수 있습니다. 이때는 실제 실행에 사용한 -f 옵션과 환경변수를 동일하게 적용해 docker compose config 결과를 다시 확인하는 것이 좋습니다.
5. Compose 변경 적용과 접속 검증: 재시작 대신 설정 반영 조회하기
6. Docker 포트 충돌 재발 방지: 내부 통신과 동적 할당 활용
Docker 공식 Compose 네트워킹 예시는 8001:5432로 공개한 데이터베이스에 같은 네트워크의 서비스가 db:5432로 연결하도록 설명합니다. 호스트에서 사용하는 8001번과 컨테이너 사이에서 사용하는 5432번은 용도가 다릅니다. 웹 서비스의 공개 포트를 바꿨다는 이유만으로 내부 데이터베이스 연결 포트까지 변경할 필요는 없습니다.
호스트나 외부 도구에서 직접 연결할 필요가 없는 데이터베이스는 ports 공개 자체가 필요한지 검토할 수 있습니다. 같은 Compose 네트워크의 서비스 간 통신에는 호스트 공개 포트가 필수 조건이 아닙니다. 이런 구성은 호스트 포트의 중복 사용과 불필요한 외부 노출을 함께 줄이는 데 도움이 됩니다.
고정 주소가 필요 없는 임시 환경이라면 ports: ["80"]처럼 컨테이너 포트만 지정해 호스트 포트를 동적으로 할당받을 수도 있습니다. 실제 할당값은 docker compose port web 80으로 확인합니다. 다만 브라우저 주소나 테스트 설정에도 그 결과를 반영해야 하므로, 고정 포트를 전제로 하는 개발 흐름에는 명시적인 매핑이 더 편할 수 있습니다. 출처: Docker 공식 문서 「Networking in Compose」.
구성 관리 측면에서는 컨테이너 IP보다 서비스 이름을 기준으로 내부 연결을 유지하는 편이 안정적입니다. Compose가 컨테이너를 교체하면 IP는 달라질 수 있지만 서비스 이름은 유지되기 때문입니다. 포트 충돌을 해결하면서 IP 주소까지 임의로 고정하기보다는, 외부 접속 경로와 내부 서비스 연결을 각각 검증하는 것이 문제 범위를 줄여 줍니다.
- 오류에 표시된 호스트 포트와 TCP·UDP 구분을 확인합니다.
docker ps와docker port로 점유 컨테이너를 찾습니다.- 필요하면 Windows의
netstat -ano와 작업 관리자에서 PID를 대조합니다. - 사용 가능한 호스트 포트로 변경하고 내부 수신 포트는 유지합니다.
docker compose up -d로 반영한 뒤 실제 매핑과 응답을 확인합니다.
해결의 기준은 컨테이너가 실행됐다는 표시와 실제 접속 성공을 함께 확인하는 것입니다. 점유 대상을 먼저 파악하고 호스트 포트만 정확히 수정하면, 기존 서비스를 유지하면서 새 컨테이너의 접속 경로를 정리할 수 있습니다.