ai-rules 08-local-env · 로컬 개발 환경 안전 규칙

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

.envDATABASE_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 참조):

  1. .env와 런타임 포트가 틀어져 AI 에이전트가 잘못된 포트로 디버깅하는 사례가 반복됨
  2. DB 포트에는 애초에 적용 불가 — 클라이언트(앱)가 DB 포트를 미리 알아야 하는데, 자동 탐색은 .env를 업데이트하지 못함
  3. 외부 도구(DBeaver/Postman) 설정이 매번 꼬임
  4. 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 전파, vite envDir 등 활용)
  • 분리가 불가피하면 포트/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 파일 수정 변경 전/후 값 명시하고 사용자 확인
.envEXPECTED_DB_NAME 없음 런타임 DB 검증 스니펫 추가 제안 (07-db 참조)
find-port 스크립트 발견 deprecated 안내 + 고정 포트 전환 제안
Docker 컨테이너가 Created/Exited 상태 포트 충돌 가능성 경고 + docker compose logs 확인 요청
DATABASE_URL 포트와 docker-compose.yml ports 불일치 즉시 보고 + 동기화 요청
모노레포에서 루트 .envapps/*/.env 값 불일치 즉시 보고 — 임의 동기화 금지, 사용자가 정답 판단