ADR-003 backend 다중 인스턴스 + nginx LB = docker-compose.lb.yml 오버레이

상태

채택 (2026-07-03)

맥락

상시 고부하 흡수를 위해 backend 다중 인스턴스(초기 3) + LB가 필요하다(FR-1). ⑧ compose 소유 경계표는 ⑦에 docker-compose.lb.yml을 부여했고, base(⑧)·override(⑧)·observability(⑤)는 ⑦가 수정하지 않는다(Single Writer). infra/nginx/mcp.confupstream sports_backend { server 127.0.0.1:8080; }(MCP 전용·TLS placeholder·컨테이너 내 미해석)로 이미 존재한다.

결정

docker-compose.lb.yml(⑦ 소유)에서 backend를 deploy.replicas: 3(내부 8080만, host 포트 미노출)으로 override하고, nginx-lb 서비스(80/443)가 유일 진입점이 된다. LB용 nginx 설정은 신규 infra/nginx/lb.conf(⑦ 소유)에 두고 upstream sports_backendserver backend:8080으로 재정의한다. Docker 임베디드 DNS(resolver 127.0.0.11 valid=10s) + 변수 proxy_pass로 replica를 매 요청 재해석해 라운드로빈한다. mcp.conf는 무수정.

근거

  • ⑧ 경계표 준수 — base·override 무수정, 추가 -f로만 병합.
  • replicas면 정적 host 포트를 못 주므로 backend는 내부 포트만, nginx가 앞단 → 표준 패턴.
  • 정적 upstream은 첫 IP만 캐시 → resolver + 변수 proxy_pass로 replica 재해석.
  • sports_backend 이름 재사용(mcp.conf 관례 계승)하되 실체만 컨테이너 DNS로 재정의 → in-place 수정(MCP 동작 변경·Single Writer 충돌) 회피.
  • 인스턴스 헬스체크(/actuator/health) + proxy_next_upstream로 비정상 replica 우회.

결과

  • prod override의 backend 직접 노출은 lb 오버레이가 덮음(⑧ 경계표 명시).
  • ⑤가 3개 backend 타깃을 scrape(다중 타깃 확장은 ⑤가 설계 반영).
  • 미채택: mcp.conf in-place 다중 서버화, --scale CLI만(비선언·재현성 낮음).