293 lines
10 KiB
YAML
293 lines
10 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:
|
|
build:
|
|
context: ./stock
|
|
args:
|
|
APP_VERSION: ${APP_VERSION:-dev}
|
|
container_name: stock
|
|
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}
|
|
- WEBAI_API_KEY=${WEBAI_API_KEY:-}
|
|
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:-}
|
|
- OPENAI_API_KEY=${OPENAI_API_KEY:-}
|
|
- YOUTUBE_OAUTH_CLIENT_ID=${YOUTUBE_OAUTH_CLIENT_ID:-}
|
|
- YOUTUBE_OAUTH_CLIENT_SECRET=${YOUTUBE_OAUTH_CLIENT_SECRET:-}
|
|
- YOUTUBE_OAUTH_REDIRECT_URI=${YOUTUBE_OAUTH_REDIRECT_URI:-}
|
|
- CLAUDE_HAIKU_MODEL=${CLAUDE_HAIKU_MODEL:-claude-haiku-4-5-20251001}
|
|
- CLAUDE_SONNET_MODEL=${CLAUDE_SONNET_MODEL:-claude-sonnet-4-6}
|
|
- VIDEO_DATA_DIR=${VIDEO_DATA_DIR:-/app/data/videos}
|
|
- WINDOWS_VIDEO_ENCODER_URL=${WINDOWS_VIDEO_ENCODER_URL:-}
|
|
- NAS_VIDEOS_ROOT=${NAS_VIDEOS_ROOT:-/volume1/docker/webpage/data/videos}
|
|
- NAS_MUSIC_ROOT=${NAS_MUSIC_ROOT:-/volume1/docker/webpage/data/music}
|
|
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
|
|
|
|
insta-lab:
|
|
build:
|
|
context: ./insta-lab
|
|
container_name: insta-lab
|
|
restart: unless-stopped
|
|
ports:
|
|
- "18700:8000"
|
|
environment:
|
|
- TZ=${TZ:-Asia/Seoul}
|
|
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}
|
|
- ANTHROPIC_MODEL_HAIKU=${ANTHROPIC_MODEL_HAIKU:-claude-haiku-4-5-20251001}
|
|
- ANTHROPIC_MODEL_SONNET=${ANTHROPIC_MODEL_SONNET:-claude-sonnet-4-6}
|
|
- NAVER_CLIENT_ID=${NAVER_CLIENT_ID:-}
|
|
- NAVER_CLIENT_SECRET=${NAVER_CLIENT_SECRET:-}
|
|
- YOUTUBE_DATA_API_KEY=${YOUTUBE_DATA_API_KEY:-}
|
|
- INSTA_DATA_PATH=/app/data
|
|
- CARD_TEMPLATE_DIR=/app/app/templates
|
|
- INSTA_DEFAULT_THEME=${INSTA_DEFAULT_THEME:-default}
|
|
- CORS_ALLOW_ORIGINS=${CORS_ALLOW_ORIGINS:-http://localhost:3007,http://localhost:8080}
|
|
volumes:
|
|
- ${RUNTIME_PATH}/data/insta:/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_URL=http://stock:8000
|
|
- MUSIC_LAB_URL=http://music-lab:8000
|
|
- INSTA_LAB_URL=http://insta-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:-}
|
|
- CLAUDE_HAIKU_MODEL=${CLAUDE_HAIKU_MODEL:-claude-haiku-4-5-20251001}
|
|
- CLAUDE_SONNET_MODEL=${CLAUDE_SONNET_MODEL:-claude-sonnet-4-6}
|
|
- 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
|
|
- music-lab
|
|
- insta-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:-}
|
|
- DSM_VERIFY_SSL=${DSM_VERIFY_SSL:-true}
|
|
- 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}
|
|
- PACK_BASE_DIR=${PACK_BASE_DIR:-/app/data/packs}
|
|
- PACK_HOST_DIR=${PACK_HOST_DIR:-${PACK_DATA_PATH:-./data/packs}}
|
|
volumes:
|
|
- ${PACK_DATA_PATH:-./data/packs}:${PACK_BASE_DIR:-/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:
|
|
- lotto
|
|
- stock
|
|
- music-lab
|
|
- insta-lab
|
|
- realestate-lab
|
|
- agent-office
|
|
- personal
|
|
- packs-lab
|
|
- travel-proxy
|
|
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
|