Docker Compose 포트 충돌은 실행 중인 프로세스와 기존 컨테이너를 먼저 확인한 뒤 해결하는 것이 안전합니다.
Docker compose up 실행 중 port is already allocated 오류가 나오면 대부분 내 PC의 호스트 포트를 이미 다른 프로그램이나 Docker 컨테이너가 사용 중인 상태입니다. 앱 코드가 망가진 문제가 아니라, 같은 포트를 두 곳에서 동시에 쓰려고 해서 Docker가 컨테이너를 시작하지 못하는 상황에 가깝습니다.
해결 순서는 단순합니다. 먼저 어떤 포트가 막혔는지 확인하고, 실행 중인 Docker 컨테이너를 확인한 뒤, 필요하면 compose.yaml의 왼쪽 포트만 바꿉니다. 기존 컨테이너 정리는 마지막 단계로 두는 것이 안전합니다.
먼저 확인할 결론
가장 안전한 해결 순서
① 사용 중인 포트를 확인합니다. ② 같은 프로젝트나 기존 컨테이너가 떠 있는지 확인합니다. ③ compose.yaml에서 호스트 포트를 바꿉니다. ④ 그래도 해결되지 않을 때만 컨테이너를 정리합니다.
포트 매핑에서 충돌이 나는 쪽은 보통 컨테이너 내부 포트가 아니라 내 PC에서 열리는 호스트 포트입니다. 예를 들어 "3000:3000"에서 왼쪽 3000번이 이미 사용 중이면 port is already allocated 오류가 발생할 수 있습니다.
오류 메시지 원문
Docker Compose 포트 충돌은 아래와 같은 메시지로 나타납니다. 숫자는 프로젝트에 따라 3000, 5173, 8000, 8080, 3306, 5432, 6379 등으로 달라질 수 있습니다.
Error response from daemon: Ports are not available
Bind for 0.0.0.0:3000 failed: port is already allocated
port is already allocated
address already in use
Bind for 0.0.0.0:8080 failed
Ports are not available
메시지에서 가장 먼저 볼 부분은 포트 번호입니다. 0.0.0.0:3000이라고 나오면 내 PC의 3000번 포트를 누가 이미 사용하고 있는지 확인하면 됩니다.
언제 발생하는 오류인지
이 오류는 Docker Compose가 컨테이너를 만들거나 시작하면서 호스트 포트를 바인딩하려는 순간에 자주 발생합니다. 특히 로컬 개발 환경에서는 같은 포트를 쓰는 앱이 많기 때문에 처음 Docker를 쓰는 사람도 자주 만납니다.
| 상황 | 예시 | 확인할 것 |
|---|---|---|
| 같은 프로젝트를 다시 실행 | 이미 docker compose up이 켜져 있음 |
docker compose ps |
| 로컬 개발 서버와 충돌 | React, Next.js, Vite가 같은 포트 사용 | 포트 점유 프로세스 |
| DB 기본 포트 충돌 | MySQL 3306, PostgreSQL 5432, Redis 6379 | 기존 DB 또는 컨테이너 |
원인 3가지
1. 같은 호스트 포트를 다른 프로그램이 사용 중인 경우
가장 흔한 원인은 내 PC에서 이미 같은 포트를 쓰는 프로그램이 실행 중인 경우입니다. 예를 들어 로컬에서 Next.js 개발 서버를 3000번 포트로 실행한 상태에서 Docker Compose도 3000번을 쓰려고 하면 충돌이 납니다.
2. 이전 Docker 컨테이너가 종료되지 않고 남아 있는 경우
터미널을 닫았다고 해서 컨테이너가 항상 내려가는 것은 아닙니다. Docker Desktop이나 백그라운드에서 이전 컨테이너가 계속 실행 중이면 같은 포트를 다시 사용할 수 없습니다.
3. compose.yaml에서 여러 서비스가 같은 호스트 포트를 쓰는 경우
하나의 compose.yaml 안에서 두 서비스가 모두 "8080:80"처럼 같은 왼쪽 포트를 쓰면 둘 중 하나는 시작하지 못합니다. 컨테이너 내부 포트는 같아도 되지만, 내 PC에 공개하는 호스트 포트는 서비스마다 달라야 합니다.
빠른 해결 방법
원인을 길게 추측하기 전에 아래 순서대로 확인하면 대부분의 포트 충돌을 빠르게 좁힐 수 있습니다.
빠른 점검 순서
1. 현재 Compose 프로젝트 컨테이너를 확인합니다.
2. 전체 Docker 컨테이너 중 같은 포트를 쓰는 항목을 확인합니다.
3. Windows, Mac, Linux 명령어로 포트 점유 프로세스를 확인합니다.
4. 충돌이 계속되면 compose.yaml의 왼쪽 포트를 바꿉니다.
docker compose ps
docker ps
현재 프로젝트 컨테이너가 실행 중이라면 먼저 중복 실행인지 확인합니다. 다른 프로젝트의 컨테이너가 같은 포트를 쓰고 있다면 docker ps 결과의 PORTS 항목에서 포트 매핑을 확인할 수 있습니다.
포트 매핑을 먼저 이해하기
Docker Compose 포트 매핑에서는 왼쪽 호스트 포트가 내 PC에서 접속하는 포트이고, 오른쪽 컨테이너 포트는 컨테이너 내부 앱이 사용하는 포트입니다.
Compose의 ports 설정은 호스트 포트와 컨테이너 내부 포트를 연결합니다. 아래 예시에서 왼쪽 3001은 내 PC에서 접속하는 포트이고, 오른쪽 3000은 컨테이너 내부 앱이 사용하는 포트입니다.
services:
web:
ports:
- "3001:3000"
브라우저에서는 http://localhost:3001로 접속하지만, 컨테이너 안의 앱은 그대로 3000번 포트를 사용할 수 있습니다. 따라서 포트 충돌을 해결할 때는 보통 오른쪽이 아니라 왼쪽 숫자를 바꾸면 됩니다.
| 표기 | 의미 | 충돌 시 수정 |
|---|---|---|
"3000:3000" |
내 PC 3000 → 컨테이너 3000 | "3001:3000" |
"8080:80" |
내 PC 8080 → 컨테이너 80 | "8081:80" |
"5432:5432" |
내 PC 5432 → 컨테이너 PostgreSQL 5432 | "5433:5432" |
Windows에서 포트 점유 확인하기
Windows에서는 netstat으로 특정 포트를 사용 중인 프로세스의 PID를 확인할 수 있습니다. 예시는 3000번 포트를 확인하는 명령어입니다.
netstat -ano | findstr :3000
결과에 LISTENING 상태와 PID가 보이면 해당 프로세스가 포트를 점유하고 있는 것입니다. 작업 관리자에서 PID 열을 표시한 뒤 어떤 프로그램인지 확인하고, 개발 서버나 불필요한 프로세스일 때만 종료합니다.
Windows에서 종료 전 확인할 점
PID만 보고 바로 종료하지 말고, 어떤 프로그램인지 먼저 확인해야 합니다. 데이터베이스, 동기화 도구, 회사 보안 프로그램처럼 계속 실행되어야 하는 프로세스일 수 있습니다.
Mac·Linux에서 포트 점유 확인하기
Mac과 Linux에서는 lsof 명령어로 특정 포트를 사용 중인 프로세스를 확인할 수 있습니다.
lsof -i :3000
결과의 COMMAND, PID, USER를 확인합니다. Node.js 개발 서버, Django 서버, FastAPI 서버처럼 사용자가 직접 실행한 프로세스라면 해당 터미널에서 종료하는 방식이 가장 안전합니다.
프로세스가 정상 종료되지 않을 때만 아래 명령어를 검토합니다. kill -9는 강제 종료이므로 저장 중인 작업이나 데이터 처리 중인 프로그램에는 사용하지 않는 것이 좋습니다.
kill -9 PID
Docker 컨테이너가 포트를 잡고 있는지 확인하기
로컬 앱이 아니라 Docker 컨테이너가 포트를 잡고 있을 수도 있습니다. 먼저 현재 폴더의 Compose 프로젝트 컨테이너를 확인합니다.
docker compose ps
다른 폴더에서 실행한 컨테이너까지 확인하려면 전체 컨테이너 목록을 봅니다.
docker ps
특정 서비스의 공개 포트를 확인하고 싶다면 docker compose port 명령어를 사용할 수 있습니다. 아래 예시는 web 서비스의 컨테이너 내부 3000번 포트가 호스트의 어떤 포트에 연결되어 있는지 확인하는 명령입니다.
docker compose port web 3000
Docker 공식 문서 기준으로 docker compose ps는 Compose 프로젝트 컨테이너의 상태와 노출 포트를 확인하는 명령입니다. 포트 충돌이 의심될 때는 앱 로그보다 먼저 컨테이너 상태와 포트 매핑을 확인하는 것이 빠릅니다.
compose.yaml에서 포트 바꾸는 방법
이미 사용 중인 포트를 종료하기 어렵거나, 여러 프로젝트를 동시에 실행해야 한다면 compose.yaml의 왼쪽 포트를 바꾸는 방식이 가장 깔끔합니다.
3000번 포트가 겹칠 때
React, Next.js, Node.js 개발 서버와 충돌한다면 호스트 포트를 3001번으로 바꿉니다.
services:
web:
ports:
- "3001:3000"
8080번 포트가 겹칠 때
Spring Boot, Nginx 테스트, 프록시 컨테이너와 충돌한다면 호스트 포트를 8081번으로 바꿀 수 있습니다.
services:
nginx:
ports:
- "8081:80"
PostgreSQL 5432번 포트가 겹칠 때
로컬에 PostgreSQL이 이미 설치되어 있거나 다른 DB 컨테이너가 실행 중이라면 호스트 포트만 5433번으로 바꿉니다. 컨테이너 내부 PostgreSQL 포트는 그대로 5432번을 유지합니다.
services:
db:
image: postgres
ports:
- "5433:5432"
이렇게 바꾸면 내 PC에서는 localhost:5433으로 접속하고, 컨테이너 내부에서는 PostgreSQL이 계속 5432번으로 동작합니다.
기존 컨테이너 정리 전 주의할 점
컨테이너를 정리하면 포트 충돌이 해결될 수 있지만, 무작정 삭제 명령부터 실행하는 것은 좋지 않습니다. 특히 DB 컨테이너를 쓰고 있다면 데이터가 볼륨에 저장되어 있는지, 컨테이너 내부에만 남아 있는지 먼저 확인해야 합니다.
정리 명령어를 실행하기 전
docker compose down은 현재 Compose 프로젝트의 컨테이너와 네트워크를 내릴 수 있습니다. 볼륨 삭제 옵션은 데이터가 사라질 수 있으므로 기본 해결책으로 사용하지 않는 것이 안전합니다.
현재 프로젝트를 종료해도 되는 상황이라면 아래 명령어로 컨테이너를 내릴 수 있습니다.
docker compose down
데이터베이스 컨테이너를 함께 쓰는 프로젝트에서는 down만 실행할지, 볼륨까지 삭제할지 구분해야 합니다. 포트 충돌 해결 목적이라면 볼륨 삭제 명령은 필요하지 않은 경우가 많습니다.
VSCode와 Dev Container에서 함께 확인할 것
VSCode Dev Container를 함께 쓰면 포트가 자동으로 포워딩되거나, 이미 컨테이너가 떠 있는 상태에서 터미널에서 다시 docker compose up을 실행하는 일이 생길 수 있습니다.
| 확인 위치 | 점검 내용 | 해결 방향 |
|---|---|---|
| VSCode Ports 패널 | 같은 포트가 이미 포워딩 중인지 확인 | 불필요한 포워딩 종료 |
| VSCode 터미널 | docker compose up을 여러 번 실행했는지 확인 |
기존 터미널 종료 또는 down 실행 |
| Docker Desktop | 같은 프로젝트 컨테이너가 계속 실행 중인지 확인 | 필요 없는 컨테이너 중지 |
Dev Container 환경에서 Docker 연결 자체가 불안정하다면 VSCode에서 Is Docker running? 오류가 뜰 때 점검할 항목을 함께 확인하면 원인을 나누는 데 도움이 됩니다.
자주 겹치는 포트 예시
아래 포트는 로컬 개발 환경에서 자주 겹칩니다. 오류 메시지에 나온 포트 번호가 표에 있다면 해당 도구나 컨테이너가 이미 실행 중인지 먼저 확인합니다.
| 포트 | 자주 쓰는 도구 | 대체 예시 |
|---|---|---|
| 3000 | React, Next.js, Node.js | 3001, 3002 |
| 5173 | Vite | 5174 |
| 8000 | Django, FastAPI | 8001 |
| 8080 | Spring Boot, Nginx 테스트 | 8081, 8082 |
| 3306 | MySQL | 3307 |
| 5432 | PostgreSQL | 5433 |
| 6379 | Redis | 6380 |
재발 방지 방법
포트 충돌을 줄이려면 프로젝트마다 호스트 포트 규칙을 정해두는 것이 좋습니다. 예를 들어 개인 프로젝트는 3001번대, 회사 프로젝트는 3100번대, DB 컨테이너는 5433번부터 쓰는 식으로 나누면 같은 오류를 줄일 수 있습니다.
포트 충돌을 줄이는 습관
프로젝트별 호스트 포트를 다르게 정합니다.
.env 파일로 포트 값을 분리합니다.
작업을 마치면 필요한 경우 docker compose down으로 정리합니다.
Docker Desktop에서 실행 중인 컨테이너를 주기적으로 확인합니다.
.env로 포트 값을 분리하면 같은 Compose 파일을 유지하면서 사람마다 다른 포트를 사용할 수 있습니다.
# .env
WEB_PORT=3001
# compose.yaml
services:
web:
ports:
- "${WEB_PORT}:3000"
공식 자료로 더 확인하기
Compose의 포트 매핑 방식과 명령어 동작은 Docker 공식 문서에서 기준을 확인하는 것이 좋습니다. 특히 팀 프로젝트에서는 개인 환경에서 임의로 판단하기보다 공식 문서의 명령어 의미를 기준으로 정리하는 편이 안전합니다.
Compose 파일에서 ports 설정으로 호스트 포트와 컨테이너 포트를 매핑하는 방식을 확인할 수 있습니다.
docker compose up이 서비스를 생성하고 시작하는 명령이라는 점과 주요 옵션을 확인할 수 있습니다.
Compose 프로젝트 컨테이너의 상태와 노출 포트를 확인하는 명령어 설명을 볼 수 있습니다.
docker compose ps 명령어 확인하기함께 보면 좋은 글
자주 묻는 질문
Docker Compose 포트 충돌은 먼저 어떤 프로세스가 호스트 포트를 사용 중인지 확인한 뒤, 필요한 경우 compose.yaml의 왼쪽 포트만 바꾸는 순서로 해결하는 것이 안전합니다.
댓글