본문 바로가기

직접 만든 소프트웨어, 두 가지 개발 기록

구현 구조와 적용 범위, 확인한 기능과 남은 한계를 함께 기록합니다.

소프트웨어개발

Docker port is already allocated 해결: Compose 호스트 포트 충돌 점검

by 아빠띠띠뽀 2026. 10. 12.

Docker 시작 과정의 port is already allocated는 먼저 오류에 표시된 호스트 포트를 누가 사용하는지 확인해야 합니다. 컨테이너 안의 앱 포트를 무작정 바꾸거나 서버를 재부팅하기 전에 Docker 컨테이너와 호스트 리슨 프로세스를 구분하세요. 다른 서비스가 정상 사용 중이면 새 서비스의 호스트 매핑을 변경하는 것이 가능한 해결책입니다.

적용 범위는 Docker Engine·Docker Desktop과 Compose V2의 일반적인 bridge 포트 공개입니다. network_mode: host는 같은 ports 예제로 처리하지 않습니다. 명령은 2026-10-10 공식 문서 확인에 기반한 예시이며 실제 운영 서버에서 실행한 기록이 아닙니다. Linux의 ss와 macOS의 lsof는 도구 설치·권한·운영체제에 따라 출력이 다릅니다.

원인: 호스트 포트와 컨테이너 포트를 혼동합니다

8080:80에서 왼쪽 8080은 호스트에 공개할 포트이고 오른쪽 80은 컨테이너 앱의 포트입니다. 같은 호스트 주소·프로토콜의 8080을 이미 사용하는 서비스가 있으면 새 컨테이너의 공개 매핑이 충돌할 수 있습니다. 다른 컨테이너 두 개가 내부 80을 각각 사용하는 것은 그 자체로 충돌이 아닙니다. Docker 포트 공개 공식 설명을 기준으로 오류가 발생한 경계를 확인하세요.

보이는 증상 먼저 구분할 것 첫 확인
port is already allocated 시작 전 호스트 바인딩 충돌 오류의 호스트 IP·포트·TCP/UDP
앱 로그의 address already in use 앱 또는 host 네트워크의 리슨 충돌 같은 네트워크 공간의 프로세스
이미 실행 중인데 연결 실패 접속 주소·서비스 이름·앱 리슨 문제 포트 매핑과 실제 앱 상태

해결 절차 1: Docker가 해당 호스트 포트를 쓰는지 확인

docker context show
docker ps --format '{{.Names}} {{.Ports}}'
docker ps --filter publish=8080
docker compose ps

조회 명령입니다. 먼저 현재 Docker context가 문제를 낸 데몬과 같은지 확인하세요. 전체 목록의 PORTS에서 호스트 쪽 8080 매핑을 읽고 컨테이너 이름과 프로젝트를 대조합니다. publish 필터는 후보를 좁히는 보조 수단이며 필터 결과만으로 호스트 프로세스 점유가 없다고 결론내리지 않습니다. 이전 Compose 프로젝트나 별도 컨테이너가 같은 공개 포트를 사용 중일 수 있습니다.

해결 절차 2: 호스트의 TCP 리슨 점유를 확인

# Linux: ss가 있는 호스트에서 TCP 리슨 조회
ss -ltnp 'sport = :8080'

# macOS: TCP 리슨 조회
lsof -nP -iTCP:8080 -sTCP:LISTEN

여기서는 TCP 8080 예시입니다. 오류가 UDP라면 TCP 조회로 판단하지 말고 해당 프로토콜을 조회하세요. 권한이 부족하면 프로세스 이름이 보이지 않을 수 있습니다. Docker Desktop은 내부 VM과 호스트 공개 경로가 나뉘므로 Docker 목록과 호스트 점유를 함께 봅니다. 출력된 PID를 바로 강제 종료하지 말고 서비스 이름·담당자·사용 목적부터 확인합니다.

해결 절차 3: 필요한 경우 호스트 쪽 포트만 변경

services:
  web:
    image: nginx:stable
    ports:
      - "127.0.0.1:8081:80"

이 예시는 로컬 호스트에서 8081로 접속하고 컨테이너 내부 앱은 계속 80을 사용하는 개발용 매핑입니다. nginx 이미지 태그는 형식 예시이므로 운영에서는 검증된 버전·다이제스트를 고정하세요. 같은 Docker 네트워크의 다른 서비스는 보통 서비스 이름과 컨테이너 포트로 연결하므로 호스트 포트 변경과 내부 연결 설정 변경을 구분합니다.

실제로 적용하기 전에 Compose 파일과 기존 매핑을 보존하고 리버스 프록시·모니터링·접속 URL이 새 포트를 따라야 하는지 확인합니다. 점유자가 폐기할 이전 서비스라는 근거가 있을 때만 담당 운영 절차로 종료하세요. 전체 프로젝트 down이나 모든 컨테이너 종료를 기본 해결책으로 사용하지 않습니다.

확인 방법: 설정·실제 공개·앱 응답을 각각 확인

docker compose config
docker compose ps
curl -I http://127.0.0.1:8081/

config 출력은 환경 변수와 민감한 설정이 포함될 수 있으므로 공유 전 가리세요. ps에서 의도한 호스트 매핑을 확인하고, curl은 예시 HTTP 서비스의 헤더를 조회합니다. 404·405 같은 응답도 HTTP 서버에 도달했음을 보여줄 수 있으나 원하는 앱 동작이 성공했다는 뜻은 아닙니다. 실제 서비스 경로와 기대 상태를 확인해야 합니다. 변경을 적용하는 기동·재생성은 별도 운영 작업이며 중단 영향을 확인한 뒤 수행하세요.

주의사항: 포트 충돌 해결이 외부 공개 범위를 넓혀서는 안 됩니다

호스트 IP를 생략하면 여러 인터페이스에 공개될 수 있습니다. 이 예시처럼 127.0.0.1로 제한할지 실제 접근 요구로 결정하세요. Docker 공식 문서는 28.0.0 미만에서 localhost 공개 포트의 같은 L2 네트워크 접근 관련 주의사항을 안내하므로 구버전에서는 이 설정만으로 외부 차단을 확정하지 마세요. Compose ports 문법과 사용 중인 Docker 버전을 함께 확인합니다.

FAQ

컨테이너 내부 포트 80이 같으면 충돌하나요? 독립적인 컨테이너에서 내부 포트가 같다는 이유만으로 충돌하지 않습니다. 호스트에 공개하는 IP·포트·프로토콜을 확인하세요.

docker ps가 비어 있으면 포트가 비었나요? 아닙니다. context가 다르거나 호스트 서비스가 점유할 수 있습니다. 오류를 낸 데몬과 실제 호스트를 확인해야 합니다.

Docker 재시작이 가장 빠른가요? 원인을 확인하지 않은 재시작은 다른 서비스에 영향을 주며 같은 매핑 충돌이 다시 발생할 수 있습니다. 점유자와 설정을 먼저 확인하세요.

공식 출처와 관련 글

공식 자료 확인 기준일: 2026-10-10. 문서 확인 내용과 설계 예시이며 실제 계정·명령 실행 결과가 아닙니다.

함께 읽기: 컨테이너끼리 연결할 때 서비스 이름과 포트 구분

두 컨테이너가 같은 호스트 소켓에 연결하려다 충돌하고 별도 소켓으로 분리되는 개념 그림
직접 제작한 개념 이미지. 호스트 포트 충돌과 매핑 분리를 설명하며 실제 실행 결과는 아닙니다.