docker-compose.dev-core.yml
Rama main · réplica de lectura del repositorio original.
# ══════════════════════════════════════════════════════════════════════
# Geny — Docker Compose (Development / Core — 경량 버전)
#
# TTS 로컬 엔진 없이 핵심 서비스만 실행합니다.
# 소스 코드가 바인드 마운트되어 로컬 편집이 컨테이너에 즉시 반영됩니다.
#
# - Backend : uvicorn --reload (watchfiles 기반 hot reload)
# - Frontend: next dev (HMR / Fast Refresh)
#
# Usage:
# docker compose -f docker-compose.dev-core.yml up --build
# docker compose -f docker-compose.dev-core.yml up -d
# docker compose -f docker-compose.dev-core.yml down
# docker compose -f docker-compose.dev-core.yml logs -f
#
# 전체 버전 (TTS 포함):
# docker compose -f docker-compose.dev.yml up --build
# ══════════════════════════════════════════════════════════════════════
services:
# ── PostgreSQL Database ───────────────────────────────────────────
postgres:
image: postgres:16-alpine
container_name: geny-postgres-dev
restart: unless-stopped
ports:
- "${POSTGRES_PORT:-5432}:5432"
environment:
POSTGRES_DB: ${POSTGRES_DB:-geny}
POSTGRES_USER: ${POSTGRES_USER:-geny}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-geny123}
POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
TZ: ${TIMEZONE:-Asia/Seoul}
volumes:
- geny-pgdata-dev:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-geny} -d ${POSTGRES_DB:-geny}"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
networks:
- geny-net-dev
# ── Backend (FastAPI + LangGraph + Claude CLI) — Dev Mode ─────────
backend:
build:
context: ./backend
dockerfile: Dockerfile
container_name: geny-backend-dev
restart: unless-stopped
ports:
- "${BACKEND_PORT:-8000}:8000"
env_file:
- path: ./backend/.env
required: false
environment:
- APP_HOST=0.0.0.0
- APP_PORT=8000
- DEBUG_MODE=true
- GENY_AGENT_STORAGE_ROOT=/data/geny_agent_sessions
# PostgreSQL
- POSTGRES_HOST=postgres
- POSTGRES_PORT=5432
- POSTGRES_DB=${POSTGRES_DB:-geny}
- POSTGRES_USER=${POSTGRES_USER:-geny}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-geny123}
- AUTO_MIGRATION=true
- TIMEZONE=${TIMEZONE:-Asia/Seoul}
# ── Persistent-storage paths (Phase 1, 2026-05-19) ─────────────
# Mirrors docker-compose.dev.yml — see that file for full
# rationale. Each path is backed by a named volume below.
- ENVIRONMENT_STORAGE_PATH=${ENVIRONMENT_STORAGE_PATH:-/data/environments}
- TRIGGER_PRESET_STORAGE_PATH=${TRIGGER_PRESET_STORAGE_PATH:-/data/trigger_presets}
- GENY_TOOL_PRESETS_DIR=/data/tool_presets
- GENY_CHAT_CONVERSATIONS_DIR=/data/chat_conversations
- GENY_GAME_STATE_DB=/data/creature_state/geny_state.sqlite3
- GENY_CONFIG_VARIABLES_DIR=/data/config_variables
- GENY_MCP_CREDENTIALS=/data/mcp/credentials.json
volumes:
# ── Bind mount: 로컬 소스 ↔ 컨테이너 동기화 ──────────────────
- ./backend:/app
# ── Backend storage root (notes / vault / capture logs) ────────
- geny-agent-sessions-dev:/data/geny_agent_sessions
# ── Phase-1 persistence volumes (2026-05-19) ───────────────────
- geny-environments-dev:/data/environments
- geny-trigger-presets-dev:/data/trigger_presets
- geny-tool-presets-dev:/data/tool_presets
- geny-chat-conversations-dev:/data/chat_conversations
- geny-creature-state-dev:/data/creature_state
- geny-config-variables-dev:/data/config_variables
- geny-mcp-credentials-dev:/data/mcp
# Baked puppet zips dropped here by avatar-editor. Backend reads + moves to
# installed/ subdir after install (rw — was :ro before C.3 added install).
- geny-baked-exports-dev:/data/baked-imports
# Phase G — host's ``~/.claude`` for Pro/Max OAuth credential
# passthrough to the in-container ``claude`` CLI. RW for token
# refresh.
- ${CLAUDE_HOST_DIR:-geny-claude-creds-dev}:/root/.claude:rw
depends_on:
postgres:
condition: service_healthy
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
interval: 15s
timeout: 10s
retries: 5
start_period: 30s
networks:
- geny-net-dev
# ── Frontend (Next.js) — Dev Mode ─────────────────────────────────
frontend:
build:
# Root context: the page renders shared/chat, which lives beside
# frontend/ and must be in the image.
context: .
dockerfile: frontend/Dockerfile.dev
container_name: geny-frontend-dev
restart: unless-stopped
ports:
- "${FRONTEND_PORT:-3000}:3000"
environment:
- API_URL=http://backend:8000
- NEXT_PUBLIC_BACKEND_PORT=${BACKEND_PORT:-8000}
- PORT=3000
- HOSTNAME=0.0.0.0
- WATCHPACK_POLLING=true
- CHOKIDAR_USEPOLLING=true
volumes:
# ── Bind mount: 로컬 소스 ↔ 컨테이너 동기화 ──────────────────
- ./frontend/src:/app/src
- ./frontend/public:/app/public
- ./frontend/next.config.ts:/app/next.config.ts
- ./frontend/tsconfig.json:/app/tsconfig.json
- ./frontend/postcss.config.mjs:/app/postcss.config.mjs
depends_on:
backend:
condition: service_healthy
networks:
- geny-net-dev
# ── Avatar Editor (geny-avatar submodule, Next.js) — Dev Core ─────
# Same standalone build as docker-compose.dev.yml. -core variants
# share the dev volume name so dev ↔ dev-core can swap freely
# without losing already-staged baked zips.
avatar-editor:
build:
context: ./vendor/geny-avatar
dockerfile: Dockerfile
args:
# NEXT_PUBLIC_* must be passed at build time — see docker-compose.yml
# comment for the full reasoning.
NEXT_PUBLIC_BASE_PATH: ""
NEXT_PUBLIC_GENY_HOST: "true"
container_name: geny-avatar-editor-dev
init: true
restart: unless-stopped
ports:
- "127.0.0.1:${AVATAR_EDITOR_PORT:-3001}:3000"
environment:
- NEXT_PUBLIC_BASE_PATH=
- NEXT_PUBLIC_GENY_HOST=true
- GENY_BAKED_EXPORTS_DIR=/exports
# AI provider keys for the editor's Generate panel.
- GEMINI_API_KEY=${GEMINI_API_KEY:-}
- OPENAI_API_KEY=${OPENAI_API_KEY:-}
- REPLICATE_API_TOKEN=${REPLICATE_API_TOKEN:-}
- PORT=3000
- HOSTNAME=0.0.0.0
- NODE_ENV=production
volumes:
- geny-baked-exports-dev:/exports
healthcheck:
test: ["CMD-SHELL", "wget -q --spider http://127.0.0.1:3000/ || exit 1"]
interval: 30s
timeout: 5s
retries: 3
start_period: 30s
networks:
- geny-net-dev
networks:
geny-net-dev:
driver: bridge
volumes:
geny-pgdata-dev:
driver: local
# Shared between avatar-editor (rw) and backend (ro) — dev variant.
geny-baked-exports-dev:
driver: local
# Phase G — Claude Code OAuth credentials. See backend.volumes.
geny-claude-creds-dev:
driver: local
# ── Backend storage root (notes / vault / capture logs) ────────────
# NOTE: dev-core shares the -dev suffix with docker-compose.dev.yml
# so the two compose files can swap freely without losing state.
geny-agent-sessions-dev:
driver: local
# ── Phase-1 persistent-storage volumes (2026-05-19) ─────────────────
geny-environments-dev:
driver: local
geny-trigger-presets-dev:
driver: local
geny-tool-presets-dev:
driver: local
geny-chat-conversations-dev:
driver: local
geny-creature-state-dev:
driver: local
geny-config-variables-dev:
driver: local
geny-mcp-credentials-dev:
driver: local