# syntax=docker/dockerfile:1 # ───────────────────────────────────────────────────────────────────────────── # TradeMind – Container-Image # # podman build --format docker -t trademind:latest -f Containerfile . # # --format docker ist nötig, damit die HEALTHCHECK-Anweisung ins Image übernommen wird; # das OCI-Format kennt sie nicht. podman-compose und die Quadlet-Einheit bringen den # Healthcheck ohnehin selbst mit, dort ist das Format egal. # ───────────────────────────────────────────────────────────────────────────── # ---------- Stufe 1: Abhängigkeiten in ein virtuelles Environment installieren FROM docker.io/library/python:3.12-slim AS builder ENV PIP_NO_CACHE_DIR=1 \ PIP_DISABLE_PIP_VERSION_CHECK=1 \ PYTHONDONTWRITEBYTECODE=1 WORKDIR /build RUN python -m venv /opt/venv ENV PATH="/opt/venv/bin:$PATH" # Erst die Metadaten kopieren – so bleibt der Dependency-Layer über Codeänderungen hinweg gültig. COPY pyproject.toml README.md ./ COPY src/trademind/__init__.py ./src/trademind/__init__.py RUN pip install --upgrade pip setuptools wheel && pip install . # Jetzt den vollständigen Quellcode und das Paket selbst installieren. COPY src/ ./src/ RUN pip install --no-deps . # ---------- Stufe 2: schlankes Laufzeit-Image FROM docker.io/library/python:3.12-slim AS runtime LABEL org.opencontainers.image.title="TradeMind" \ org.opencontainers.image.description="Selbstlernender Krypto-Trading-Bot (Paper, Backtest, Live)" \ org.opencontainers.image.source="https://github.com/tlt-turbo/trademind" \ org.opencontainers.image.licenses="MIT" ENV PATH="/opt/venv/bin:$PATH" \ PYTHONUNBUFFERED=1 \ PYTHONDONTWRITEBYTECODE=1 \ TRADEMIND_CONFIG=/config/config.yaml \ TZ=UTC # Nicht-Root-Benutzer; UID/GID 10001 kollidiert selten mit Host-Benutzern. RUN groupadd --gid 10001 trademind \ && useradd --uid 10001 --gid 10001 --create-home --home-dir /home/trademind trademind \ && mkdir -p /data/models /config \ && chown -R 10001:10001 /data /config COPY --from=builder /opt/venv /opt/venv COPY --chown=10001:10001 config/config.example.yaml /config/config.example.yaml USER 10001:10001 WORKDIR /home/trademind # /data hält SQLite-Datenbank und trainiertes Modell – als Volume einhängen, sonst # gehen Lernfortschritt und Historie beim Neustart verloren. VOLUME ["/data"] EXPOSE 8080 HEALTHCHECK --interval=30s --timeout=5s --start-period=45s --retries=3 \ CMD python -c "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:8080/health', timeout=4).status==200 else 1)" ENTRYPOINT ["trademind"] CMD ["run", "--config", "/config/config.yaml"]