# 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 price_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).