Ctrl K
ComunidadGuías…

docker-compose.yml

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# =============================================================================
# FlintTrade Docker Compose — Production Deployment
# =============================================================================
#
# Usage:
#   docker compose up -d                  # start the app services (default profile)
#   docker compose up -d --build          # rebuild and start the app services
#   docker compose --profile monitoring up -d   # app + observability stack
#   docker compose logs -f flinttrade     # follow FlintTrade logs
#   docker compose down                   # stop all services
#
# Profiles:
#   default      -> flinttrade (backend), terminal (one-shot UI build), nginx (UI origin)
#   monitoring   -> Uptime Kuma, GlitchTip (+ its Postgres/Redis), VictoriaLogs, Netdata.
#                   The GlitchTip services need real GLITCHTIP_SECRET_KEY /
#                   GLITCHTIP_DB_PASSWORD values in .env — the baked-in defaults are
#                   config-load placeholders only, never production credentials.
#
# Architecture:
#   Nginx -> React static files + reverse proxy to backend services. In Docker,
#     Nginx is the UI origin: http://localhost:8080 by default (override the host
#     ports with FLINTTRADE_HTTP_PORT / FLINTTRADE_HTTPS_PORT).
#   FlintTrade (5100) -> Platform backend (strategy engine, screener, AI). The
#     image does not contain the built terminal, so port 5100 is API-only in
#     Docker — the UI is served by Nginx from the terminal build volume.
#   Monitoring stack (profile: monitoring) -> Uptime Kuma, GlitchTip,
#     VictoriaLogs, Netdata
#
# All internal services bind to 127.0.0.1 only. Nginx is the sole entry point.
# A .env file is optional: the app services start without one.
#
# Multi-arch builds:
#   All base images (python:3.14-slim-trixie, node:22-alpine, nginx:alpine, etc.) support
#   linux/amd64 and linux/arm64. To build the FlintTrade image for multiple platforms:
#     docker buildx build --platform linux/amd64,linux/arm64 -t flinttrade:latest .
# =============================================================================

services:

  # ---------------------------------------------------------------------------
  flinttrade:
    build:
      context: .
      dockerfile: Dockerfile
    image: flinttrade:latest
    platform: linux/amd64
    container_name: flinttrade-backend
    volumes:
      - flinttrade_data:/data/flinttrade
      - ${FLINTTRADE_HOME:-~/.flinttrade}:/home/flinttrade/.flinttrade
      - flinttrade_strategies:/data/flinttrade/strategies
      - flinttrade_logs:/data/flinttrade/logs
    ports:
      - "127.0.0.1:5100:5100"
    # .env is gitignored and absent from a fresh clone; required: false keeps
    # `docker compose up` working without it (Compose v2.24+).
    env_file:
      - path: .env
        required: false
    environment:
      - FLINTTRADE_DEV=0
      - FLINTTRADE_BACKEND_PORT=5100
      - OPENBLAS_NUM_THREADS=2
      - OMP_NUM_THREADS=2
      - GUNICORN_WORKERS=1
      - GUNICORN_TIMEOUT=120
      - LOG_LEVEL=info
    restart: unless-stopped
    read_only: true
    tmpfs:
      - /tmp:size=100M
    security_opt:
      - "no-new-privileges:true"
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://localhost:5100/api/v1/ping"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 15s
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "5"
    networks:
      - flinttrade

  # ---------------------------------------------------------------------------
  # Terminal — Build React static files (builder only, no runtime container)
  # Nginx serves the built dist/ directory.
  #
  # This is a pnpm workspace (root pnpm-lock.yaml, no package-lock.json) and the
  # terminal imports @flinttrade/design-system via a file: path that lives
  # outside the terminal package, so the whole repo must be mounted and built
  # through the workspace. The commands mirror the node-core-tests job in
  # .github/workflows/test.yml: corepack enable, then a frozen-lockfile install,
  # then build the terminal package. Vite writes to the default dist/ inside the
  # terminal package, which is the path Nginx mounts via terminal_dist.
  # ---------------------------------------------------------------------------
  terminal:
    image: node:22-alpine
    platform: linux/amd64
    container_name: flinttrade-terminal-builder
    working_dir: /workspace
    volumes:
      - .:/workspace
      - terminal_dist:/workspace/packages/apps/terminal/dist
      - terminal_node_modules:/workspace/node_modules
    # Corepack is no longer distributed with Node.js from v25.0.0 onwards, so
    # 'corepack enable' cannot be relied on once this image moves off the 22
    # line. Fall through to a version-matched pnpm and finally to npx with the
    # pinned version - the same chain as infra/scripts/setup.sh.
    # '$$' escapes Compose's own interpolation so the shell receives '$PNPM'.
    command: >
      sh -c "if command -v corepack >/dev/null 2>&1; then corepack enable; fi;
             if command -v pnpm >/dev/null 2>&1; then PNPM='pnpm';
             else PNPM='npx --yes pnpm@10.34.5'; fi;
             $$PNPM install --frozen-lockfile &&
             $$PNPM --dir packages/apps/terminal run build"
    environment:
      - NODE_ENV=production
    restart: "no"
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
    networks:
      - flinttrade

  # ---------------------------------------------------------------------------
  # Nginx — Reverse proxy and static file server (sole public entry point)
  # ---------------------------------------------------------------------------
  nginx:
    image: nginx:1.30.5-alpine@sha256:0985e772fb9f729e6fa0980da05fca5d9c468e870eed43071545afa9d2e27d94
    platform: linux/amd64
    container_name: flinttrade-nginx
    # High-port defaults so a dev machine with a busy :80/:443 still comes up.
    # Production hosts that want the classic ports set FLINTTRADE_HTTP_PORT=80
    # and FLINTTRADE_HTTPS_PORT=443 in .env.
    ports:
      - "${FLINTTRADE_HTTP_PORT:-8080}:80"
      - "${FLINTTRADE_HTTPS_PORT:-8443}:443"
    volumes:
      - ./infra/nginx/flinttrade.conf:/etc/nginx/conf.d/default.conf:ro
      - terminal_dist:/var/www/flinttrade/dist:ro
      - nginx_logs:/var/log/nginx
      # Uncomment when SSL certificates are provisioned:
      # - /etc/letsencrypt:/etc/letsencrypt:ro
    depends_on:
      terminal:
        condition: service_completed_successfully
      flinttrade:
        condition: service_healthy
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "http://localhost:80/"]
      interval: 30s
      timeout: 5s
      retries: 3
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "5"
    networks:
      - flinttrade

  # ---------------------------------------------------------------------------
  # Uptime Kuma — Uptime monitoring dashboard
  # Internal only (proxied via Nginx at /monitoring/)
  # ---------------------------------------------------------------------------
  uptime-kuma:
    image: louislam/uptime-kuma:2.5.6@sha256:9912da7d7d9b6ddc0c2d904beb84d24689c1ed9c33b81419eb9008663a92a329
    platform: linux/amd64
    container_name: flinttrade-uptime-kuma
    profiles: ["monitoring"]
    ports:
      - "127.0.0.1:3001:3001"
    volumes:
      - uptime_kuma_data:/app/data
    restart: unless-stopped
    logging:
      driver: json-file
      options:
        max-size: "20m"
        max-file: "3"
    networks:
      - flinttrade

  # ---------------------------------------------------------------------------
  # Glitchtip — Error tracking (Sentry-compatible, MIT licence)
  # Internal only (proxied via Nginx at /errors/)
  # Requires PostgreSQL for storage + Celery worker for async processing
  # ---------------------------------------------------------------------------
  glitchtip-redis:
    image: redis:8.10.2-alpine@sha256:3811787313eba226a2ef38658c6ccb91cd5e110edc89c37767de373120a0e5a0
    platform: linux/amd64
    container_name: flinttrade-glitchtip-redis
    profiles: ["monitoring"]
    restart: unless-stopped
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
    networks:
      - flinttrade

  glitchtip:
    image: glitchtip/glitchtip:6.2.6@sha256:a3d8eb1b36c1e1603d55ab32711ea3dd8115874742a781a57391a62a16e0dff6
    platform: linux/amd64
    container_name: flinttrade-glitchtip
    profiles: ["monitoring"]
    ports:
      - "127.0.0.1:8000:8000"
    depends_on:
      glitchtip-db:
        condition: service_healthy
    # `:-` (not `:?`) — a `:?` here aborts config load for the WHOLE compose
    # file, so even `docker compose up flinttrade` failed on an optional
    # sidecar. The dev-only defaults exist purely so config loads without a
    # .env; set real values before running the monitoring profile.
    environment:
      DATABASE_URL: "postgres://glitchtip:${GLITCHTIP_DB_PASSWORD:-flinttrade-dev-only-change-me}@glitchtip-db:5432/glitchtip"
      SECRET_KEY: "${GLITCHTIP_SECRET_KEY:-flinttrade-dev-only-change-me}"
      CELERY_BROKER_URL: "redis://glitchtip-redis:6379/0"
      PORT: "8000"
      GLITCHTIP_DOMAIN: "http://127.0.0.1:8000"
    restart: unless-stopped
    logging:
      driver: json-file
      options:
        max-size: "20m"
        max-file: "3"
    networks:
      - flinttrade

  glitchtip-worker:
    image: glitchtip/glitchtip:6.2.6@sha256:a3d8eb1b36c1e1603d55ab32711ea3dd8115874742a781a57391a62a16e0dff6
    platform: linux/amd64
    container_name: flinttrade-glitchtip-worker
    profiles: ["monitoring"]
    command: bin/run-celery-with-beat.sh
    depends_on:
      glitchtip-db:
        condition: service_healthy
      glitchtip-redis:
        condition: service_started
    environment:
      DATABASE_URL: "postgres://glitchtip:${GLITCHTIP_DB_PASSWORD:-flinttrade-dev-only-change-me}@glitchtip-db:5432/glitchtip"
      SECRET_KEY: "${GLITCHTIP_SECRET_KEY:-flinttrade-dev-only-change-me}"
      CELERY_BROKER_URL: "redis://glitchtip-redis:6379/0"
    restart: unless-stopped
    logging:
      driver: json-file
      options:
        max-size: "20m"
        max-file: "3"
    networks:
      - flinttrade

  glitchtip-db:
    image: postgres:16.15-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea
    platform: linux/amd64
    container_name: flinttrade-glitchtip-db
    profiles: ["monitoring"]
    volumes:
      - glitchtip_pg:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: glitchtip
      POSTGRES_PASSWORD: "${GLITCHTIP_DB_PASSWORD:-flinttrade-dev-only-change-me}"
      POSTGRES_DB: glitchtip
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U glitchtip"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
    networks:
      - flinttrade

  # ---------------------------------------------------------------------------
  # VictoriaLogs — Log aggregation and search
  # Internal only (proxied via Nginx at /logs/)
  # ---------------------------------------------------------------------------
  victorialogs:
    image: victoriametrics/victoria-logs:v1.53.0@sha256:251121fa882af99b95ba0c230a4a2f412ea602d2698c64a96c58dc9842bb755d
    platform: linux/amd64
    container_name: flinttrade-victorialogs
    profiles: ["monitoring"]
    ports:
      - "127.0.0.1:9090:9090"
    volumes:
      - victorialogs_data:/victoria-logs-data
    command:
      - "-storageDataPath=/victoria-logs-data"
      - "-httpListenAddr=:9090"
    restart: unless-stopped
    logging:
      driver: json-file
      options:
        max-size: "20m"
        max-file: "3"
    networks:
      - flinttrade

  # ---------------------------------------------------------------------------
  # Netdata — Real-time system performance monitoring
  # Internal only (proxied via Nginx at /metrics/)
  # ---------------------------------------------------------------------------
  netdata:
    image: netdata/netdata:v2.12.1@sha256:5cfa05a5fa5686b98e0c70e884f00685fb3c662e9c5d727cf46c96d8e37b7818
    platform: linux/amd64
    container_name: flinttrade-netdata
    profiles: ["monitoring"]
    ports:
      - "127.0.0.1:19999:19999"
    volumes:
      - netdata_config:/etc/netdata
      - netdata_lib:/var/lib/netdata
      - netdata_cache:/var/cache/netdata
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /etc/os-release:/host/etc/os-release:ro
    cap_add:
      - SYS_PTRACE
    security_opt:
      - apparmor:unconfined
    restart: unless-stopped
    logging:
      driver: json-file
      options:
        max-size: "20m"
        max-file: "3"
    networks:
      - flinttrade

# =============================================================================
# Named volumes — persistent data across container restarts
# =============================================================================
volumes:
  # Core application
  flinttrade_data:
    name: flinttrade_platform_data
  flinttrade_strategies:
    name: flinttrade_strategies
  flinttrade_logs:
    name: flinttrade_logs

  # Terminal build
  terminal_dist:
    name: flinttrade_terminal_dist
  terminal_node_modules:
    name: flinttrade_terminal_node_modules

  # Nginx
  nginx_logs:
    name: flinttrade_nginx_logs

  # Monitoring
  uptime_kuma_data:
    name: flinttrade_uptime_kuma_data
  glitchtip_pg:
    name: flinttrade_glitchtip_pg
  victorialogs_data:
    name: flinttrade_victorialogs_data
  netdata_config:
    name: flinttrade_netdata_config
  netdata_lib:
    name: flinttrade_netdata_lib
  netdata_cache:
    name: flinttrade_netdata_cache

# =============================================================================
# Internal network — all services communicate over this bridge
# =============================================================================
networks:
  flinttrade:
    name: flinttrade
    driver: bridge