Docker für Strategien-Deployment.

Wer eine Trading-Strategie schreibt, sollte sie auch in fünf Jahren noch starten können — ohne dass eine kaputte Python-Version, ein verschwundenes Paket oder ein OS-Update zum Stolperstein wird. Docker ist die einfachste, langweiligste und beste Antwort auf dieses Problem. In diesem Artikel zeige ich, wie ich Strategien-Images baue, welche Patterns sich bewähren und welche Anti-Patterns mir in Kundenprojekten immer wieder begegnen.

Warum überhaupt Docker für Trading?

Eine Strategie hat selten weniger als zehn Python-Abhängigkeiten. pandas, numpy, ein Broker-SDK, vielleicht torch oder xgboost, dazu eigene Utility-Pakete. Jedes Paket hat seine eigene Versionspolitik. Was heute auf Ihrem Laptop funktioniert, funktioniert in zwei Jahren mit einem frischen Python-Setup vielleicht nicht mehr — weil pandas eine Funktion entfernt oder ein Broker-SDK eine Breaking-Change-Version released hat.

Docker zementiert den Zustand. Ein gebautes Image enthält die exakten Versionen aller Dependencies, die exakte Python-Runtime, die exakten System-Bibliotheken. Wenn das Image heute läuft, läuft es auch in fünf Jahren — solange Sie den Image-Speicher erhalten. Das ist nicht nur Komfort, sondern Compliance: bei Kundenprojekten ist Reproduzierbarkeit oft eine vertragliche Anforderung.

Das richtige Base-Image.

Hier passieren die ersten Fehler. FROM python:3.12 klingt unschuldig, zieht aber ein 1 GB großes Debian-Image mit hunderten Paketen, die Sie nicht brauchen und die alle CVEs haben können. Die Alternativen, sortiert nach Größe:

Für die Hauptmasse der Trading-Workloads ist python:3.12-slim die richtige Wahl. Sicher genug, klein genug, und es funktioniert mit allen relevanten Python-Paketen ohne Verrenkungen.

Multi-Stage-Build.

Das wichtigste Muster für saubere Trading-Images: Multi-Stage-Builds. Ein Build-Stage installiert Dependencies und kompiliert was kompiliert werden muss, ein Runtime-Stage kopiert nur die fertigen Artefakte. Resultat: kleinere Images, weniger Angriffsfläche, schnellere Pulls.

# Dockerfile fuer eine Trading-Strategie
# syntax=docker/dockerfile:1.7

FROM python:3.12-slim AS build
ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1 \
    PIP_NO_CACHE_DIR=1 \
    PIP_DISABLE_PIP_VERSION_CHECK=1

RUN apt-get update && apt-get install --no-install-recommends -y \
        build-essential \
        git \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY pyproject.toml poetry.lock ./
RUN pip install --upgrade pip poetry==1.8.3 \
    && poetry config virtualenvs.in-project true \
    && poetry install --only=main --no-root --no-interaction

COPY src ./src
RUN poetry install --only=main --no-interaction

# --- Runtime-Stage ---
FROM python:3.12-slim AS runtime
ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1 \
    PATH="/app/.venv/bin:${PATH}"

