perf(docker): 개발 프론트엔드를 컨테이너에서 호스트 vite 로 전환

Windows 바인드 마운트(./frontend:/app) 너머의 소스를 vite 가 모듈마다 읽는 데다
폴링 감시까지 항상 켜져 있어 첫 서빙에 수 분이 걸렸다. 호스트에서 띄우면 2초다.

- dev 오버라이드의 frontend 를 compose profile `frontend` 뒤로 숨긴다 (운영은 그대로)
- 폴링 감시는 CHOKIDAR_USEPOLLING 으로 컨테이너에서만 켠다
- dev 서버 포트·프록시 대상을 루트 .env.{mode} 에서 읽는다 (포트 SSOT 유지)
  포트 충돌 시 조용히 옮기지 않도록 strictPort — CORS_ORIGIN·포트 매핑이 묶여 있다

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-21 11:41:19 +09:00
parent 40af8a2e09
commit 94357d26bd
9 changed files with 195 additions and 38 deletions
+44 -1
View File
@@ -12,8 +12,12 @@ description: Docker Compose 기반 로컬·운영 오케스트레이션 실행/
## 개발 환경
> **개발 환경에서 프론트엔드는 컨테이너로 뜨지 않는다.** compose profile `frontend` 뒤에 숨겨져 있다.
> vite 를 컨테이너에서 돌리면 소스가 바인드 마운트(`./frontend:/app`) 너머라 첫 서빙까지 수 분이 걸린다.
> 프론트엔드는 호스트에서 `cd frontend && npm run dev` 로 띄운다 (아래 "프론트엔드는 호스트에서" 참조).
```bash
# 코드만 수정했을 때 (의존성 변경 없음)
# 코드만 수정했을 때 (의존성 변경 없음) — backend + db 가 뜬다
docker compose -f docker-compose.yml -f docker-compose.dev.yml --env-file .env.development up -d
# 의존성 변경 시에만 --build
@@ -35,6 +39,44 @@ sudo docker compose --env-file .env.production logs -f backend
---
## 프론트엔드는 호스트에서 (개발 환경)
```bash
cd frontend && npm install && npm run dev # → http://localhost:5173
```
- **포트는 루트 `.env.{APP_ENV}` 가 SSOT 다** ([[env-structure]]). `vite.config.ts` 가 루트 env 를 직접 읽어
`FRONTEND_PORT` 로 열고, `/api` 프록시 대상은 `http://localhost:${BACKEND_PORT}`(백엔드 컨테이너가
호스트에 노출한 포트)로 잡는다. 포트를 바꿀 때 루트 env 한 줄만 고치면 된다.
백엔드를 아예 다른 주소에 띄웠다면 `VITE_DEV_API_PROXY` 로 대상을 덮어쓴다.
- `strictPort: true` 라 포트가 이미 사용 중이면 **다음 포트로 옮기지 않고 실패**한다.
`CORS_ORIGIN` 과 compose 포트 매핑이 그 포트에 묶여 있어, 조용히 5174 로 옮겨가면
API 요청이 원인 모르게 막힌다 (fail-fast).
- 폴링 감시(`watch.usePolling`)는 **컨테이너에서만** 켜진다 (`CHOKIDAR_USEPOLLING` 로 판별).
호스트에서는 OS 파일 감시 이벤트로 충분하며, 폴링을 켜면 기동이 느려지고 CPU 만 쓴다.
- 의존성 설치는 호스트에서 해도 된다 — 프론트엔드 dev 는 컨테이너를 쓰지 않으므로
lock 파일이 깨지는 문제([[nestjs]] 의 Windows 주의 항목)는 **backend 에만** 해당한다.
단 `frontend` 프로필이나 운영 이미지를 빌드할 계획이라면 같은 주의가 적용된다.
### 컨테이너로 띄워야 할 때 (선택)
호스트에 Node 를 둘 수 없는 환경 등에서만 쓴다. 느린 것은 정상이다.
```bash
# 일회성
docker compose -f docker-compose.yml -f docker-compose.dev.yml --env-file .env.development --profile frontend up -d
# 상시 — 루트 .env.development 에 (redis 와 함께 켤 때는 frontend,redis)
COMPOSE_PROFILES=frontend
```
- 호스트 vite 와 컨테이너 vite 는 같은 호스트 포트(`FRONTEND_PORT`)를 쓴다 — **동시에 띄우지 말 것.**
- 컨테이너 **내부** 포트는 5173 고정이다 (compose 의 `--port`·healthcheck·포트 매핑이 함께 묶여 있다).
루트 env 는 컨테이너 안에 없으므로 `vite.config.ts` 는 기본값으로 떨어지고, compose 의 `--port` 가 이긴다.
- 운영(`docker-compose.yml` 단독)에는 profile 이 없으므로 nginx 정적 호스팅이 그대로 동작한다.
---
## 자주 쓰는 보조 명령
> 개발 prefix가 길어 아래는 다음 별칭으로 줄여 표기한다.
@@ -103,6 +145,7 @@ docker compose -f docker-compose.runner.yml --env-file .env up -d
```bash
# 켜기 — 루트 .env.{APP_ENV} 한 줄 수정 (이후 평소 명령 그대로)
COMPOSE_PROFILES=redis
# (프론트엔드 컨테이너도 함께 켤 때는 COMPOSE_PROFILES=redis,frontend)
# 또는 일회성
dc --profile redis up -d