services: n8n: image: ${N8N_IMAGE:-docker.n8n.io/n8nio/n8n:latest} container_name: storyforge-n8n restart: unless-stopped environment: N8N_HOST: ${N8N_HOST:-0.0.0.0} N8N_PORT: 5678 N8N_PROTOCOL: ${N8N_PROTOCOL:-http} WEBHOOK_URL: ${WEBHOOK_URL:-http://127.0.0.1:5670/} STORYFORGE_INTERNAL_BASE_URL: ${STORYFORGE_INTERNAL_BASE_URL:-http://collector:8081} STORYFORGE_ORCHESTRATOR_SECRET: ${ORCHESTRATOR_SHARED_SECRET:-__set_a_strong_shared_secret__} GENERIC_TIMEZONE: ${GENERIC_TIMEZONE:-Asia/Shanghai} TZ: ${TZ:-Asia/Shanghai} N8N_SECURE_COOKIE: ${N8N_SECURE_COOKIE:-false} N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: ${N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS:-false} ports: - "5670:5678" volumes: - ./data/n8n:/home/node/.n8n - ./n8n:/workspace/n8n:ro collector: build: context: ./collector-service container_name: storyforge-collector restart: unless-stopped depends_on: - n8n environment: DATA_DIR: /data/collector DATABASE_PATH: /data/collector/storyforge.db DEFAULT_EXTERNAL_BASE_URL: ${DEFAULT_EXTERNAL_BASE_URL:-https://storyforge.hyzq.net} LOCAL_OPENAI_BASE_URL: ${LOCAL_OPENAI_BASE_URL:-http://host.docker.internal:8317/v1} LOCAL_OPENAI_MODEL: ${LOCAL_OPENAI_MODEL:-GLM-5} LOCAL_OPENAI_API_KEY: ${LOCAL_OPENAI_API_KEY:-} N8N_BASE_URL: ${COLLECTOR_N8N_BASE_URL:-http://n8n:5678} N8N_ANALYSIS_WEBHOOK_PATH: ${N8N_ANALYSIS_WEBHOOK_PATH:-/webhook/storyforge-analysis} N8N_REAL_CUT_WEBHOOK_PATH: ${N8N_REAL_CUT_WEBHOOK_PATH:-/webhook/storyforge-real-cut} N8N_AI_VIDEO_WEBHOOK_PATH: ${N8N_AI_VIDEO_WEBHOOK_PATH:-/webhook/storyforge-ai-video} N8N_CONTENT_SOURCE_SYNC_WEBHOOK_PATH: ${N8N_CONTENT_SOURCE_SYNC_WEBHOOK_PATH:-/webhook/storyforge-content-source-sync} BOOTSTRAP_SUPERADMIN_USERNAME: ${BOOTSTRAP_SUPERADMIN_USERNAME:-} BOOTSTRAP_SUPERADMIN_PASSWORD: ${BOOTSTRAP_SUPERADMIN_PASSWORD:-} BOOTSTRAP_SUPERADMIN_DISPLAY_NAME: ${BOOTSTRAP_SUPERADMIN_DISPLAY_NAME:-StoryForge Admin} ORCHESTRATOR_SHARED_SECRET: ${ORCHESTRATOR_SHARED_SECRET:-__set_a_strong_shared_secret__} CUTVIDEO_BASE_URL: ${CUTVIDEO_BASE_URL:-} CUTVIDEO_API_KEY: ${CUTVIDEO_API_KEY:-} CUTVIDEO_BASE_CONFIG: ${CUTVIDEO_BASE_CONFIG:-example.job.yaml} CUTVIDEO_POLL_INTERVAL_SEC: ${CUTVIDEO_POLL_INTERVAL_SEC:-10} CUTVIDEO_MAX_WAIT_SEC: ${CUTVIDEO_MAX_WAIT_SEC:-1800} CUTVIDEO_UPLOAD_TIMEOUT_SEC: ${CUTVIDEO_UPLOAD_TIMEOUT_SEC:-1800} HUOBAO_BASE_URL: ${HUOBAO_BASE_URL:-http://host.docker.internal:5678} YTDLP_BIN: ${YTDLP_BIN:-yt-dlp} FFMPEG_BIN: ${FFMPEG_BIN:-ffmpeg} WHISPER_BIN: ${WHISPER_BIN:-} WHISPER_MODEL: ${WHISPER_MODEL:-/data/collector/models/ggml-base.en.bin} ASR_HTTP_BASE_URL: ${ASR_HTTP_BASE_URL:-} ASR_HTTP_TRANSCRIBE_PATH: ${ASR_HTTP_TRANSCRIBE_PATH:-/transcribe} ASR_HTTP_FIELD_NAME: ${ASR_HTTP_FIELD_NAME:-wav} ASR_HTTP_TIMEOUT_SEC: ${ASR_HTTP_TIMEOUT_SEC:-120} HUOBAO_POLL_INTERVAL_SEC: ${HUOBAO_POLL_INTERVAL_SEC:-10} HUOBAO_MAX_WAIT_SEC: ${HUOBAO_MAX_WAIT_SEC:-900} ports: - "8081:8081" volumes: - ./data/collector:/data/collector command: uvicorn app.main:app --host 0.0.0.0 --port 8081 cli-proxy-api: image: ${CLIPROXY_IMAGE:-storyforge/cli-proxy-api:patched} container_name: storyforge-cliproxyapi restart: unless-stopped command: - ./CLIProxyAPI - -config - /CLIProxyAPI/config.yaml volumes: - ./data/cliproxyapi/config.yaml:/CLIProxyAPI/config.yaml:ro - ./data/cliproxyapi/auths:/root/.cli-proxy-api - ./data/cliproxyapi/logs:/CLIProxyAPI/logs ports: - "8317:8317" - "8085:8085"