o2o-negosium-original/docker-compose.prod.landing.yml

215 lines
8.9 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

services:
# ── 프론트 (React/Vite → 정적 빌드 → nginx) ──────────────────────────────
negodata-front:
build:
context: ./negodata/front
dockerfile: Dockerfile.prod
container_name: negodata-front
ports:
- "${NEGODATA_FRONT_PORT:-30012}:80"
depends_on:
- negodata-backend # nginx 가 시작 시 upstream(negodata-backend) 이름을 해석해야 함
restart: unless-stopped
negosium-front:
build:
context: ./frontend
dockerfile: Dockerfile.prod
container_name: negosium-front
ports:
- "${NEGOSIUM_FRONT_PORT:-30010}:80"
depends_on:
- negosium-backend
restart: unless-stopped
# ── 솔루션 랜딩 (React Router SSG → 정적 빌드 → nginx) ───────────────────
landing:
build:
context: ./landing
dockerfile: Dockerfile.prod
container_name: negosium-landing
ports:
- "${LANDING_PORT:-30013}:80"
restart: unless-stopped
# ── 백엔드 (FastAPI, 기존 Dockerfile) ────────────────────────────────────
negodata-backend:
build: ./negodata/backend
container_name: negodata-backend
environment:
APP_ENV: prod
SCHEDULER_ENABLED: "1" # 견적 자동마감 크론(process_count=1 단일 워커라 중복 없음)
PYTHONUNBUFFERED: "1"
LPS_BASE_URL: http://lps-api:9600 # 최저가 검색요청 enqueue — 같은 compose 망의 lps-api 컨테이너(미설정 시 localhost:9600 → 연결실패)
# LPS 읽기 DB(lps_db)는 config.prod.toml 의 [LpsDBConfig](172.30.1.36/o2o_db_admin) 이 담당 → 별도 env 불필요
DB_HOST: ${DB_HOST} # toml 의 127.0.0.1 을 외부 DB 로 override
DB_PORT: ${DB_PORT:-5432}
DB_USER: ${DB_USER}
DB_PASSWORD: ${DB_PASSWORD}
DB_NAME: ${DB_NAME:-negosium_db}
volumes:
- ./negodata/backend/config/config.prod.toml:/app/config/config.prod.toml:ro
# 외부 비노출 — negodata-front 의 nginx 가 /v1 을 내부망으로 프록시.
extra_hosts:
- "host.docker.internal:host-gateway" # DB 가 이 서버 호스트면 DB_HOST=host.docker.internal
restart: unless-stopped
negosium-backend:
build: ./backend
container_name: negosium-backend
environment:
APP_ENV: prod
AGENT_BASE_URL: http://agent:9500 # 내부망으로 agent 호출
PYTHONUNBUFFERED: "1"
DB_HOST: ${DB_HOST}
DB_PORT: ${DB_PORT:-5432}
DB_USER: ${DB_USER}
DB_PASSWORD: ${DB_PASSWORD}
DB_NAME: ${DB_NAME:-negosium_db}
volumes:
- ./backend/config/config.prod.toml:/app/config/config.prod.toml:ro
# 외부 비노출 — negosium-front 의 nginx 가 /v1 을 내부망으로 프록시.
extra_hosts:
- "host.docker.internal:host-gateway"
restart: unless-stopped
# ── 협상 에이전트 (Python, 내부 전용) ────────────────────────────────────
agent:
build: ./agent
container_name: negosium-agent
environment:
APP_ENV: prod
PYTHONUNBUFFERED: "1"
DB_HOST: ${DB_HOST}
DB_PORT: ${DB_PORT:-5432}
DB_USER: ${DB_USER}
DB_PASSWORD: ${DB_PASSWORD}
DB_NAME: ${DB_NAME:-negosium_db}
volumes:
- ./agent/config/config.prod.toml:/app/config/config.prod.toml:ro
extra_hosts:
- "host.docker.internal:host-gateway"
restart: unless-stopped
# ── 앵커링 값 자동 조정 배치 (negosium_db 공유, 포트 없음 — 상주 스케줄러) ──
# 이미지는 config.{APP_ENV}.toml 을 읽는다(dev/prod 는 파일 없으면 기동 중단). DB/시크릿은
# config.prod.toml(172.30.1.36) 에서 온다 — env(DB_*/REDIS_*) 를 설정하면 파일값을 override.
anchoring:
build: ./schedules/anchoring
container_name: anchoring
environment:
APP_ENV: prod # → config.prod.toml 선택 (local 로 두면 빈 config.local 로 기동 실패)
REDIS_HOST: anchoring-redis # 전용 캐시 컨테이너 사용(config 의 redis host 를 override)
TZ: Asia/Seoul
volumes:
- ./schedules/anchoring/config.prod.toml:/app/config.prod.toml:ro # DB 접속·시크릿은 파일에서(마운트 필수)
depends_on:
- anchoring-redis
extra_hosts:
- "host.docker.internal:host-gateway"
restart: unless-stopped
logging: # 상주 배치 — 장기 운영 디스크 보호
driver: json-file
options:
max-size: "10m"
max-file: "5"
# 앵커링 조회 캐시 (anchoring 전용)
anchoring-redis:
image: redis:7-alpine
container_name: anchoring-redis
ports:
- "127.0.0.1:6380:6379" # 호스트 로컬만 개방 (무인증 Redis). 6380 = 호스트 redis(6379)와 충돌 회피
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
# ── LPS (인터넷 최저가 검색) ──────────────────────────────────
# API(요청 접수) + 워커(크롤, Chromium+Xvfb).
# 이미지는 APP_ENV=local 고정 → config.local.toml 을 읽는다. prod 실값(DB 172.30.1.36 /
# o2o_db_admin / negosium_db + OpenAI·Naver·Decodo 시크릿)은 config.prod.toml 을 그 경로에
# 마운트해 주입한다(다른 prod 서비스와 동일한 파일 기반 방식). DB_* env 는 주지 않는다 —
# 주면 파일값을 빈 값/오타로 덮어써 인증 실패(예: 사용자 o2oadmin)한다.
lps-api:
build:
context: ./lps
dockerfile: Dockerfile
container_name: lps-api
environment:
APP_ENV: local # 이미지 고정값 — 변경 금지(config.prod.toml 을 직접 읽지 않음)
PYTHONUNBUFFERED: "1"
PROCESS_COUNT: ${LPS_API_PROCESS_COUNT:-1}
DB_CONNECTION_BUDGET: ${LPS_DB_CONNECTION_BUDGET:-40} # 전용 PG(max_connections≈100)면 90 근처로 상향
volumes:
- ./lps/config/config.prod.toml:/app/config/config.local.toml:ro # prod DB·시크릿 주입(APP_ENV=local 이 읽는 경로 덮어씀)
ports:
- "9600:9600"
extra_hosts:
- "host.docker.internal:host-gateway"
labels:
autoheal: "true" # HEALTHCHECK 실패 시 autoheal 이 재시작
restart: unless-stopped
logging:
driver: json-file
options: { max-size: "10m", max-file: "5" }
lps-worker:
build:
context: ./lps
dockerfile: Dockerfile.worker # Chromium + Xvfb (headless 는 안티봇에 탐지됨)
container_name: lps-worker
environment:
APP_ENV: local # 이미지 고정값 — 변경 금지
PYTHONUNBUFFERED: "1"
WORKER_CONCURRENCY: "1" # 상품 동시 검색 수(워커별 브라우저 세트, Chrome 4×N)
LPS_PROFILE_DIR: /profiles # Chrome 프로필을 영속 볼륨에 → 재시작해도 cf_clearance 유지
# DB·시크릿(OpenAI/Naver/Decodo)은 아래 config.prod.toml 마운트에서 온다. env override 는 주지 않는다.
volumes:
- ./lps/config/config.prod.toml:/app/config/config.local.toml:ro # prod DB·시크릿 주입(APP_ENV=local 이 읽는 경로 덮어씀)
- lps-profiles:/profiles # Chrome 프로필(쿠키) 영속
extra_hosts:
- "host.docker.internal:host-gateway"
shm_size: "1gb" # Chrome 는 /dev/shm 을 많이 씀 — 부족하면 탭 크래시
stop_grace_period: 75s # graceful 종료 유예 — 기본 10s 면 하던 잡 마무리 전에 SIGKILL
labels:
autoheal: "true" # 하트비트 HEALTHCHECK 실패(행/좀비) 시 autoheal 이 재시작
restart: unless-stopped
logging:
driver: json-file
options: { max-size: "10m", max-file: "5" }
# LPS 관리자 UI (정적 React → nginx). /v1·/healthz·/readyz 는 nginx 가 lps-api:9600 으로 프록시(동일 compose 망).
lps-admin:
build:
context: ./lps-admin
dockerfile: Dockerfile
container_name: lps-admin
ports:
- "${LPS_ADMIN_PORT:-30014}:80"
depends_on:
- lps-api
restart: unless-stopped
logging:
driver: json-file
options: { max-size: "10m", max-file: "5" }
# HEALTHCHECK 실패 컨테이너 자동 재시작 — autoheal 라벨 붙은 컨테이너(lps-api/lps-worker)를 감시해 재시작.
# docker.sock 마운트 = 도커 제어 권한이므로 신뢰 환경에서만 사용.
autoheal:
image: willfarrell/autoheal:latest
container_name: autoheal
environment:
AUTOHEAL_CONTAINER_LABEL: autoheal
volumes:
- /var/run/docker.sock:/var/run/docker.sock
restart: unless-stopped
logging:
driver: json-file
options: { max-size: "10m", max-file: "5" }
volumes:
lps-profiles: