From b665c34ac211d4701e986860993521d5ecf6ded4 Mon Sep 17 00:00:00 2001 From: hbyang Date: Mon, 7 Sep 2026 16:05:01 +0900 Subject: [PATCH] =?UTF-8?q?[fix]=20deploy:=20.env.example=20=EA=B7=B8?= =?UTF-8?q?=EB=8C=80=EB=A1=9C=20=EC=93=B0=EB=A9=B4=20=EB=A1=9C=EC=BB=AC=20?= =?UTF-8?q?=EB=B0=9C=ED=96=89=EC=9D=B4=20=EC=95=88=20=EB=90=90=EB=8B=A4=20?= =?UTF-8?q?=E2=80=94=20DB=5FHOST=20=EC=99=80=20=EC=A4=84=EB=81=9D=20?= =?UTF-8?q?=EC=A3=BC=EC=84=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 문서대로 `cp .env.example .env` → `docker compose up -d` → 발행을 걸면 게이트는 통과하고 발행만 실패한다. 두 함정이 겹쳐 있었다(둘 다 실측). - DB_HOST=127.0.0.1: 컨테이너 안의 127.0.0.1 은 그 컨테이너다. 증상이 고약하다 — API 는 /healthz 가 DB 를 안 보므로 200 healthy 로 뜨고 워커만 조용히 재시작을 반복한다. compose 기본값(host.docker.internal)을 기본으로 올리고, 127.0.0.1 은 네이티브 실행용이라고 적었다 - 줄 끝 주석이 값이 된다: env_file 은 `KEY= # 설명` 을 빈 값으로 읽지 않는다. Azure 를 끈 로컬에서 is_configured() 가 참이 되어 발행 잡이 업로드를 시도하고 죽었다 (Connection string is either blank or malformed). 같은 모양 5개를 윗줄로 올리고, 파일 머리에 규칙을 근거와 함께 박았다 검증: web4ai_db 신규 생성 + init.sql → compose up → demo_build.py 발행 게이트 통과 · published:true · http://localhost/s/ 200. --- .env.example | 27 +++++++++++++++++++++------ docs/DEVLOG.md | 26 ++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/.env.example b/.env.example index 950d8b1..e945f04 100644 --- a/.env.example +++ b/.env.example @@ -1,10 +1,20 @@ # cp .env.example .env 후 값을 채운다. .env 는 커밋되지 않는다. # 우선순위: 실제 환경변수(compose) > .env > 코드 기본값(config_models.py) +# +# ★ 값 뒤에 주석을 붙이지 않는다. compose 의 `env_file` 은 줄 끝 주석을 **값으로 읽는다** — +# `AZURE_STORAGE_CONNECTION_STRING= # 비우면...` 은 "빈 값"이 아니라 "# 비우면..." 이라는 값이다. +# 실측(2026-09-07): 그래서 Azure 를 끈 로컬에서 발행 잡이 업로드를 시도하고 +# "Connection string is either blank or malformed" 로 죽었다. 게이트는 통과했는데 발행만 실패한다. +# 주석은 반드시 **윗줄**에 둔다. # ── 공통 solution/backend · admin/backend (server_configs 가 읽는다) APP_ENV=local -DB_HOST=127.0.0.1 +# ★ compose 로 띄우면 `host.docker.internal` 이다 — 컨테이너 안의 127.0.0.1 은 그 컨테이너다. +# 127.0.0.1 은 백엔드를 **네이티브로**(.venv/bin/python) 돌릴 때만 맞다. +# 이 값을 그대로 두고 `docker compose up` 하면 API 는 healthz 200 으로 멀쩡해 보이는데 +# 워커만 조용히 재시작을 반복한다(ConnectionRefusedError 5432) — 발행 잡이 영원히 안 돈다. +DB_HOST=host.docker.internal DB_PORT=5432 DB_USER=postgres DB_PASSWORD= @@ -17,12 +27,15 @@ JWT_REFRESH_SECRET= # 키가 비면 그 어댑터만 꺼진다. 서버는 뜬다. PERPLEXITY_API_KEY= -COLLECT_USE_PERPLEXITY=0 # Perplexity 채널 발견. 0=끔(기본) +# Perplexity 채널 발견. 0=끔(기본) +COLLECT_USE_PERPLEXITY=0 NAVER_CLIENT_ID= NAVER_CLIENT_SECRET= -KAKAO_REST_API_KEY= # 미발급. 없으면 네이버 지역검색을 쓴다 +# 미발급. 없으면 네이버 지역검색을 쓴다 +KAKAO_REST_API_KEY= GEMINI_API_KEY= -TOUR_API_KEY= # 디코딩된 키(인코딩 키는 이중 인코딩된다) +# 디코딩된 키(인코딩 키는 이중 인코딩된다) +TOUR_API_KEY= # 구글 로그인. 비우면 구글 로그인만 꺼진다(서버는 뜨고, 화면에 버튼도 안 뜬다). # Google Cloud Console > API 및 서비스 > 사용자 인증 정보 > OAuth 2.0 클라이언트 ID(웹 애플리케이션) @@ -46,8 +59,10 @@ GOOGLE_CLIENT_ID= # canonical·og:url·sitemap·IndexNow 가 전부 SITE_PUBLIC_HOST 를 쓴다. # 로컬은 비워 둔다(기본값 localhost). 서버에 올릴 때만 실제 도메인을 적는다. # SITE_PUBLIC_HOST=web4ai.o2osolution.ai -INDEXNOW_KEY= # 비우면 색인 통보를 건너뛴다(발행은 정상) -AZURE_STORAGE_CONNECTION_STRING= # 비우면 로컬 발행만 한다 +# 비우면 색인 통보를 건너뛴다(발행은 정상) +INDEXNOW_KEY= +# 비우면 로컬 발행만 한다 +AZURE_STORAGE_CONNECTION_STRING= AZURE_STORAGE_CONTAINER= AZURE_STORAGE_PREFIX= diff --git a/docs/DEVLOG.md b/docs/DEVLOG.md index bfb7dba..717e63c 100644 --- a/docs/DEVLOG.md +++ b/docs/DEVLOG.md @@ -5,6 +5,32 @@ --- +## 2026-09-07 — `.env.example` 그대로 쓰면 로컬 발행이 안 됐다 — 함정 둘 + +클론 직후 문서대로 `cp .env.example .env` 하고 `docker compose up -d` 한 다음 발행을 걸어 봤다. +**게이트는 통과하는데 발행만 실패한다.** 두 가지가 겹쳐 있었다. + +**1) `DB_HOST=127.0.0.1`** — 컨테이너 안의 127.0.0.1 은 그 컨테이너다. compose 기본값은 +`host.docker.internal` 인데 `.env` 가 그걸 덮어쓴다. 증상이 고약하다: API 는 `/healthz` 가 +DB 를 안 보므로 **200 healthy** 로 뜨고, **워커만 조용히 재시작을 반복한다** — 화면은 멀쩡하고 +발행 잡만 영원히 안 돈다. + +**2) 줄 끝 주석이 값이 된다.** compose 의 `env_file` 은 `KEY= # 설명` 을 "빈 값"으로 읽지 +않는다 — 값이 `"# 설명"` 이다. 그래서 Azure 를 끈 로컬에서 `is_configured()` 가 참이 되고 +발행 잡이 업로드를 시도해 `Connection string is either blank or malformed` 로 죽었다. +같은 모양이 5개였다: `COLLECT_USE_PERPLEXITY`(값 `0` 이 `"0 # ..."` 가 된다) · +`KAKAO_REST_API_KEY` · `TOUR_API_KEY` · `INDEXNOW_KEY` · `AZURE_STORAGE_CONNECTION_STRING`. + +**고친 것** — `.env.example`: `DB_HOST` 기본값을 `host.docker.internal` 로 바꾸고 네이티브 +실행 때만 127.0.0.1 이라는 것을 주석으로 남겼다. 값 뒤 주석은 전부 **윗줄로 올렸고**, +파일 머리에 "값 뒤에 주석을 붙이지 않는다" 를 근거와 함께 박았다. + +**검증** — 새 DB(`web4ai_db`)에 `init.sql` 적용 → `docker compose up -d` → 워커 정상 기동 → +`scripts/demo_build.py` 로 발행: 게이트 통과 · `published: true` · 프리렌더가 굽고 +`http://localhost/s/` 200. ★ 참고로 `demo_build.py` 는 자기 안에서 워커를 한 번 돌리는데, +compose 워커가 잡을 먼저 집어가므로 **스크립트 출력은 "게이트 거부"로 보인다** — 실제 결과는 +`job.jobs.result` 와 워커 로그에 있다. + ## 2026-09-07 — 숙박 예약 구성 — "실시간 예약" 섹션이 전화번호 한 줄이었다 **왜**