# syntax=docker/dockerfile:1 # --------------------------------------------------------------------------- # Dexter — unified finance app (Dexter / Hedge Fund / OpenBB boards). # One FastAPI server on :7860 serves the SPA and in-process reverse-proxies the # OpenBB and Dexter sidecars. No Caddy, no exposed terminal. # --------------------------------------------------------------------------- # ===== Stage 1: build the unified React SPA ===== FROM node:20-slim AS frontend WORKDIR /fe COPY ai-hedge-fund/app/frontend/package.json ai-hedge-fund/app/frontend/package-lock.json* ./ RUN npm ci || npm install COPY ai-hedge-fund/app/frontend/ ./ # Same-origin API base (served by the FastAPI backend under /api). RUN rm -f .env.local && printf 'VITE_API_URL=/api\n' > .env.production \ && (npm run build || npx vite build) # ===== Stage 2: runtime ===== FROM python:3.11-slim-bookworm AS runtime ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ curl ca-certificates git unzip xz-utils build-essential python3-dev \ supervisor libstdc++6 \ && rm -rf /var/lib/apt/lists/* # Bun (dexter runtime) COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun # Lightpanda (headless CDP browser backend for dexter's research tool) RUN curl -fsSL "https://github.com/lightpanda-io/browser/releases/download/nightly/lightpanda-x86_64-linux" \ -o /usr/local/bin/lightpanda && chmod +x /usr/local/bin/lightpanda # HF requires a non-root user with uid 1000 RUN useradd -m -u 1000 user ENV HOME=/home/user WORKDIR /app # ---- OpenBB Platform venv (build provider stubs once, at image-build time) ---- RUN python3 -m venv /opt/venv-openbb \ && /opt/venv-openbb/bin/pip install --no-cache-dir -U pip \ && /opt/venv-openbb/bin/pip install --no-cache-dir "openbb==4.7.2" "openbb-platform-api" \ && /opt/venv-openbb/bin/python -c "import openbb; print('openbb build ok')" # ---- ai-hedge-fund venv (deps first for caching) ---- COPY ai-hedge-fund/pyproject.toml ai-hedge-fund/poetry.lock* /app/ai-hedge-fund/ RUN python3 -m venv /opt/venv-hedge \ && /opt/venv-hedge/bin/pip install --no-cache-dir -U pip "poetry==1.8.5" \ && cd /app/ai-hedge-fund \ && /opt/venv-hedge/bin/poetry config virtualenvs.create false \ && VIRTUAL_ENV=/opt/venv-hedge /opt/venv-hedge/bin/poetry install \ --no-root --without dev --no-interaction --no-ansi COPY ai-hedge-fund/ /app/ai-hedge-fund/ # ---- dexter (bun); Chromium download skipped, Lightpanda used instead ---- COPY dexter/ /app/dexter/ ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 RUN cd /app/dexter && bun install # ---- built SPA ---- COPY --from=frontend /fe/dist /app/web # ---- infra ---- COPY supervisord.conf /etc/supervisord.conf COPY entrypoint.sh /usr/local/bin/entrypoint.sh COPY state-backup.sh /usr/local/bin/state-backup.sh RUN chmod +x /usr/local/bin/entrypoint.sh /usr/local/bin/state-backup.sh \ && mkdir -p /home/user/.openbb_platform /data /app/dexter/.dexter \ && chown -R user:user /home/user /data /app/dexter /app/ai-hedge-fund /app/web USER user ENV OPENBB_API_BASE_URL=http://127.0.0.1:6900 \ DEXTER_AGENT_URL=http://127.0.0.1:7778 \ DEXTER_SERVER_PORT=7778 \ LIGHTPANDA_CDP_URL=ws://127.0.0.1:9222 \ WEB_DIR=/app/web \ PYTHONUNBUFFERED=1 \ STATE_REPO=JsonLord/hedge-state EXPOSE 7860 CMD ["/usr/local/bin/entrypoint.sh"]