Technology Stack

Analysis Date: 2026-04-17

Project Type

This is a Docker Compose orchestration project. There is no application source code to compile, test, or build. The stack is entirely composed of pre-built Docker images configured via docker-compose.yml and environment files.

Languages

Primary:
- None (no source code) β€” all services are containerized third-party images

Configuration Languages:
- YAML β€” docker-compose.yml (service definitions, volumes, networking)
- .env β€” Docker variable injection (e.g., PAPERLESS_AI_PORT)
- docker-compose.env β€” Paperless-ngx runtime configuration (gitignored, must be created manually)

Runtime

Environment:
- Docker Engine (with Compose plugin)
- Host platform: macOS (darwin 25.3.0, amd64/arm64)
- Paperless-ngx supports: amd64, arm, arm64

Orchestration:
- Docker Compose v2 (docker compose up -d)

Services (Docker Images)

webserver β€” Paperless-ngx:
- Image: ghcr.io/paperless-ngx/paperless-ngx:latest
- Registry: GitHub Container Registry (ghcr.io)
- Runtime inside container: Python / Django
- Port: 8000 (host) β†’ 8000 (container)
- Restart policy: unless-stopped
- Volumes: data:/usr/src/paperless/data, media:/usr/src/paperless/media, ./export, ./consume
- Config: reads from docker-compose.env (env_file)
- Depends on: db, broker

db β€” PostgreSQL:
- Image: docker.io/library/postgres:18
- Version: 18 (explicit pin)
- Port: 5432 (internal only, not exposed to host)
- Restart policy: unless-stopped
- Volume: pgdata:/var/lib/postgresql
- Database: paperless, User: paperless

broker β€” Redis:
- Image: docker.io/library/redis:8
- Version: 8 (explicit pin)
- Port: 6379 (internal only, not exposed to host)
- Restart policy: unless-stopped
- Volume: redisdata:/data
- Role: Message broker and cache for Paperless-ngx task queue

paperless-ai β€” AI Analysis Layer:
- Image: clusterzx/paperless-ai
- Registry: Docker Hub
- Version: untagged (:latest implied)
- Runtime inside container: Node.js
- Port: 3000 (host) β†’ ${PAPERLESS_AI_PORT:-3000} (container)
- Container name: paperless-ai (explicit, fixed)
- Restart policy: unless-stopped
- Depends on: webserver
- Security: cap_drop: ALL, no-new-privileges: true
- Volume: paperless-ai_data:/app/data
- Env vars set in compose: PUID=1000, PGID=1000, RAG_SERVICE_URL, RAG_SERVICE_ENABLED

Ollama β€” Local LLM (Host-native, NOT containerized):
- Not a Docker service β€” runs directly on the host machine
- Purpose: GPU access for local LLM inference
- Port: 11434 (host)
- Models: llama3.2 (primary), llama2
- Containers reach it via: http://host.docker.internal:11434
- Start command: ollama serve

Docker Volumes

All volumes are Docker-managed (no bind-mount paths except ./export and ./consume):

Volume Service Purpose
data webserver Paperless application data
media webserver Scanned/imported document files
pgdata db PostgreSQL database files
redisdata broker Redis persistence
paperless-ai_data paperless-ai paperless-ai config, ChromaDB vectors

Bind-mounted host directories:
- ./export β†’ /usr/src/paperless/export (document export target)
- ./consume β†’ /usr/src/paperless/consume (document drop/inbox)

Configuration

Environment files:
- .env β€” Docker Compose variable injection (committed; currently only PAPERLESS_AI_PORT)
- docker-compose.env β€” Paperless-ngx secrets and settings (gitignored, created manually on each install)

Required contents of docker-compose.env (not in repo):
- ADMIN_USER, ADMIN_PASSWORD, SECRET_KEY β€” minimum required keys
- PAPERLESS_REDIS=redis://broker:6379 (set in compose directly)
- PAPERLESS_DBHOST=db (set in compose directly)

paperless-ai runtime config (stored at /app/data/.env inside container, set via web UI at :3000/setup):
- PAPERLESS_API_URL=http://webserver:8000/api (must end with /api)
- PAPERLESS_URL=http://webserver:8000 (must NOT have /api)
- PAPERLESS_API_TOKEN=<generated-token>
- AI_PROVIDER=ollama
- OLLAMA_API_URL=http://host.docker.internal:11434
- OLLAMA_MODEL=llama3.2
- SCAN_INTERVAL=*/30 * * * *

Platform Requirements

Development / Production (same machine):
- Docker Engine with Compose plugin
- Ollama installed and running on host (ollama serve)
- docker-compose.env created manually (not in git)
- No internet required after initial image pull

Known Constraints:
- network_mode: bridge must NOT be set on paperless-ai β€” it breaks host.docker.internal DNS resolution to Ollama
- Ollama must be started before docker compose up

Key Configuration Files

File Path Committed
Service definitions docker-compose.yml Yes
Compose variables .env Yes
Paperless-ngx secrets docker-compose.env No (gitignored)
Gitignore rules .gitignore Yes

Stack analysis: 2026-04-17