Skip to content

[INFRA] 운영에 PINLOG_AI_BASE_URL이 없다 — 실패가 조용히 삼켜진다 #102

Description

@minyongP

AI 연동에 필요한 환경변수 두 개가 운영 배포 계약에 없다. #101과 같은 뿌리(운영 주입 계약 누락)이지만 고치는 값과 결정 주체가 달라서 따로 남긴다.

#101과 순서가 얽혀 있다. 아래 2번 때문에 #101의 SPRING_PROFILES_ACTIVE=prod를 먼저 켜면 파드가 기동에 실패한다. 두 이슈를 같이 봐야 한다.

@cherry-go-round 주입 쪽, @colosair 주소 결정 쪽을 봐 주면 좋겠다.

1. PINLOG_AI_BASE_URL — 운영에서 localhost로 해석된다

back/src/main/resources/application.yml:79

pinlog:
  ai:
    base-url: ${PINLOG_AI_BASE_URL:http://localhost:8000}

application-prod.ymlpinlog.ai override가 없고, 인프라도 이 변수를 주입하지 않는다. 그래서 운영 파드는 자기 자신의 8000 포트로 AI를 호출한다.

실패 모드가 완전히 무음이다. 연결이 거부되면 AiProcessClient가 예외를 삼키고, Context 상태는 PENDING으로 남고, 재스캔은 아직 없다(#99). 결과는 파드는 뜨고, API는 200을 주고, 임베딩만 하나도 생기지 않는 상태다 — 이 연동이 애초에 막으려던 상태와 똑같다.

이 지적은 PR #82 리뷰(2026-07-29)에서 이미 나왔는데 반영되지 않았다. 당시 제안은 "application-prod.yml에 주소를 적어라"였지만, #101에서 확인된 대로 prod 프로파일 자체가 활성화되어 있지 않아 그렇게 고쳐도 적용되지 않는다. 리뷰가 프로파일이 켜져 있다고 전제했다.

2. PINLOG_AI_INTERNAL_SECRET — 프로파일을 켜는 순간 기동을 막는다

AiProcessClientrequireSecretJwtKeyProvider와 같은 기준으로 갈린다 — 운영 프로파일이면 기동 실패, 그 외는 경고 후 빈 값.

운영 프로파일에는 pinlog.ai.internal-secret(PINLOG_AI_INTERNAL_SECRET)이 필요하다.

인프라가 이 값을 주입하지 않는다. 따라서 #101에서 SPRING_PROFILES_ACTIVE=prod를 넣는 순간, JWT 키를 제대로 넣었더라도 이 값이 없어서 파드가 뜨지 않는다.

지금 프로파일이 꺼져 있어서 이 fail-fast도 무력화된 상태다. 현재 운영 파드는 빈 시크릿으로 동작하고 있고, FastAPI가 모든 호출을 401로 거절하며, 그 실패는 삼켜진다. 1번과 합쳐 두 겹으로 무음이다.

확인한 것

확인 대상 상태
back/.../application.yml:79, :82 둘 다 기본값 있음 — http://localhost:8000, 빈 문자열
back/.../application-prod.yml pinlog.ai 블록 없음
infra/ 전체 PINLOG_AI_BASE_URL·PINLOG_AI_INTERNAL_SECRET 주입 없음 (걸리는 것은 .github/workflows/ai-image-update.yaml의 GitHub Actions 토큰들뿐, 무관하다)
infra/apps/ prod에는 back만 있다. AI 서비스는 dev에만 배포되어 있다 (apps/dev/ai)
back/docs/development/configuration.md:82-86 인프라 요청 대상 표에 PINLOG_AI_INTERNAL_SECRET없다 (PR #82 리뷰 지적, 미반영)

먼저 정해야 하는 것

운영에서 back이 어느 AI 서비스를 호출하는가. apps/prod에 AI가 없으니 주소를 적을 수가 없다. 세 가지 중 하나를 정해야 한다.

  1. AI를 prod에도 배포한다 → 주소는 http://ai.pinlog-prod.svc.cluster.local:8000 형태
  2. 운영 back이 dev의 AI를 호출한다 → 네임스페이스를 가로지르는 주소, 그리고 그렇게 해도 되는지 판단이 필요하다
  3. 운영에서는 AI 연동을 끈다 → 그러면 지금처럼 조용히 실패하게 두지 않고 명시적으로 끄는 방법이 필요하다(현재 그런 스위치는 없다)

이건 AI 파트·인프라 결정이라 백엔드가 단독으로 정하지 않는다.

해야 할 일

백엔드 (주소가 정해진 뒤)

  • application-prod.ymlpinlog.ai.base-url을 적는다. 설정 규약대로 주소는 비밀이 아니므로 파일에 박고, 환경변수 이름을 새로 만들지 않는다(configuration.md "비밀값과 자격증명 주입"). application.yml${PINLOG_AI_BASE_URL:http://localhost:8000}은 로컬 기본값으로 남긴다
  • configuration.md의 인프라 요청 표에 PINLOG_AI_INTERNAL_SECRET을 넣는다

인프라

  • PINLOG_AI_INTERNAL_SECRET을 SealedSecret으로 만들어 apps/prod/back/values.yamlenv:에 넣는다. 값은 AI 쪽과 공유하는 시크릿이라 양쪽이 같아야 한다(헤더 이름 X-Internal-Secret, 원본은 ai 레포 app/core/security.py)
  • #101의 SPRING_PROFILES_ACTIVE=prod보다 먼저 들어가야 한다. 순서가 뒤바뀌면 파드가 기동에 실패한다

참고

Metadata

Metadata

Assignees

Labels

chore빌드·설정·잡무

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions