08-local-env 로컬 개발 환경 안전 규칙
목적
목적
여러 프로젝트를 동시에 개발할 때 포트 충돌, DB 덮어쓰기, 환경변수 오염을 방지한다.
정책 개요
이 프로젝트는 "프로젝트별 고정 포트 할당(1-B)" 을 기본 정책으로 채택한다. 배경·대안 비교는 docs/guide/LOCAL_PORT_POLICY.md 참조.
핵심 원칙:
- 앱 포트(Frontend/Backend)와 DB 포트 모두 프로젝트마다 고유한 번호로 영구 고정
- 번호는
~/.claude/projects/PORT_REGISTRY.md로 중앙 관리 - 자동 포트 탐색(find-port)은 deprecated — AI 에이전트가
.env와 런타임이 틀어진 상태를 인지하기 어려움 - 런타임 방어선(DB 이름 검증)은 core/07-db.md 의 "DB 연결 검증" 섹션 참조
1. 포트 충돌 방지
신규 프로젝트 세팅 시 포트 체크 서브 프로토콜
아래는 §3의 전체 11단계 체크리스트 중 포트 관련 1~3 + 10단계 를 상세화한 것이다. §3이 전체 흐름, §1은 포트 단계의 세부 명령이다.
[1/5] PORT_REGISTRY 조회
cat ~/.claude/projects/PORT_REGISTRY.md
→ 다음 비어 있는 포트 번호 확인
[2/5] 호스트 포트 사용 현황 확인 (앱 + DB 포트 모두)
# Windows cmd / PowerShell / Git Bash
# findstr은 공백 구분 문자열을 OR 패턴으로 처리하며 literal 매칭이므로 /C: 로 각 포트 명시
netstat -ano | findstr "LISTENING" | findstr /C:":3000" /C:":3010" /C:":4000" /C:":4010" /C:":5432" /C:":5433" /C:":5434" /C:":5436" /C:":3306" /C:":27017" /C:":6379"
# macOS / Linux — lsof의 -i는 쉼표 리스트를 지원하지 않으므로 전체 LISTEN을 grep으로 필터
lsof -iTCP -sTCP:LISTEN -P -n | grep -E ':(3000|3010|4000|4010|5432|5433|5434|5436|3306|27017|6379)\b'
[3/5] Docker 컨테이너 상태 확인 (Docker 사용 프로젝트 한정)
docker ps -a --format "table {{.Names}}\t{{.Ports}}\t{{.Status}}"
→ Created/Exited 상태 컨테이너가 같은 포트를 노리고 있으면 충돌 위험 경고
[4/5] 결과를 사용자에게 보고
- 할당 예정 포트: frontend=3040, api=4040, db=5440
- 기존 점유 포트: 3000(meetflow), 3010(ax-studio-plan), 5432(meetflow-postgres), ...
- 충돌 여부 판정
[5/5] PORT_REGISTRY 업데이트 (사용자 승인 후)
→ 새 프로젝트 행 추가
충돌이 발견되면 즉시 사용자에게 보고 — 에이전트가 임의로 포트를 바꾸지 않는다. 사용자가 대안 번호를 지정한 뒤에만 진행.
PORT_REGISTRY 기반 고정 포트 할당 (1-B 패턴)
번호는 프로젝트당 10씩 증가. 역할별로 다른 수천의 자리(3000/4000/5432+) 사용.
| 역할 | 기본 시작 | 할당 규칙 |
|---|---|---|
| Frontend (SPA/SSR) | 3000 | 프로젝트당 +10 |
| Backend API (Node) | 4000 | 프로젝트당 +10 |
| Backend (Python/FastAPI) | 8000 | 프로젝트당 +10 |
| DB (PostgreSQL 호스트 포트) | 5432 | 프로젝트당 +1 |
| DB (MySQL 호스트 포트) | 3306 | 프로젝트당 +1 |
| Admin / Storybook | 6000 | 프로젝트당 +10 |
| DB GUI (Prisma Studio 등) | 5555 | 프로젝트당 +10 |
예시:
- 프로젝트 A: frontend=3000, api=4000, db=5432
- 프로젝트 B: frontend=3010, api=4010, db=5433
- 프로젝트 C: frontend=3020, api=4020, db=5434
한번 할당된 포트는 프로젝트가 삭제되기 전까지 재사용 금지 — 과거 개발자의 외부 도구 설정, 북마크, 스크립트가 무효화되는 것을 방지.
Docker Compose 사용 시 DB 포트 명시
DB 포트는 반드시 호스트 포트로 명시한다. "5432:5432"처럼 기본값에 의존하지 않는다.
# ❌ 금지 — 호스트 포트 자동 결정
services:
db:
image: postgres:16
# ports 미지정 또는 환경에 따라 달라지는 매핑
# ❌ 금지 — 여러 프로젝트가 같은 호스트 포트 사용
services:
db:
ports: ["5432:5432"] # 다른 프로젝트와 충돌 시 Created 상태로 조용히 대기
# ✅ 권장 — 프로젝트별 고정 호스트 포트
services:
db:
ports: ["5433:5432"] # 호스트 5433 ← 컨테이너 5432
.env의 DATABASE_URL도 동일 호스트 포트를 가리키게 유지:
# .env (ax-studio-plan 예시)
DATABASE_URL="postgresql://postgres:postgres@localhost:5433/ax_studio_plan_dev"
EXPECTED_DB_NAME=ax_studio_plan_dev # 런타임 검증용 (07-db 참조)
⚠️ 자동 포트 탐색(find-port) — deprecated
이전 버전 규칙에서 scripts/find-port.mjs 패턴을 권장했으나, 2026-04-15부터 deprecated로 전환한다.
이유 (상세는 LOCAL_PORT_POLICY.md 참조):
.env와 런타임 포트가 틀어져 AI 에이전트가 잘못된 포트로 디버깅하는 사례가 반복됨- DB 포트에는 애초에 적용 불가 — 클라이언트(앱)가 DB 포트를 미리 알아야 하는데, 자동 탐색은
.env를 업데이트하지 못함 - 외부 도구(DBeaver/Postman) 설정이 매번 꼬임
- 1-B 고정 할당이 있으면 충돌 자체가 드묾 → 자동 탐색의 가치가 낮음
기존 프로젝트 대응:
- 이미
scripts/find-port.mjs,src/utils/find-port.ts,scripts/start.py등이 있는 프로젝트는 점진적으로 제거 - 제거 시점: 다음 번 해당 프로젝트의 로컬 세팅 정리 PR 또는
.env수정 작업 중 - 즉시 제거가 부담스러우면 파일 상단에 deprecated 주석 추가 후 새 프로젝트부터 채택 안 함
신규 프로젝트: find-port 스크립트 금지. 1-B 고정 할당만 사용.
모노레포 다중 .env 동기화
모노레포(apps/*/, packages/*/, services/*/ 등)에서는 하위 패키지마다 .env가 별도로 존재할 수 있다. 루트 .env만 수정하고 하위를 놓치면 앱이 잘못된 포트로 붙는 사고가 반복적으로 발생한다.
원칙:
- 프로젝트 내 모든
.env는 같은 PORT_REGISTRY 값을 가리켜야 한다 (DB URL, 포트, EXPECTED_DB_NAME 모두) - 가능하면 dotenv 로더를 루트 단일 파일로 통일 (turborepo
globalEnv, nx env 전파, viteenvDir등 활용) - 분리가 불가피하면 포트/DB URL 값은 동일하게 유지하고, 각
.env파일 상단에 "루트.env와 동기화 필수" 주석 추가
세팅 또는 포트 변경 시 전수 확인 명령:
# 프로젝트 내 모든 .env 파일을 찾아 DATABASE_URL 과 PORT 값 비교
find . -name ".env*" -not -path "*/node_modules/*" -not -name "*.example" 2>/dev/null \
| xargs grep -E "DATABASE_URL|PORT=" 2>/dev/null
# 결과의 모든 행이 같은 호스트 포트와 DB 이름을 가리키는지 확인
불일치 발견 시 즉시 사용자에게 보고 — 에이전트가 임의로 동기화하지 않는다 (어느 값이 정답인지 사람이 판단해야 함).
.env.example 포트 표기 규칙
# .env.example — 포트는 반드시 PORT_REGISTRY의 할당값 명시
PORT=4010 # Backend API 포트 — PORT_REGISTRY 할당값 (변경 금지)
FRONTEND_PORT=3010 # Frontend 포트 — PORT_REGISTRY 할당값
# 새 프로젝트 세팅 시 ~/.claude/projects/PORT_REGISTRY.md 에서 다음 비어 있는 번호를 할당받아 사용
DATABASE_URL="postgresql://postgres:postgres@localhost:5433/{프로젝트명}_dev"
EXPECTED_DB_NAME={프로젝트명}_dev # 런타임 DB 검증용 (07-db 참조)
2. DB 충돌 방지 (신규 프로젝트 세팅)
신규 프로젝트 세팅 시 아래 순서로 진행:
2-1. 기존 DB 목록 확인
# PostgreSQL
psql -U postgres -c "\l" | grep -v template | grep -v "^$"
# 다른 프로젝트의 DB 이름 중복 확인
# {your-projects-root} 는 본인의 작업 디렉토리로 치환 (예: ~/dev, /d/dev-project, ~/workspace 등)
# 여러 작업 디렉토리를 쓴다면 각각 실행
find {your-projects-root} -name ".env" -not -path "*/node_modules/*" 2>/dev/null \
| xargs grep "DATABASE_URL" 2>/dev/null
2-2. 고유한 DB 이름 결정
| ✅ 올바른 예 | ❌ 금지 예 |
|---|---|
ax_studio_plan |
ax_studio (다른 프로젝트와 동일) |
aitem_v2_dev |
dev, test, app, database |
printstudio_local |
postgres |
lro_engine_dev |
mydb |
2-3. DB 생성
# 에이전트가 안내하는 명령어, 실행은 사람이 직접
createdb -U postgres {프로젝트명}_dev
# 또는
psql -U postgres -c "CREATE DATABASE {프로젝트명}_dev;"
2-4. .env 설정
# .env
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/{프로젝트명}_dev"
3. 신규 프로젝트 로컬 세팅 체크리스트 (에이전트 실행 프로토콜)
에이전트가 신규 프로젝트 세팅 시 반드시 이 순서를 출력하며 따른다. 각 항목의 결과를 사용자에게 보고하고 승인받은 뒤 다음 단계로 진행한다.
[ ] 1. PORT_REGISTRY 조회 — ~/.claude/projects/PORT_REGISTRY.md 에서 다음 비어 있는 포트 결정
[ ] 2. 호스트 포트 사용 현황 확인 — 앱 포트 + DB 포트(5432/3306/27017/6379 등) 모두 스캔
[ ] 3. Docker 컨테이너 상태 확인 — 같은 포트를 노리는 Created/Exited 컨테이너 감지
[ ] 4. DB 이름 중복 확인 — 기존 프로젝트 DB 이름과 겹치지 않는 이름 결정 (07-db 참조)
[ ] 5. .env 작성 — 결정된 포트/DB 이름 반영 + EXPECTED_DB_NAME 포함
(모노레포면 apps/*/.env, packages/*/.env 까지 전수 확인 → §1 "모노레포 다중 .env 동기화" 참조)
[ ] 6. .env.example 동기화 — 실제 값 없이 키+주석만 포함, PORT_REGISTRY 참조 링크 명시
[ ] 7. .gitignore 확인 — .env가 포함되어 있는지 확인
[ ] 8. docker-compose.yml 포트 명시 — DB 호스트 포트를 프로젝트 고유 값으로 고정
[ ] 9. 런타임 DB 검증 코드 추가 — 앱 부팅 시 current_database() 확인 (07-db 참조)
[ ] 10. PORT_REGISTRY 업데이트 — 새 프로젝트 행 추가
[ ] 11. README에 로컬 세팅 가이드 작성 — 포트/DB 이름/검증 방식 명시
주의: find-port 스크립트 추가 금지 — 자동 탐색 패턴은 deprecated.
4. 공통 .gitignore 항목
신규 프로젝트 .gitignore에 반드시 포함:
# 환경변수 — 절대 커밋 금지
.env
.env.local
.env.*.local
!.env.example # example은 커밋 허용
# DB 덤프 — 로컬 백업 파일
*.sql
*.dump
backup_*.sql
# 로컬 개발 도구
.prisma/
5. 에이전트 행동 규칙
| 상황 | 에이전트 행동 |
|---|---|
| 신규 프로젝트 세팅 | PORT_REGISTRY 조회 → 포트/DB 충돌 확인 → 결과 보고 후 진행 |
| 포트 충돌 감지 | 즉시 사용자에게 보고 — 임의 변경 금지 |
| DB 이름 중복 감지 | 즉시 사용자에게 경고 + 대안 이름 제안 |
| .env 파일 수정 | 변경 전/후 값 명시하고 사용자 확인 |
.env에 EXPECTED_DB_NAME 없음 |
런타임 DB 검증 스니펫 추가 제안 (07-db 참조) |
| find-port 스크립트 발견 | deprecated 안내 + 고정 포트 전환 제안 |
| Docker 컨테이너가 Created/Exited 상태 | 포트 충돌 가능성 경고 + docker compose logs 확인 요청 |
DATABASE_URL 포트와 docker-compose.yml ports 불일치 |
즉시 보고 + 동기화 요청 |
모노레포에서 루트 .env와 apps/*/.env 값 불일치 |
즉시 보고 — 임의 동기화 금지, 사용자가 정답 판단 |