phase: 01-core-stack
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
- docker-compose.yml
autonomous: true
requirements:
- STACK-02
- STACK-03
- STACK-04
- STACK-05

must_haves:
truths:
- "Ollama laeuft als Container mit NVIDIA-GPU-Zugriff (nvidia-smi sichtbar im Container)"
- "paperless-ai erreicht Ollama unter http://ollama:11434 — kein host.docker.internal mehr"
- "Gitea laeuft als Container und ist im Docker-Netz erreichbar"
- "Alle 6 Dienste sind in docker-compose.yml definiert"
- "Bestehende Dienste (webserver, db, broker, paperless-ai) sind unveraendert erhalten"
artifacts:
- path: "docker-compose.yml"
provides: "6-Dienste-Compose-Stack: broker, db, webserver, paperless-ai, ollama, gitea"
contains: "ollama"
- path: "docker-compose.yml"
provides: "Gitea-Service-Definition"
contains: "gitea"
key_links:
- from: "paperless-ai (environment)"
to: "ollama service"
via: "OLLAMA_API_URL=http://ollama:11434"
pattern: "ollama:11434"
- from: "ollama service"
to: "NVIDIA GPU"
via: "nvidia container runtime + device reservation"
pattern: "nvidia"



Zwei neue Dienste in docker-compose.yml ergaenzen: Ollama (containerisiert, NVIDIA-GPU-Passthrough) und Gitea (Self-hosted-Git).

Purpose: Ollama vom Host-Prozess in einen Container verschieben, damit der Stack keine Host-seitigen Abhaengigkeiten mehr hat. Gitea als sechsten Dienst hinzufuegen.
Output: docker-compose.yml mit 6 Diensten. paperless-ai kommuniziert mit Ollama ueber das interne Docker-Netz statt ueber host.docker.internal.


@$HOME/.claude/get-shit-done/workflows/execute-plan.md
@$HOME/.claude/get-shit-done/templates/summary.md


@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md

Bekannte Image-Namen fuer neue Dienste:
Ollama: ollama/ollama:latest
Gitea: gitea/gitea:latest

Ollama GPU-Passthrough (nvidia-container-toolkit erforderlich auf Debian 13):
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]

paperless-ai OLLAMA_API_URL muss von http://host.docker.internal:11434
auf http://ollama:11434 geaendert werden.


Task 1: Ollama-Dienst mit NVIDIA-GPU-Passthrough ergaenzen
docker-compose.yml

- docker-compose.yml — vollstaendige aktuelle Konfiguration lesen, bevor etwas veraendert wird


Den Dienst ollama in docker-compose.yml ergaenzen. Exakt folgende Konfiguration verwenden:

  ollama:
    image: ollama/ollama:latest
    container_name: paperless-ollama-1
    restart: unless-stopped
    ports:
      - "11434:11434"
    volumes:
      - ollamamodels:/root/.ollama
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]

Gleichzeitig im Dienst paperless-ai die Umgebungsvariable OLLAMA_API_URL hinzufuegen bzw. aktualisieren:

      - OLLAMA_API_URL=http://ollama:11434
      - OLLAMA_MODEL=llama3.2
      - AI_PROVIDER=ollama

Den Dienst paperless-ai mit depends_on: [ollama] ergaenzen, damit Ollama zuerst startet.

Im volumes-Block am Ende der Datei ollamamodels: ergaenzen.

WICHTIG: Die bestehenden Dienste (broker, db, webserver, paperless-ai) NICHT veraendern ausser der depends_on- und environment-Ergaenzung bei paperless-ai.


grep -n "ollama/ollama" /Users/bmt/Documents/OhnePapier-v.0.0/docker-compose.yml && grep -n "ollama:11434" /Users/bmt/Documents/OhnePapier-v.0.0/docker-compose.yml && grep -n "nvidia" /Users/bmt/Documents/OhnePapier-v.0.0/docker-compose.yml && grep -n "ollamamodels" /Users/bmt/Documents/OhnePapier-v.0.0/docker-compose.yml


- grep "ollama/ollama:latest" docker-compose.yml gibt mindestens eine Zeile aus
- grep "ollama:11434" docker-compose.yml gibt mindestens zwei Zeilen aus (ports + OLLAMA_API_URL)
- grep "nvidia" docker-compose.yml findet den capabilities-Eintrag
- grep "count: all" docker-compose.yml findet den GPU-Reservierungs-Block
- grep "ollamamodels" docker-compose.yml findet Volume-Deklaration und Volume-Mount
- grep "OLLAMA_API_URL=http://ollama:11434" docker-compose.yml findet den paperless-ai-Eintrag
- grep "depends_on" docker-compose.yml zeigt dass paperless-ai jetzt ollama als Abhaengigkeit hat

Ollama-Dienst mit GPU-Passthrough in docker-compose.yml vorhanden; paperless-ai zeigt auf http://ollama:11434


