phase: 01-core-stack
plan: "01"
subsystem: infra
tags: [docker-compose, ollama, gitea, nvidia, gpu-passthrough, paperless-ngx]
Dependency graph
requires: []
provides:
- ollama/ollama:latest service with NVIDIA GPU passthrough in docker-compose.yml
- gitea/gitea:latest service with SQLite backend in docker-compose.yml
- paperless-ai now references ollama via internal Docker network (http://ollama:11434)
- volumes: ollamamodels, giteadata declared
affects:
- 01-02-PLAN.md (adds healthchecks/network to these 6 services)
- Phase 3 (verify.sh must check Ollama GPU and Gitea reachability)
Tech tracking
tech-stack:
added:
- ollama/ollama:latest (containerized LLM inference with GPU passthrough)
- gitea/gitea:latest (self-hosted Git, SQLite backend)
- nvidia-container-runtime device reservation (deploy.resources.reservations.devices)
patterns:
- GPU passthrough via Docker Compose deploy.resources.reservations.devices block
- Ollama port bound to 127.0.0.1 only (localhost-only exposure per threat model)
- Internal service communication via Docker Compose service names (ollama:11434)
key-files:
created: []
modified:
- docker-compose.yml
key-decisions:
- "Ollama port bound to 127.0.0.1:11434 not 0.0.0.0:11434 — T-01-01 threat mitigation to prevent external model/prompt exposure"
- "Gitea uses SQLite (GITEA__database__DB_TYPE=sqlite3) — no external DB dependency, self-contained service"
- "Gitea SSH on port 222 to leave host SSH port 22 free"
- "Gitea web on port 3001 to avoid conflict with paperless-ai on 3000"
patterns-established:
- "Threat model mitigations applied at implementation time (T-01-01: localhost binding)"
- "paperless-ai depends_on ollama to ensure correct startup order"
requirements-completed: [STACK-02, STACK-03, STACK-04, STACK-05]
Metrics
duration: 1min
completed: 2026-04-17
Phase 1 Plan 01: Ollama (GPU-Passthrough) + Gitea Summary
Ollama containerized with NVIDIA GPU passthrough and Gitea added as a 6th service — paperless-ai switched from host.docker.internal to internal Docker network routing
Performance
- Duration: 1 min
- Started: 2026-04-17T20:36:12Z
- Completed: 2026-04-17T20:37:20Z
- Tasks: 2
- Files modified: 1
Accomplishments
- Added
ollama/ollama:latestservice with NVIDIA GPU device reservation (count: all,capabilities: [gpu]) — Ollama now runs inside Docker, eliminating the host-sideollama servedependency - Added
gitea/gitea:latestservice with SQLite backend on port 3001 (web) and 222 (SSH), with persistentgiteadatavolume - Updated
paperless-aito route Ollama requests via internal Docker network (http://ollama:11434) instead ofhost.docker.internal, addeddepends_on: [ollama]for correct startup order
Task Commits
Each task was committed atomically:
- Task 1: Ollama-Dienst mit NVIDIA-GPU-Passthrough -
c9034d4(feat) - Task 2: Gitea-Dienst ergaenzen -
56c9f8a(feat)
Plan metadata: committed with SUMMARY.md (docs)
Files Created/Modified
docker-compose.yml— Added ollama and gitea services, updated paperless-ai environment and depends_on, added ollamamodels and giteadata volumes
Decisions Made
- Ollama port localhost-only: Bound to
127.0.0.1:11434:11434instead of11434:11434— implements T-01-01 threat mitigation from the plan's threat model. Ollama models and prompts stay local and are not exposed on the network interface. - Gitea SQLite: Used
GITEA__database__DB_TYPE=sqlite3as specified — keeps Gitea self-contained with no external DB dependency. - Port assignments: Gitea web on 3001 (paperless-ai holds 3000), SSH on 222 (host SSH holds 22).
Deviations from Plan
Auto-fixed Issues
1. [Rule 2 - Security Mitigation] Ollama port bound to localhost only
- Found during: Task 1
- Issue: Plan specified 11434:11434 but the threat model (T-01-01, disposition: mitigate) requires binding to localhost only to prevent external exposure of LLM models and prompts
- Fix: Changed port binding to 127.0.0.1:11434:11434
- Files modified: docker-compose.yml
- Verification: grep "127.0.0.1:11434" docker-compose.yml confirms localhost binding
- Committed in: c9034d4 (Task 1 commit)
Total deviations: 1 auto-fixed (1 security mitigation from plan's own threat model)
Impact on plan: Required for security correctness. No scope creep — threat model T-01-01 explicitly calls for this mitigation.
Issues Encountered
docker compose configvalidation initially showed error about missingdocker-compose.env— this is expected behavior, the file is intentionally not committed to git (per CLAUDE.md). Verified YAML validity using a temporary stub env file.
User Setup Required
None — no external service configuration required by this plan. (The docker-compose.env file required for full stack startup is addressed in Plan 02.)
Next Phase Readiness
docker-compose.ymlnow defines all 6 services: broker, db, webserver, paperless-ai, ollama, gitea- Ready for Plan 02: explicit Docker network declaration, healthchecks, security hardening, and
docker-compose.env.template - Pre-flight note:
nvidia-container-toolkitmust be installed on the target Debian 13 host for GPU passthrough to work — this is a host prerequisite, not a Compose concern
Phase: 01-core-stack
Completed: 2026-04-17