fix(backend): 운영 공개 URL 에 로컬 주소가 남으면 기동을 실패시킴

.env.production.example 이 개발용 값(localhost)을 그대로 담고 있어, 복사해 배포하면
서버는 정상 기동하지만 CORS 화이트리스트가 실제 도메인을 막고 프론트 번들은
localhost 를 호출한다 — 브라우저에서만 조용히 실패해 원인을 찾기 어렵다.

- CORS_ORIGIN·BACKEND_API_URL 에 로컬 주소나 예시 도메인이 있으면 운영에서 기동 실패
- 예제 값을 도메인 형태로 교체 (그대로 두면 이 검사에 걸린다)
- BACKEND_API_URL 은 앱이 쓰지 않지만 검사를 위해 compose 가 backend 에 주입한다
- 로컬에서 운영 이미지를 검증할 때만 ALLOW_LOCALHOST_URL=true 로 건너뛴다

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-21 11:42:23 +09:00
parent 94357d26bd
commit 52e671cedb
7 changed files with 120 additions and 2 deletions
+1
View File
@@ -8,6 +8,7 @@
## 1. 신규 프로젝트 셋업 (클론 직후 1회)
- [ ] 루트 `.env.{env}.example` → `.env.{env}` 복사 후 **placeholder 값 교체** (`change-me-*` 가 남아 있으면 안 된다, [[env-structure]])
운영은 `BACKEND_API_URL`·`CORS_ORIGIN` 을 **실제 도메인**으로 — `localhost`/`example.com` 이 남으면 기동 실패한다
- [ ] `backend/.env.{env}.example` → `backend/.env.{env}` 복사 후 `JWT_SECRET` 등 고유 시크릿 작성 (compose `env_file` 로 로드 — 파일이 없으면 기동 실패)
- [ ] `flutter/.env.example` → `flutter/.env` 복사 후 `API_URL` 확인 (Android 에뮬레이터: `10.0.2.2`)
— **이 파일이 없으면 `flutter analyze` 가 asset 경고를 낸다**
+4
View File
@@ -39,6 +39,10 @@ description: 환경변수 단일 진실 공급원(SSOT) 구조 — 루트 .env.{
- 숫자 항목은 형식 검사 (모든 환경)
- 운영 환경: `DB_HOST`/`DB_USER`/`DB_PASSWORD`/`DB_NAME` 필수
- 운영 환경: `change-me`·`password` 같은 **예시 값이 그대로 배포되는 것을 차단**
- 운영 환경: `CORS_ORIGIN`·`BACKEND_API_URL` 에 **로컬 주소(`localhost`·`127.0.0.1` 등)나
예시 도메인(`example.com`)이 남아 있으면 차단** — 기동은 되는데 브라우저만 조용히 실패하는 조합을 막는다.
로컬에서 운영 이미지를 검증하느라 일부러 localhost 를 쓸 때만 `ALLOW_LOCALHOST_URL=true` 로 건너뛴다
(`BACKEND_API_URL` 은 앱이 쓰지 않지만 이 검사를 위해 compose 가 backend 에 주입한다)
- 문제는 하나씩이 아니라 **한 번에 모아서** 보여준다 (재기동 반복 방지)
- 새 필수 설정을 추가하면 이 파일의 목록과 테스트도 함께 갱신한다