Task 2: Gitea-Dienst ergaenzen
docker-compose.yml

- docker-compose.yml — nach Task 1 nochmal lesen um den aktuellen Stand zu kennen


Den Dienst gitea in docker-compose.yml ergaenzen. Exakt folgende Konfiguration verwenden:

  gitea:
    image: gitea/gitea:latest
    container_name: paperless-gitea-1
    restart: unless-stopped
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - GITEA__database__DB_TYPE=sqlite3
    ports:
      - "3001:3000"
      - "222:22"
    volumes:
      - giteadata:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro

Im volumes-Block am Ende der Datei giteadata: ergaenzen.

Hinweis: Gitea benutzt SQLite (keine externe DB-Abhaengigkeit). Port 3001 nach aussen, damit kein Konflikt mit paperless-ai auf 3000. SSH auf 222 statt 22 um Host-SSH freizulassen.


grep -n "gitea/gitea" /Users/bmt/Documents/OhnePapier-v.0.0/docker-compose.yml && grep -n "giteadata" /Users/bmt/Documents/OhnePapier-v.0.0/docker-compose.yml && grep -n "3001:3000" /Users/bmt/Documents/OhnePapier-v.0.0/docker-compose.yml


- grep "gitea/gitea:latest" docker-compose.yml gibt mindestens eine Zeile aus
- grep "3001:3000" docker-compose.yml bestaetigt Port-Mapping (kein Konflikt mit paperless-ai:3000)
- grep "giteadata" docker-compose.yml findet Volume-Deklaration und Volume-Mount
- grep "USER_UID=1000" docker-compose.yml bestaetigt UID-Konfiguration
- docker compose config 2>&1 | grep -c "^ [a-z]" gibt 6 oder mehr zurueck (6 Dienste)
- docker compose config laeuft ohne Fehler durch (valides YAML)

Gitea-Dienst in docker-compose.yml vorhanden; docker compose config validiert ohne Fehler; 6 Dienste total

Vertrauensgrenzen

Grenze Beschreibung
Host-Netz → Docker-Netz Ports 8000, 3000, 3001, 11434, 222 oeffentlich exponiert
paperless-ai → ollama Internes Netz, kein TLS — vertrauenswuerdig weil gleiches Compose-Netz
Docker → NVIDIA-GPU nvidia-container-toolkit vermittelt GPU-Zugriff aus Container

STRIDE Bedrohungsregister

Threat ID Kategorie Komponente Disposition Massnahme
T-01-01 Information Disclosure Ollama Port 11434 (oeffentlich) mitigate Ollama-Port nur auf localhost binden: 127.0.0.1:11434:11434 statt 11434:11434 — Modelle und Prompts bleiben lokal
T-01-02 Elevation of Privilege NVIDIA GPU-Passthrough accept nvidia-container-toolkit isoliert GPU-Zugriff; akzeptabel fuer Single-User-Setup
T-01-03 Information Disclosure Gitea SSH Port 222 mitigate In Firewall (ufw) nur auf vertrauenswuerdige IPs beschraenken; wird in Plan 03 (setup.sh) dokumentiert
T-01-04 Tampering paperless-ai ohne Authentifizierung auf :3000 accept Lokales Netz, kein oeffentliches Internet; cap_drop: ALL bereits gesetzt
T-01-05 Information Disclosure POSTGRES_PASSWORD=paperless (Klartext in Compose) mitigate In Plan 02 in docker-compose.env.template verschieben und aus Compose-Datei entfernen


Nach Ausfuehren beider Tasks:

# YAML-Validierung
docker compose -f /Users/bmt/Documents/OhnePapier-v.0.0/docker-compose.yml config

# Alle 6 Dienste vorhanden
docker compose -f /Users/bmt/Documents/OhnePapier-v.0.0/docker-compose.yml config --services
# Erwartete Ausgabe: broker, db, gitea, ollama, paperless-ai, webserver

# GPU-Konfiguration korrekt
grep -A8 "deploy:" /Users/bmt/Documents/OhnePapier-v.0.0/docker-compose.yml

# Ollama-URL korrekt fuer internes Netz
grep "OLLAMA_API_URL" /Users/bmt/Documents/OhnePapier-v.0.0/docker-compose.yml
# Muss ausgeben: OLLAMA_API_URL=http://ollama:11434


- docker-compose.yml enthaelt exakt 6 Dienste: broker, db, webserver, paperless-ai, ollama, gitea
- docker compose config laeuft ohne Fehler (valides YAML)
- paperless-ai zeigt auf http://ollama:11434 (nicht auf host.docker.internal)
- Ollama hat nvidia GPU-Reservierung mit count: all und capabilities: [gpu]
- Gitea-Port 3001 kein Konflikt mit paperless-ai auf 3000
- Volumes: ollamamodels und giteadata deklariert

Nach Abschluss `.planning/phases/01-core-stack/01-01-SUMMARY.md` erstellen.