Funk-lab/tools/finlab/Dockerfile
alkatrazz a2b39a084b feat(finlab): dashboard web (graphiques/portefeuille/actions) + fix seed NFS
Ajoute une interface graphique à finlab, en plus de la console Claude Code (les
deux cohabitent sur finance.lab.local) :

- dashboard/ : backend FastAPI (sans LLM/clé) exposant les données finlab en JSON
  (/api/portfolio, /api/scan, /api/ohlc, /api/plan, /api/alerts) + front statique
  (lightweight-charts) : graphiques chandeliers MM50/200 + volume, portefeuille
  (P&L/poids/secteurs), watchlists thématiques scannées, alertes, plan de trade R:R
- Découplage code/data : finlab lit ses configs depuis FINLAB_HOME si défini
  (workspace persistant) ; repli sur le dossier du package en dév local
- Image double usage (un build, deux conteneurs) : code → /opt/app, seed minimal
  (configs + persona + MCP) → workspace
- Fix seed NFS (cause racine du workspace vide) : WORKDIR n'est plus sur le volume
  (le runtime le créait en root sur NFS) ; seed déplacé dans un initContainer
  robuste (recrée le dossier s'il est non-inscriptible)
- Deployment : initContainer seed + 2 conteneurs (console ttyd -b /console, dashboard
  uvicorn) ; Service 2 ports ; IngressRoute 2 routes (/console + dashboard), basicAuth

Validé en local (podman) : seed OK, dashboard /api/portfolio → 16k€/10 positions
via FINLAB_HOME, endpoints ohlc/scan/plan/alerts OK, ttyd/claude/finlab présents.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 00:54:11 +02:00

57 lines
2.9 KiB
Docker

# funk-finlab — image double usage (un seul build, deux conteneurs en déploiement) :
# • CONSOLE : session Claude Code dans un terminal web (ttyd), abonnement persisté.
# • DASHBOARD : interface web (graphiques marché / portefeuille / watchlists / actions).
# Les deux partagent le workspace persistant (PVC) où vivent les CONFIGS éditables (portefeuille,
# watchlists, alertes) ; le CODE finlab vit dans l'image (/opt/app) et se met à jour avec elle.
FROM python:3.12-slim-bookworm
# Node (CLI claude-code) + git + tini. ttyd n'est pas packagé sur bookworm → binaire statique.
ARG TTYD_VERSION=1.7.7
RUN apt-get update && apt-get install -y --no-install-recommends \
curl ca-certificates git tini procps \
&& curl -fsSL "https://github.com/tsl0922/ttyd/releases/download/${TTYD_VERSION}/ttyd.x86_64" \
-o /usr/local/bin/ttyd \
&& chmod +x /usr/local/bin/ttyd \
&& ttyd --version \
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get install -y --no-install-recommends nodejs \
&& npm install -g @anthropic-ai/claude-code \
&& npm cache clean --force \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# Dépendances Python (venv dédié, hors du workspace).
COPY requirements.txt /opt/finlab/requirements.txt
RUN python -m venv /opt/venv \
&& /opt/venv/bin/pip install --no-cache-dir -r /opt/finlab/requirements.txt
# CODE applicatif (mis à jour avec l'image) : package finlab + backend dashboard + webapp (option).
COPY finlab/ /opt/app/finlab/
COPY dashboard/ /opt/app/dashboard/
COPY webapp/ /opt/app/webapp/
# « Seed » du workspace : UNIQUEMENT ce que l'utilisateur édite/possède (pas de code).
# Configs finlab + persona Claude + branchement MCP + autorisations. Copié dans le PVC au
# 1er boot par l'initContainer (cp -rn no-clobber → edits préservés ensuite).
COPY portfolio.yaml watchlists.yaml alerts.yaml /opt/seed/
COPY workspace/CLAUDE.md /opt/seed/CLAUDE.md
COPY workspace/.mcp.json /opt/seed/.mcp.json
COPY workspace/.claude/ /opt/seed/.claude/
COPY entrypoint-seed.sh entrypoint-console.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/entrypoint-seed.sh /usr/local/bin/entrypoint-console.sh
# uid non-root (PodSecurity « restricted »). HOME = PVC (login abonnement + workspace).
# WORKDIR reste sur /opt/app (PAS sur le volume) : sinon le runtime crée le dossier du workspace
# en root sur le NFS avant le process → seed cassé (bug corrigé). Le seed/console font le cd.
RUN useradd -m -u 1000 -s /bin/bash finlab
ENV HOME=/home/finlab \
WORKSPACE=/home/finlab/workspace \
FINLAB_HOME=/home/finlab/workspace \
PATH=/opt/venv/bin:/usr/local/bin:/usr/bin:/bin \
PYTHONPATH=/opt/app \
PYTHONUNBUFFERED=1 \
TZ=Europe/Paris
USER 1000
WORKDIR /opt/app
# Pas d'ENTRYPOINT unique : le Deployment fixe la commande par conteneur
# (entrypoint-seed.sh en initContainer, entrypoint-console.sh + uvicorn en conteneurs).