File size: 3,424 Bytes
eed6127
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# 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"]