RUN apt-get update && apt-get install --no-install-recommends -y \
        ca-certificates \
        tzdata \
    && rm -rf /var/lib/apt/lists/* \
    && groupadd --gid 10001 trader \
    && useradd --uid 10001 --gid trader --shell /usr/sbin/nologin trader

WORKDIR /app
COPY --from=build --chown=trader:trader /app/.venv /app/.venv
COPY --from=build --chown=trader:trader /app/src /app/src

USER trader
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
    CMD python -m strategy.healthcheck || exit 1

ENTRYPOINT ["python", "-m", "strategy.run"]

Sechs Punkte, die in diesem Dockerfile wichtig sind. Erstens syntax=docker/dockerfile:1.7 aktiviert moderne BuildKit-Features. Zweitens deterministisch fixierte Versionen (poetry==1.8.3). Drittens kein Pip-Cache im Image. Viertens ein non-root-User mit fixer UID — wichtig für Kubernetes-Pod-Security. Fünftens ein eingebauter Healthcheck. Sechstens ENTRYPOINT statt CMD — der Container tut genau eine Sache.

Reproduzierbare Builds.

Ein typisches Problem: das Image, das letzte Woche gebaut wurde, lässt sich heute nicht reproduzieren — weil ein transitives Dependency-Paket inzwischen eine neue Patch-Version released hat. Drei Maßnahmen verhindern das:

# In Dockerfile
ARG GIT_SHA=unknown
ARG BUILD_TIME=unknown
LABEL org.opencontainers.image.revision="${GIT_SHA}" \
      org.opencontainers.image.created="${BUILD_TIME}" \
      org.opencontainers.image.source="https://github.com/mg-quant/strategies"

# Beim Build
docker build \
    --build-arg GIT_SHA=$(git rev-parse --short HEAD) \
    --build-arg BUILD_TIME=$(date -u +%Y-%m-%dT%H:%M:%SZ) \
    -t ghcr.io/mg-quant/momentum-v3:$(git rev-parse --short HEAD) \
    -t ghcr.io/mg-quant/momentum-v3:latest \
    .

docker-compose für lokale Entwicklung.

Bevor eine Strategie in Kubernetes geht, läuft sie meist erst Wochen lokal. Dafür ist docker-compose immer noch das ehrlichste Werkzeug: einfach genug für Solo-Entwicklung, mächtig genug für realistische Setups mit Datenbank, Broker-Mock und Monitoring.

# docker-compose.yml
version: "3.9"
services:
  strategy:
    build:
      context: .
      dockerfile: Dockerfile
    image: momentum-v3:dev
    env_file:
      - .env.dev
    depends_on:
      postgres:
        condition: service_healthy
      broker-mock:
        condition: service_started
    volumes:
      - ./src:/app/src:ro
    ports:
      - "8080:8080"
    restart: unless-stopped

  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: dev
      POSTGRES_DB: trading
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 3s
      retries: 10
    volumes:
      - postgres_data:/var/lib/postgresql/data

  broker-mock:
    image: ghcr.io/mg-quant/ibkr-mock:1.2.0
    ports:
      - "7497:7497"

  prometheus:
    image: prom/prometheus:v2.54.1
    volumes:
      - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro
    ports:
      - "9090:9090"

volumes:
  postgres_data:

Wichtig: in der Dev-Umgebung werden Source-Files als Bind-Mount eingebunden (./src:/app/src:ro). Das ermöglicht Hot-Reload ohne ständigen Rebuild, der ro-Flag verhindert, dass der Container Files verändert. In Produktion ist das Image immutable.

Security-Patterns.

Trading-Container haben Zugriff auf Geld. Drei Sicherheitsmaßnahmen, die ich für jeden produktiven Container durchsetze:

# Im GitHub-Actions-Workflow
- name: Build image
  run: docker build -t app:${{ github.sha }} .

- name: Scan image with Trivy
  uses: aquasecurity/trivy-action@master
  with:
    image-ref: "app:${{ github.sha }}"
    format: "table"
    exit-code: "1"
    severity: "CRITICAL,HIGH"
    ignore-unfixed: true

Image-Registry und Retention.

Ein praktisches Detail, das oft vergessen wird: Image-Registries kosten Speicher. Wenn Sie jeden Commit als Image taggen, haben Sie nach einem Jahr mehrere hundert Images im Registry. Setzen Sie Retention-Policies: alle Images älter als 90 Tage werden gelöscht, ausgenommen Tags wie release-*, v*.*.* oder latest. Bei GitHub Container Registry funktioniert das mit einer Action wie actions/delete-package-versions.

Wann Docker zu viel ist.

Auch wenn ich Docker fast immer empfehle — es gibt Fälle, wo es Overhead ohne Nutzen ist. Ein einmaliges Recherche-Skript, das einmal pro Quartal in JupyterLab läuft? Kein Docker nötig. Ein winziger Bash-Cron, der einmal pro Tag eine E-Mail schickt? Auch nicht. Docker lohnt sich, sobald Code mehrfach deployed wird, mehrere Maschinen sieht, oder eine produktive Rolle spielt. Dann zahlt sich die initiale Disziplin aus.

Stand: Mai 2026, überarbeitet Oktober 2026. Angaben zu Produkten, Preisen, Gesetzen und Fristen können sich seitdem geändert haben; maßgeblich sind die aktuellen Angaben der Anbieter und Behörden.

Sie wollen Ihre Trading-Strategien sauber containerisieren oder einen reproduzierbaren Build-Prozess aufsetzen? Unverbindlich anfragen — wir gehen Dockerfile, Pipeline und Registry-Strategie gemeinsam an. Mehr zu meinem Angebot: Trading-Systeme entwickeln lassen.