feat: Unraid deploy, dealer-flow heatmap, confluence zones, 13F capture
Ship Node production images, Unraid compose, and Gitea CI/CD (test then push registry images; cron script if no runner). Rebuild dealer flow as a heatmap-first map with integrity gates and chart helpers. Add confluence zone rules, session clock, capture evidence, and tighter 13F/queue/options paths, plus the matching UI and tests.
This commit is contained in:
+48
-32
@@ -1,46 +1,62 @@
|
||||
# Investor Flow — Docker Compose Deployment (Slice 26)
|
||||
# Self-hostable stack: Bun backend + Next.js frontend + SQLite volume.
|
||||
# Investor Flow — production compose (local or Unraid).
|
||||
#
|
||||
# Usage:
|
||||
# 1. Copy .env.example to .env and fill in secrets
|
||||
# 2. docker compose up --build
|
||||
# 3. Frontend: http://localhost:3000
|
||||
# 4. Backend: http://localhost:3001
|
||||
# Unraid: copy deploy/unraid/.env.example to .env, set secrets, then:
|
||||
# docker compose --env-file .env up -d --build
|
||||
# Prefer a cache-only appdata path for SQLite (not /mnt/user FUSE). See docs/DEPLOY_UNRAID.md.
|
||||
|
||||
services:
|
||||
backend:
|
||||
image: ${IFLOW_IMAGE_BACKEND:-investor-flow-backend:local}
|
||||
build:
|
||||
context: ./app/server
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "3001:3001"
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- IFLOW_SESSION_SECRET=${IFLOW_SESSION_SECRET:-dev-secret-change-me}
|
||||
- SEC_OPERATOR_EMAIL=${SEC_OPERATOR_EMAIL}
|
||||
- X_COOKIE=${X_COOKIE}
|
||||
- REDDIT_CLIENT_ID=${REDDIT_CLIENT_ID}
|
||||
- REDDIT_CLIENT_SECRET=${REDDIT_CLIENT_SECRET}
|
||||
- REDDIT_USER_AGENT=${REDDIT_USER_AGENT}
|
||||
- LLM_PROVIDER_URL=${LLM_PROVIDER_URL:-http://localhost:1234/v1}
|
||||
- FRED_API_KEY=${FRED_API_KEY}
|
||||
volumes:
|
||||
- sqlite-data:/app/data
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${IFLOW_BACKEND_PORT:-3001}:3001"
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
HOST: 0.0.0.0
|
||||
PORT: 3001
|
||||
IFLOW_DB_PATH: /app/data/investor-flow.db
|
||||
IFLOW_SESSION_SECRET: ${IFLOW_SESSION_SECRET:?set IFLOW_SESSION_SECRET}
|
||||
IFLOW_CRYPTO_KEY: ${IFLOW_CRYPTO_KEY:-}
|
||||
SEC_OPERATOR_EMAIL: ${SEC_OPERATOR_EMAIL:-operator@example.com}
|
||||
YF_OPERATOR_EMAIL: ${YF_OPERATOR_EMAIL:-${SEC_OPERATOR_EMAIL:-operator@example.com}}
|
||||
FRED_API_KEY: ${FRED_API_KEY:-}
|
||||
LLM_PROVIDER_URL: ${LLM_PROVIDER_URL:-}
|
||||
ORNITH_LLM_URL: ${ORNITH_LLM_URL:-${LLM_PROVIDER_URL:-}}
|
||||
GITHUB_CLIENT_ID: ${GITHUB_CLIENT_ID:-}
|
||||
GITHUB_CLIENT_SECRET: ${GITHUB_CLIENT_SECRET:-}
|
||||
GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID:-}
|
||||
GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET:-}
|
||||
volumes:
|
||||
- ${IFLOW_DATA_DIR:-./app/server/data}:/app/data
|
||||
healthcheck:
|
||||
test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3001/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
|
||||
frontend:
|
||||
image: ${IFLOW_IMAGE_FRONTEND:-investor-flow-frontend:local}
|
||||
build:
|
||||
context: ./app
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- NEXT_PUBLIC_API_URL=http://backend:3001
|
||||
- NODE_ENV=production
|
||||
depends_on:
|
||||
- backend
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
sqlite-data:
|
||||
driver: local
|
||||
depends_on:
|
||||
backend:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- "${IFLOW_WEB_PORT:-3000}:3000"
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
HOSTNAME: 0.0.0.0
|
||||
PORT: 3000
|
||||
IFLOW_BACKEND_URL: http://backend:3001
|
||||
healthcheck:
|
||||
test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3000/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
|
||||
Reference in New Issue
Block a user