phase: 01-core-stack
plan: "02"
subsystem: infra
tags: [docker-compose, healthchecks, networking, security-hardening, env-template]

Dependency graph

requires:
- phase: 01-core-stack/01-01
provides: 6-service docker-compose.yml (broker, db, webserver, paperless-ai, ollama, gitea)
provides:
- paperless-net bridge network declared; all 6 services joined
- healthchecks on all 6 services with appropriate start_period values
- Ollama port binding hardened to 127.0.0.1:11434 only
- docker-compose.env.template versioned in git with all required variables
- depends_on conditions upgraded to service_healthy for webserver and paperless-ai
affects:
- 01-03 (Phase 3: install/verify scripts — verify.sh can rely on healthcheck status)
- SCRIPT-03 (Phase 3): will migrate POSTGRES_PASSWORD out of compose plaintext

Tech tracking

tech-stack:
added: []
patterns:
- Healthcheck pattern: redis-cli ping, pg_isready, curl -f for all service types
- Docker network isolation: explicit named bridge network (paperless-net)
- depends_on with condition: service_healthy for startup ordering
- Env template pattern: CHANGE_ME markers, versioned template + gitignored real file

key-files:
created:
- docker-compose.env.template
modified:
- docker-compose.yml

key-decisions:
- "depends_on upgraded to service_healthy — ensures webserver waits for DB+broker, paperless-ai waits for webserver+ollama before starting"
- "POSTGRES_PASSWORD left as plaintext in compose — deferred to SCRIPT-03 (Phase 3) per plan; stack must be functional first"
- "OLLAMA_API_URL in template uses http://ollama:11434 (internal Docker network), not host.docker.internal — consistent with Wave 1 decision"

patterns-established:
- "Threat model T-02-01 mitigated: docker-compose.env in .gitignore, template is the versioned artifact"
- "Threat model T-02-04 documented: POSTGRES_PASSWORD comment in compose pointing to Phase 3 migration"

requirements-completed: [STACK-01, STACK-05]

Metrics

duration: 2min
completed: 2026-04-17


Phase 1 Plan 02: Netzwerk, Healthchecks, Sicherheitshaertung Summary

paperless-net bridge network + 6 healthchecks + service_healthy startup ordering + versioned docker-compose.env.template — Stack jetzt produktionsreif startbar

Performance

  • Duration: ~2 min
  • Started: 2026-04-17T20:39:40Z
  • Completed: 2026-04-17T20:41:00Z
  • Tasks: 2
  • Files modified: 2

Accomplishments

  • Added paperless-net (bridge driver) network to docker-compose.yml; all 6 services now explicitly joined — no implicit default network
  • Added healthchecks to all 6 services with correct test commands: redis-cli ping (broker), pg_isready (db), curl -f (webserver, ollama, gitea, paperless-ai); start_period 60s for slow-starting services
  • Upgraded depends_on to condition: service_healthy for webserver (waits for db+broker) and paperless-ai (waits for webserver+ollama)
  • Created docker-compose.env.template with all required variables, CHANGE_ME markers on secrets, internal-network OLLAMA_API_URL

Task Commits

Each task was committed atomically:

  1. Task 1: Explizites Netz + Healthchecks + Sicherheitshaertung - 7a09cae (feat)
  2. Task 2: docker-compose.env.template erstellen - b8ed795 (feat)

Files Created/Modified

  • docker-compose.yml — Added paperless-net to all 6 services, 6 healthchecks, service_healthy depends_on, T-02-04 comment on POSTGRES_PASSWORD
  • docker-compose.env.template — New file: all required env vars, CHANGE_ME markers, API token generation instructions, internal Ollama URL

Decisions Made

  • service_healthy depends_on: webserver now waits for db and broker to be healthy; paperless-ai waits for webserver and ollama. This prevents race-condition startup failures where paperless tried to connect before DB was ready.
  • POSTGRES_PASSWORD deferred: Plan explicitly calls out that the plaintext value in docker-compose.yml stays until SCRIPT-03 (Phase 3) migrates it to docker-compose.env. A comment was added to the compose file pointing to this future migration.
  • OLLAMA_API_URL = http://ollama:11434 in template: Consistent with Wave 1 decision — all inter-service communication uses Docker internal names, not host.docker.internal.

Deviations from Plan

None - plan executed exactly as written.

Issues Encountered

  • docker compose config requires docker-compose.env to be present for validation (env_file directive). Used a temporary stub file for YAML validation. This is expected behavior — the real file is intentionally absent from git.

User Setup Required

None - no external service configuration required. Users create docker-compose.env from the template before first stack startup.

Next Phase Readiness

  • docker-compose.yml is now production-ready: explicit networking, healthchecks, hardened port binding
  • docker-compose.env.template is versioned — users copy and fill in secrets before docker compose up -d
  • Phase 2 (AI Providers) and Phase 3 (Install & Verify Scripts) can build on this stable foundation
  • Phase 3 verify.sh can use docker compose ps healthcheck status for readiness checks
  • Remaining: POSTGRES_PASSWORD migration (SCRIPT-03, Phase 3)

Threat Flags

No new threat surface introduced. Both T-02-01 and T-02-04 mitigations from the plan's threat model have been applied:
- T-02-01: docker-compose.env in .gitignore; template (no secrets) versioned
- T-02-04: Comment in compose pointing to Phase 3 migration


Self-Check: PASSED

  • docker-compose.yml exists: FOUND
  • docker-compose.env.template exists: FOUND
  • Commit 7a09cae: FOUND (feat(01-02): add paperless-net, healthchecks...)
  • Commit b8ed795: FOUND (feat(01-02): add docker-compose.env.template...)
  • healthcheck count: 6 (confirmed)
  • paperless-net references: 7 (confirmed)
  • 127.0.0.1:11434 binding: confirmed
  • docker-compose.env in .gitignore: confirmed

Phase: 01-core-stack
Completed: 2026-04-17