# Paperless OCR worker (SOLARIA) — KB module 3.
#
# Same image as services/paperless/ but the command is overridden to run ONLY
# a celery worker (no webserver, no consumer, no beat). It attaches to the
# broker/DB of paperless@PIHA and sees the document storage via NFS from PIHA.
# This split is NOT officially supported by paperless-ngx but is the
# maintainer-confirmed pattern (GH discussion #3900); constraints and risks
# are documented in README.md.
#
# When SOLARIA is powered down this worker simply disappears — queued tasks
# wait in Redis@PIHA (AOF-persisted) and PIHA's built-in concurrency-1 worker
# grinds slowly. When SOLARIA returns, this worker drains the queue.
services:
  paperless-worker:
    # MUST be the exact same tag as services/paperless/docker-compose.yml —
    # shared DB schema + celery task signatures. Bump both together.
    image: ghcr.io/paperless-ngx/paperless-ngx:2.14
    container_name: paperless-worker
    restart: unless-stopped
    # Worker-only mode: the image entrypoint handles USERMAP + language
    # install, then execs this instead of the full s6 service tree.
    # OCR (ocrmypdf/tesseract) is CPU-bound — the win here is SOLARIA's
    # 24 cores, not the GPU (stock paperless OCR does not use CUDA).
    #
    # MUST be an absolute path. /sbin/docker-entrypoint.sh branches on
    # argv[0]: anything NOT starting with "/" is treated as a Django
    # management-command name and handed to `manage.py` (`exec gosu paperless
    # python3 manage.py "$@"`) — so a bare `celery ...` command fails with
    # "Unknown command: 'celery'". An absolute path takes the `else exec "$@"`
    # branch instead, running celery directly. `gosu paperless` in front
    # replaces the implicit gosu the manage.py branch would have applied, so
    # the process still runs as uid 1000 (paperless), not root — required so
    # files it writes on the NFS-shared storage keep the correct owner and
    # match USERMAP_UID/GID below. Verified against the image: gosu is at
    # /usr/sbin/gosu, celery at /usr/local/bin/celery.
    command: /usr/sbin/gosu paperless /usr/local/bin/celery --app paperless worker --loglevel INFO --concurrency ${WORKER_CONCURRENCY:-4}
    env_file:
      - .env
    environment:
      # Broker + DB on PIHA over the fast LAN (NOT Tailscale) — same L2 as
      # the NFS mounts, transfer is not the bottleneck. Broker has
      # requirepass set — PAPERLESS_REDIS_PASSWORD in .env MUST equal the
      # value in services/paperless/.env on PIHA.
      - PAPERLESS_REDIS=redis://:${PAPERLESS_REDIS_PASSWORD}@192.168.31.5:6380
      - PAPERLESS_DBHOST=192.168.31.5
      - PAPERLESS_DBPORT=5434
      - PAPERLESS_DBNAME=paperless
      - PAPERLESS_DBUSER=paperless
      # Settings below MUST mirror services/paperless — drift between the two
      # stacks changes how documents get named/OCR-ed depending on which host
      # picked the task.
      - PAPERLESS_URL=https://paper.kapala.org
      - PAPERLESS_TIME_ZONE=Europe/Warsaw
      - PAPERLESS_OCR_LANGUAGES=pol
      - PAPERLESS_OCR_LANGUAGE=pol+eng
      # Threads used INSIDE a single OCR task; total load ~ concurrency ×
      # threads. 4×4=16 threads leaves headroom on 24 cores/32 threads.
      # TODO AT DEPLOY (module 5): measure on a sample before the 70k-attachment
      # batch — decide whether to raise concurrency (e.g. 8) or keep headroom
      # for ollama/AI workloads.
      - PAPERLESS_THREADS_PER_WORKER=4
      # MUST match paperless@PIHA — files on the NFS export carry numeric
      # UID/GID; a mismatch means this worker cannot read/write documents.
      - USERMAP_UID=1000
      - USERMAP_GID=1000
    volumes:
      # NFS volumes from PIHA (defined below). Container paths MUST be
      # identical to paperless@PIHA — task payloads and the DB carry absolute
      # /usr/src/paperless/... paths.
      - paperless_data:/usr/src/paperless/data
      - paperless_media:/usr/src/paperless/media
      - paperless_consume:/usr/src/paperless/consume
      # SCRATCH_DIR (default /tmp/paperless — paperless-ngx sets it to
      # tempfile.gettempdir()/"paperless" when PAPERLESS_SCRATCH_DIR is unset,
      # see src/paperless/settings.py) is where paperless@PIHA stages the
      # uploaded file before consuming it. The celery task payload carries
      # that path as an ABSOLUTE path, and this worker opens the same path on
      # its own filesystem — without a shared mount here, any task picked up
      # by SOLARIA (instead of the local PIHA worker) fails with "Cannot
      # consume ...: File not found". Must be NFS-mounted at the identical
      # container path, same reasoning as data/media/consume above. No need
      # to set PAPERLESS_SCRATCH_DIR explicitly: the default already resolves
      # to /tmp/paperless on both sides.
      - paperless_scratch:/tmp/paperless
    healthcheck:
      # Pings THIS worker through the broker — proves broker connectivity and
      # a live celery process in one shot.
      test: ["CMD", "celery", "--app", "paperless", "inspect", "ping", "--timeout", "10"]
      interval: 60s
      timeout: 15s
      retries: 3
      start_period: 60s

# Docker-managed NFS mounts (no /etc/fstab entry needed on SOLARIA). Docker
# mounts these lazily on container start; if PIHA is unreachable the container
# fails to start and docker retries via restart policy — acceptable, the queue
# waits on PIHA anyway. The HOST-side prerequisite is on PIHA: the /etc/exports
# entry (see README.md, "NFS export").
volumes:
  paperless_data:
    driver: local
    driver_opts:
      type: nfs
      o: addr=192.168.31.5,rw,nfsvers=4.1,hard,timeo=150
      device: ":/opt/homelab/data/paperless/data"
  paperless_media:
    driver: local
    driver_opts:
      type: nfs
      o: addr=192.168.31.5,rw,nfsvers=4.1,hard,timeo=150
      device: ":/opt/homelab/data/paperless/media"
  paperless_consume:
    driver: local
    driver_opts:
      type: nfs
      o: addr=192.168.31.5,rw,nfsvers=4.1,hard,timeo=150
      device: ":/opt/homelab/data/paperless/consume"
  paperless_scratch:
    driver: local
    driver_opts:
      type: nfs
      o: addr=192.168.31.5,rw,nfsvers=4.1,hard,timeo=150
      device: ":/opt/homelab/data/paperless/scratch"
