Files
llm-wiki/raw/errors/bootstrap-postgres-port-collision-2026-06-24.md
T

69 lines
3.3 KiB
Markdown

---
title: error / bootstrap PostgreSQL host port collision (2026-06-24)
source_type: error-note
status: raw
related_branches: [feature-developer-experience-contract]
related_projects: [ca-skeleton]
tags: [error, ca-skeleton, runtime, docker, networking]
created: 2026-06-24
status_label: resolved
---
# error: bootstrap-postgres-port-collision
## Parent / 부모
- [[raw/branch-notes/feature-developer-experience-contract]]
## 증상 / Symptom
- 에러 메시지 (원문 그대로):
```text
Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint ca-tmpl-db-1: Bind for 0.0.0.0:5432 failed: port is already allocated
```
- 발생 컨텍스트: `cd src && ./gradlew bootstrap`의 `bootstrapDependencies` 단계.
- 발생 시점: 2026-06-24
- 발생 환경: local Docker Desktop/Engine
- 재현 가능 여부: `always` — 다른 container가 host 5432를 publish한 상태.
## 재현 절차 / Reproduction
1. 별도 PostgreSQL container가 `0.0.0.0:5432->5432`를 사용하도록 실행한다.
2. `cd src && ./gradlew bootstrap`을 실행한다.
3. 기대 결과는 bootstrap 전용 DB healthy지만 실제 결과는 `bootstrapDependencies` non-zero다.
## 조사 단계 / Investigation log
- 2026-06-24 — `docker compose ... config`로 렌더링 확인 → 신규 service는 loopback 5432 publish로 정확히 렌더링됨.
- 2026-06-24 — `ss -ltnp 'sport = :5432'` 확인 → host 5432가 이미 LISTEN 상태.
- 2026-06-24 — `docker ps --format ...` 확인 → 기존 `ca-pg`가 `0.0.0.0:5432`와 `[::]:5432`를 점유.
- 2026-06-24 — data flow 재검토 → Flyway는 app container가 internal Compose network의 `db:5432`로 실행하므로 host publish가 불필요함.
## 근본 원인 / Root cause
- 직접 원인: 두 container가 host TCP 5432를 동시에 publish하려 했다.
- 근본 원인: bootstrap 설계가 host-side migration을 하지 않는데도 DB port를 publish했다.
- 트리거 조건: 개발자 장비에서 다른 PostgreSQL/container가 5432를 점유한 상태.
## Sources / 근거
- [[raw/branch-notes/feature-developer-experience-contract]] D3 — bootstrap의 Compose dependency/Flyway 단계 정의.
- local command evidence — `docker compose config`, `ss`, `docker ps` 결과. 외부 공식 자료를 근거로 한 결정이 아니라 프로젝트 runtime topology 검증이다.
## 해결 / Resolution
- 적용한 조치: `docker-compose.local.yml`의 DB host port publish를 제거하고 app↔db internal network만 유지.
- 검증 방법: `./gradlew bootstrap` 재실행으로 DB healthy, startup Flyway, sample contract, HTTP smoke까지 exit 0 확인.
- 잔여 위험 / 후속 작업: host DB client가 필요한 개발자는 별도 override 파일로 명시적 port를 선택해야 한다.
## 회고 / Lessons
- 빨리 감지하는 신호: Docker 오류에 `port is already allocated`가 있으면 먼저 `docker compose config`와 `docker ps`를 함께 본다.
- 예방 체크리스트 항목 후보: container 간 통신만 필요한 dependency는 host port를 publish하지 않는다.
- wiki로 끌어올릴 가치가 있는 일반화된 교훈: local bootstrap의 network exposure 최소화.
## Related / 관련
- [[raw/errors/slim-jre-random-generator-missing-2026-06-24]]
- [[raw/blog-topics/five-stage-local-bootstrap-contract-2026-06-24]]