Ctrl K
ComunidadGuías…

docker-compose.yml

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Lively 배포 스택.
#
# 기본 토폴로지 = Option 2 (배포 설계 결정):
#   · store(pgvector) = 도커(이 compose)
#   · gateway(게이트웨이 = 컨트롤플레인 + 중앙박스 러너) = 호스트 네이티브(systemd/launchd, deploy/ 참조)
#   네이티브 게이트웨이가 호스트 docker 를 그대로 쓰므로 중앙박스(웹터미널) 세션의 DinD 함정을 피한다.
#   (근거: knowledge_get central-box-design)
#
# 사용:
#   docker compose up -d                        # items-db(pgvector) 만 = Option 2 의 도커 파트
#   docker compose --profile embeddings up -d   # + Ollama 임베딩 사이드카(#172, 4GB 박스엔 비권장 — t4g.large+)
#   docker compose --profile gateway up -d      # + 게이트웨이까지 컨테이너로(full-docker / Option 1 미리보기)
#
# 시크릿은 .env(PGPASSWORD 등)에서 읽는다. deploy/install.sh 가 .env 를 생성한다(deploy/lib/common.sh).

# ⚠ compose 프로젝트명은 레포명과 별개로 고정한다 — 바꾸면 named volume 이름(items-db-data)이 달라져
#   기존 박스의 DB 가 빈 볼륨으로 새로 생성된다(데이터 유실). 레포명이 lively 로 바뀐 뒤에도 이 값은 유지.
name: context-ontology

# ⚠ 컨테이너 로그 상한(#813) — 도커 기본 json-file 드라이버는 **상한이 없다**(무제한 증가).
#  박스 수명은 수년이고 고객 박스는 우리가 들여다보지 못하므로, 방치하면 로그만으로 디스크가 찬다
#  (디스크가 차면 Postgres 가 죽어 전 기능이 500 — 2026-07-13 사고). 모든 서비스에 앵커로 상속시킨다.
#  게이트웨이 자신의 로그(logs/gateway.log)는 in-process 재니터가 관리한다(관리탭 '저장소·로그').
x-logging: &default-logging
  driver: json-file
  options:
    max-size: ${DOCKER_LOG_MAX_SIZE:-10m}
    max-file: "${DOCKER_LOG_MAX_FILE:-3}"

