Files
web-page-backend/docker-compose.yml
gahusb 0906c3ba35 chore(infra): packs-lab 서비스 통합 (compose 18950 + nginx 5GB streaming + env 7개)
- docker-compose.yml: 포트 18910→18950 수정, env 형식을 list 스타일로 통일,
  TZ/UPLOAD_TOKEN_TTL_SEC 추가, volume 경로를 /app/data/packs으로 정정
- .env.example: packs-lab 섹션 신규 추가 (DSM_HOST/DSM_USER/DSM_PASS/
  BACKEND_HMAC_SECRET/SUPABASE_URL/SUPABASE_SERVICE_KEY/UPLOAD_TOKEN_TTL_SEC/PACK_DATA_PATH)
- nginx/default.conf: 이전 커밋(9a0bbec)에 이미 포함 — 변경 없음

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 01:37:29 +09:00

266 lines
8.7 KiB
YAML

name: webpage
services:
lotto:
build:
context: ./lotto
args:
APP_VERSION: ${APP_VERSION:-dev}
container_name: lotto
restart: unless-stopped
ports:
- "18000:8000"
environment:
- TZ=${TZ:-Asia/Seoul}
- LOTTO_ALL_URL=${LOTTO_ALL_URL:-https://smok95.github.io/lotto/results/all.json}
- LOTTO_LATEST_URL=${LOTTO_LATEST_URL:-https://smok95.github.io/lotto/results/latest.json}
volumes:
- ${RUNTIME_PATH}/data:/app/data
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
interval: 30s
timeout: 5s
retries: 3
stock-lab:
build:
context: ./stock-lab
args:
APP_VERSION: ${APP_VERSION:-dev}
container_name: stock-lab
restart: unless-stopped
ports:
- "18500:8000"
environment:
- TZ=${TZ:-Asia/Seoul}
- WINDOWS_AI_SERVER_URL=${WINDOWS_AI_SERVER_URL:-http://192.168.0.5:8000}
- GEMINI_API_KEY=${GEMINI_API_KEY:-}
- GEMINI_MODEL=${GEMINI_MODEL:-gemini-1.5-flash}
- ADMIN_API_KEY=${ADMIN_API_KEY:-}
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}
- ANTHROPIC_MODEL=${ANTHROPIC_MODEL:-claude-haiku-4-5-20251001}
- LLM_PROVIDER=${LLM_PROVIDER:-claude}
- OLLAMA_URL=${OLLAMA_URL:-http://192.168.45.59:11435}
- OLLAMA_MODEL=${OLLAMA_MODEL:-qwen3:14b}
- CORS_ALLOW_ORIGINS=${CORS_ALLOW_ORIGINS:-http://localhost:3007,http://localhost:8080}
volumes:
- ${RUNTIME_PATH}/data/stock:/app/data
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
interval: 30s
timeout: 5s
retries: 3
music-lab:
build:
context: ./music-lab
container_name: music-lab
restart: unless-stopped
ports:
- "18600:8000"
environment:
- TZ=${TZ:-Asia/Seoul}
- MUSIC_AI_SERVER_URL=${MUSIC_AI_SERVER_URL:-}
- SUNO_API_KEY=${SUNO_API_KEY:-}
- MUSIC_MEDIA_BASE=${MUSIC_MEDIA_BASE:-/media/music}
- CORS_ALLOW_ORIGINS=${CORS_ALLOW_ORIGINS:-http://localhost:3007,http://localhost:8080}
- PEXELS_API_KEY=${PEXELS_API_KEY:-}
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}
- VIDEO_DATA_DIR=${VIDEO_DATA_DIR:-/app/data/videos}
volumes:
- ${RUNTIME_PATH}/data/music:/app/data
- ${RUNTIME_PATH:-.}/data/videos:/app/data/videos
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
interval: 30s
timeout: 5s
retries: 3
blog-lab:
build:
context: ./blog-lab
container_name: blog-lab
restart: unless-stopped
ports:
- "18700:8000"
environment:
- TZ=${TZ:-Asia/Seoul}
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}
- NAVER_CLIENT_ID=${NAVER_CLIENT_ID:-}
- NAVER_CLIENT_SECRET=${NAVER_CLIENT_SECRET:-}
- CORS_ALLOW_ORIGINS=${CORS_ALLOW_ORIGINS:-http://localhost:3007,http://localhost:8080}
volumes:
- ${RUNTIME_PATH}/data/blog:/app/data
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
interval: 30s
timeout: 5s
retries: 3
realestate-lab:
build:
context: ./realestate-lab
container_name: realestate-lab
restart: unless-stopped
ports:
- "18800:8000"
environment:
- TZ=${TZ:-Asia/Seoul}
- DATA_GO_KR_API_KEY=${DATA_GO_KR_API_KEY:-}
- CORS_ALLOW_ORIGINS=${CORS_ALLOW_ORIGINS:-http://localhost:3007,http://localhost:8080}
- AGENT_OFFICE_URL=${AGENT_OFFICE_URL:-http://agent-office:8000}
volumes:
- ${RUNTIME_PATH}/data/realestate:/app/data
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
interval: 30s
timeout: 5s
retries: 3
agent-office:
build:
context: ./agent-office
container_name: agent-office
restart: unless-stopped
ports:
- "18900:8000"
environment:
- TZ=${TZ:-Asia/Seoul}
- CORS_ALLOW_ORIGINS=${CORS_ALLOW_ORIGINS:-http://localhost:3007,http://localhost:8080}
- STOCK_LAB_URL=http://stock-lab:8000
- MUSIC_LAB_URL=http://music-lab:8000
- BLOG_LAB_URL=http://blog-lab:8000
- REALESTATE_LAB_URL=http://realestate-lab:8000
- REALESTATE_DASHBOARD_URL=${REALESTATE_DASHBOARD_URL:-http://localhost:8080/realestate}
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN:-}
- TELEGRAM_CHAT_ID=${TELEGRAM_CHAT_ID:-}
- TELEGRAM_WEBHOOK_URL=${TELEGRAM_WEBHOOK_URL:-}
- TELEGRAM_WIFE_CHAT_ID=${TELEGRAM_WIFE_CHAT_ID:-}
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}
- LOTTO_BACKEND_URL=${LOTTO_BACKEND_URL:-http://lotto:8000}
- LOTTO_CURATOR_MODEL=${LOTTO_CURATOR_MODEL:-claude-sonnet-4-5}
- CONVERSATION_MODEL=${CONVERSATION_MODEL:-claude-haiku-4-5-20251001}
- CONVERSATION_HISTORY_LIMIT=${CONVERSATION_HISTORY_LIMIT:-20}
- CONVERSATION_RATE_PER_MIN=${CONVERSATION_RATE_PER_MIN:-6}
- YOUTUBE_DATA_API_KEY=${YOUTUBE_DATA_API_KEY:-}
volumes:
- ${RUNTIME_PATH:-.}/data/agent-office:/app/data
depends_on:
- stock-lab
- music-lab
- blog-lab
- realestate-lab
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
interval: 30s
timeout: 5s
retries: 3
personal:
build:
context: ./personal
container_name: personal
restart: unless-stopped
ports:
- "18850:8000"
environment:
- TZ=${TZ:-Asia/Seoul}
- PORTFOLIO_EDIT_PASSWORD=${PORTFOLIO_EDIT_PASSWORD:-}
- CORS_ALLOW_ORIGINS=${CORS_ALLOW_ORIGINS:-http://localhost:3007,http://localhost:8080}
volumes:
- ${RUNTIME_PATH:-.}/data/personal:/app/data
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
interval: 30s
timeout: 5s
retries: 3
packs-lab:
build:
context: ./packs-lab
container_name: packs-lab
restart: unless-stopped
ports:
- "18950:8000"
environment:
- TZ=${TZ:-Asia/Seoul}
- DSM_HOST=${DSM_HOST:-}
- DSM_USER=${DSM_USER:-}
- DSM_PASS=${DSM_PASS:-}
- BACKEND_HMAC_SECRET=${BACKEND_HMAC_SECRET:-}
- SUPABASE_URL=${SUPABASE_URL:-}
- SUPABASE_SERVICE_KEY=${SUPABASE_SERVICE_KEY:-}
- UPLOAD_TOKEN_TTL_SEC=${UPLOAD_TOKEN_TTL_SEC:-1800}
volumes:
- ${PACK_DATA_PATH:-./data/packs}:/app/data/packs
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
interval: 30s
timeout: 5s
retries: 3
travel-proxy:
build: ./travel-proxy
container_name: travel-proxy
restart: unless-stopped
user: "${PUID}:${PGID}"
ports:
- "19000:8000"
environment:
- TZ=${TZ:-Asia/Seoul}
- TRAVEL_ROOT=${TRAVEL_ROOT:-/data/travel}
- TRAVEL_THUMB_ROOT=${TRAVEL_THUMB_ROOT:-/data/thumbs}
- TRAVEL_MEDIA_BASE=${TRAVEL_MEDIA_BASE:-/media/travel}
- TRAVEL_DB_PATH=${TRAVEL_DB_PATH:-/data/thumbs/travel.db}
- CORS_ALLOW_ORIGINS=${CORS_ALLOW_ORIGINS:-http://localhost:3007,http://localhost:8080}
volumes:
- ${PHOTO_PATH}:/data/travel:ro
- ${RUNTIME_PATH}/travel-thumbs:/data/thumbs:rw
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
interval: 30s
timeout: 5s
retries: 3
frontend:
image: nginx:alpine
container_name: frontend
restart: unless-stopped
depends_on:
- music-lab
- blog-lab
- realestate-lab
ports:
- "8080:80"
volumes:
- ${FRONTEND_PATH}:/usr/share/nginx/html:ro
- ${RUNTIME_PATH}/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
- ${PHOTO_PATH}:/data/travel:ro
- ${RUNTIME_PATH}/travel-thumbs:/data/thumbs:ro
- ${RUNTIME_PATH}/data/music:/data/music:ro
- ${RUNTIME_PATH}/data/videos:/data/videos:ro
extra_hosts:
- "host.docker.internal:host-gateway"
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:80/"]
interval: 30s
timeout: 5s
retries: 3
deployer:
build: ./deployer
container_name: webpage-deployer
restart: unless-stopped
ports:
- "127.0.0.1:19010:9000"
environment:
- TZ=${TZ:-Asia/Seoul}
- WEBHOOK_SECRET=${WEBHOOK_SECRET}
- PUID=${PUID:-1026}
- PGID=${PGID:-100}
volumes:
- ${REPO_PATH}:/repo:rw
- ${RUNTIME_PATH}:/runtime:rw
- ${RUNTIME_PATH}/scripts:/scripts:ro
- /var/run/docker.sock:/var/run/docker.sock