services:
  # ── store: 조직 지식(knowledge)·v6·도메인맵·임베딩이 사는 쓰기 DB. ──
  #  ⚠ 불변식: 이미지는 반드시 pgvector/pgvector — plain postgres 로 재생성 금지(#172 벡터검색).
  #     (knowledge_get items-db-pgvector-image-invariant)
  items-db:
    image: pgvector/pgvector:pg18
    environment:
      POSTGRES_USER: ${PGUSER:-lively}
      POSTGRES_PASSWORD: ${PGPASSWORD:?PGPASSWORD 를 .env 에 설정하세요 (deploy/install.sh 가 생성)}
      POSTGRES_DB: ${PGDATABASE:-items}
    ports:
      # ⚠ 127.0.0.1 바인딩 — DB 를 외부에 노출하지 않는다(네이티브 게이트웨이가 localhost 로 접근).
      - "127.0.0.1:${ITEMS_DB_PORT:-5432}:5432"
    volumes:
      # ⚠ pg18+ 이미지는 단일 마운트 /var/lib/postgresql (데이터는 그 아래 버전 서브디렉). /data 마운트는 거부됨.
      - items-db-data:/var/lib/postgresql
      - ./deploy/initdb:/docker-entrypoint-initdb.d:ro   # 최초 init 1회: domainmap DB 생성
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${PGUSER:-lively} -d ${PGDATABASE:-items}"]
      interval: 5s
      timeout: 5s
      retries: 30
    logging: *default-logging
    restart: unless-stopped

  # ── 임베딩 사이드카(선택, profile=embeddings) — OpenAI-compatible /v1/embeddings(Ollama, CPU). ──
  #  스왑: 다른 모델=EMBEDDINGS_MODEL + ollama pull; 다른 런타임/외부 API=EMBEDDINGS_BASE_URL 교체.
  #  ⚠ 판을 고정한다 — latest 면 박스마다 설치 시점의 판이 깔린다. 올릴 땐 아래 두 줄을 같은 판으로(deploy/enable-embeddings.test.mjs).
  embeddings:
    image: ollama/ollama:0.40.13
    profiles: ["embeddings"]
    ports:
      - "127.0.0.1:${EMBEDDINGS_PORT:-11434}:11434"   # 네이티브 게이트웨이가 localhost 로 접근
    volumes:
      - ollama-models:/root/.ollama
    logging: *default-logging
    restart: unless-stopped

  embeddings-init:   # 최초 1회 모델 pull(멱등). store 의 임베딩 호출 전에 모델 준비.
    image: ollama/ollama:0.40.13
    profiles: ["embeddings"]
    depends_on: [embeddings]
    environment:
      OLLAMA_HOST: embeddings:11434
    entrypoint: ["/bin/sh","-c","until ollama list >/dev/null 2>&1; do sleep 1; done; ollama pull ${EMBEDDINGS_MODEL:-bge-m3}"]
    logging: *default-logging
    restart: "no"

  # ── gateway(선택, profile=gateway) — full-docker(Option 1) 미리보기. 파일럿(Option 2)은 미사용. ──
  #  ⚠ 컨테이너 안에서 중앙박스 세션을 띄우면 DinD 함정. 중앙박스(웹터미널)를 쓸 거면 네이티브로(deploy/).
  gateway:
    build: .
    profiles: ["gateway"]
    env_file: [.env]
    environment:
      # 컨테이너 네트워크 안에서는 호스트가 'items-db'. (네이티브 경로의 localhost 와 분리)
      ITEMS_DATABASE_URL: postgres://${PGUSER:-lively}:${PGPASSWORD}@items-db:5432/${PGDATABASE:-items}
      EMBEDDINGS_BASE_URL: ${EMBEDDINGS_BASE_URL_COMPOSE:-http://embeddings:11434}
      LANG: C.UTF-8
      LC_ALL: C.UTF-8
    depends_on:
      items-db:
        condition: service_healthy
    ports:
      - "${PORT:-8080}:8080"
    logging: *default-logging
    restart: unless-stopped

  # ── caddy(선택, profile=proxy) — 자동 HTTPS 리버스 프록시(Let's Encrypt). TLS 종단 → localhost:8080. ──
  #  network_mode: host → 호스트 80/443 바인딩 + 네이티브 게이트웨이(localhost:8080)로 프록시. WS Upgrade 자동 통과.
  #  도메인 필요(LIVELY_DOMAIN — A레코드가 이 호스트를 향해야 인증서 발급). 인증서는 caddy-data 볼륨에 영속.
  caddy:
    image: caddy:2
    profiles: ["proxy"]
    network_mode: host
    logging: *default-logging
    restart: unless-stopped
    environment:
      # 기본 빈 값(:-) — 프로필 미지정(items-db/gateway) up 시에도 파싱되게. compose 는 프로필 필터 전에
      # 파일 전체를 interpolate 하므로 :? 면 TLS 안 쓰는 설치도 막힌다. 도메인 검증은 proxy_up(common.sh).
      LIVELY_DOMAIN: ${LIVELY_DOMAIN:-}
      LIVELY_UPSTREAM: ${LIVELY_UPSTREAM:-localhost:8080}
    volumes:
      - ./deploy/Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy-data:/data
      - caddy-config:/config

volumes:
  items-db-data:   # ⚠ 조직 지식 전체. 백업 대상(pg_dump / 볼륨 스냅샷). -v 로 날리지 말 것.
  ollama-models:
  caddy-data:      # ⚠ TLS 인증서·ACME 계정. 삭제 시 재발급(LE rate-limit 주의).
  caddy-config: