Paperless-ngx zelf hosten op een VPS met Docker Compose

12 min leestijd·Matthieu·self-hostingdocker-composeocrdocument-managementpaperless-ngx|

Deploy Paperless-ngx op een VPS met Docker Compose, PostgreSQL en Redis. Configureer OCR-talen en -modi, automatische tagging-regels, e-mailverwerking en een productie-backupstrategie met offsite-synchronisatie.

Paperless-ngx maakt van je VPS een doorzoekbaar documentenarchief. Je scant of uploadt documenten, Paperless-ngx voert OCR uit, maakt ze doorzoekbaar op volledige tekst en ordent ze met automatische tags en correspondenten. Het draait als een Docker Compose-stack met PostgreSQL, Redis en Gotenberg voor documentconversie.

Deze handleiding deployt Paperless-ngx op een VPS waar Docker en een reverse proxy al draaien. Als je die basis nog niet hebt, begin dan met onze handleiding voor het opzetten van de Docker-basisstack.

Welke resources heeft Paperless-ngx nodig op een VPS?

Paperless-ngx vereist minimaal 2 GB RAM, 4 GB aanbevolen. De stack draait PostgreSQL, Redis, Gotenberg, Tika en de webserver. In rust ligt het totale geheugengebruik rond de 900 MB. Tijdens OCR-verwerking van gescande PDF's verdeelt het CPU-gebruik zich over twee of meer cores en stijgt het RAM-gebruik naar 1,5-2 GB. Schijfgebruik is gemiddeld 5-10 MB per document (origineel + archief + thumbnail).

Component RAM (rust) RAM max (OCR) Schijf per 1.000 docs
Paperless-ngx webserver ~650 MB ~1.100 MB 5-10 GB
PostgreSQL ~50 MB ~100 MB ~500 MB
Redis ~10 MB ~10 MB verwaarloosbaar
Gotenberg ~10 MB ~300 MB —
Tika ~160 MB ~400 MB —
Totaal ~880 MB ~1.910 MB 5-10 GB

Plan de schijfruimte op basis van je documentvolume. Een huishouden dat 50 documenten per maand scant, heeft ongeveer 6 GB per jaar nodig. Een klein bedrijf met 500 documenten/maand moet 50-60 GB per jaar reserveren.

Hoe deploy ik Paperless-ngx met Docker Compose op een VPS?

Maak een directory voor de stack, genereer secrets en schrijf het Compose-bestand. Elke service heeft een health check zodat Docker ongezonde containers automatisch herstart.

Projectdirectory aanmaken

mkdir -p /opt/paperless-ngx && cd /opt/paperless-ngx

Secrets genereren

Gebruik nooit standaardwachtwoorden. Genereer een sterk databasewachtwoord en een Django-secret-key:

openssl rand -base64 32 > .db_password
openssl rand -base64 48 > .secret_key
chmod 600 .db_password .secret_key

Deze bestanden blijven op schijf staan met beperkte rechten. Het Compose-bestand leest ze bij het starten van de containers.

Omgevingsbestand schrijven

cat > .env << 'EOF'
COMPOSE_PROJECT_NAME=paperless
EOF

Compose-bestand schrijven

# docker-compose.yml
services:
  broker:
    image: docker.io/library/redis:8
    restart: unless-stopped
    volumes:
      - redisdata:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 30s
      timeout: 5s
      retries: 3

  db:
    image: docker.io/library/postgres:18
    restart: unless-stopped
    volumes:
      - pgdata:/var/lib/postgresql
    environment:
      POSTGRES_DB: paperless
      POSTGRES_USER: paperless
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U paperless"]
      interval: 30s
      timeout: 5s
      retries: 3

  gotenberg:
    image: docker.io/gotenberg/gotenberg:8
    restart: unless-stopped
    command:
      - "gotenberg"
      - "--chromium-disable-javascript=true"
      - "--chromium-allow-list=file:///tmp/.*"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 5s
      retries: 3

  tika:
    image: docker.io/apache/tika:3.3.1.0
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "bash", "-c", "exec 3<>/dev/tcp/127.0.0.1/9998"]
      interval: 30s
      timeout: 5s
      retries: 3

  webserver:
    image: ghcr.io/paperless-ngx/paperless-ngx:latest
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
      broker:
        condition: service_healthy
      gotenberg:
        condition: service_healthy
      tika:
        condition: service_healthy
    ports:
      - "127.0.0.1:8000:8000"
    volumes:
      - data:/usr/src/paperless/data
      - media:/usr/src/paperless/media
      - ./export:/usr/src/paperless/export
      - ./consume:/usr/src/paperless/consume
    environment:
      PAPERLESS_REDIS: redis://broker:6379
      PAPERLESS_DBENGINE: postgresql
      PAPERLESS_DBHOST: db
      PAPERLESS_DBUSER: paperless
      PAPERLESS_DBPASS_FILE: /run/secrets/db_password
      PAPERLESS_TIKA_ENABLED: 1
      PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
      PAPERLESS_TIKA_ENDPOINT: http://tika:9998
      PAPERLESS_SECRET_KEY_FILE: /run/secrets/secret_key
      PAPERLESS_OCR_LANGUAGE: eng
      PAPERLESS_OCR_MODE: auto
      PAPERLESS_OCR_OUTPUT_TYPE: pdfa
      PAPERLESS_FILENAME_FORMAT: "{{ created_year }}/{{ correspondent }}/{{ title }}"
      PAPERLESS_URL: https://paperless.example.com
      USERMAP_UID: 1000
      USERMAP_GID: 1000
    secrets:
      - db_password
      - secret_key
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 60s

secrets:
  db_password:
    file: .db_password
  secret_key:
    file: .secret_key

volumes:
  data:
  media:
  pgdata:
  redisdata:

Over deze configuratie:

  • Poorten zijn alleen gebonden aan 127.0.0.1. Je reverse proxy verzorgt de publieke toegang via HTTPS. Poort 8000 blootstellen op 0.0.0.0 zou TLS en je firewall omzeilen.
  • Tika staat vast op 3.3.1.0. Tika 4 heeft de endpoints verwijderd die Paperless-ngx aanroept, dus apache/tika:latest breekt de verwerking van Office-bestanden en e-mails. De Tika-image bevat geen curl, daarom opent de health check de poort met bash.
  • PAPERLESS_DBENGINE: postgresql is sinds Paperless-ngx 3.0 verplicht om PostgreSQL te gebruiken.
  • Secrets gebruiken Docker secrets (variabelen met het _FILE-achtervoegsel). Wachtwoorden verschijnen nooit in de uitvoer van docker inspect of in proceslijsten.
  • USERMAP_UID/USERMAP_GID koppelen de containergebruiker aan UID 1000 op de host. Bestanden die in de consume- en export-directory's worden aangemaakt, zijn eigendom van deze gebruiker.
  • PAPERLESS_URL moet overeenkomen met je publieke domein. Paperless-ngx gebruikt dit voor het genereren van deellinks en e-mail-URL's. Vervang paperless.example.com door je werkelijke domein.

De stack starten

docker compose up -d

Wacht ongeveer 60 seconden tot alle services zijn geïnitialiseerd. Controleer of elke container gezond is:

docker compose ps
NAME                    IMAGE                                        COMMAND                  SERVICE     CREATED              STATUS                        PORTS
paperless-broker-1      docker.io/library/redis:8                    "docker-entrypoint.s…"   broker      About a minute ago   Up About a minute (healthy)   6379/tcp
paperless-db-1          docker.io/library/postgres:18                "docker-entrypoint.s…"   db          About a minute ago   Up About a minute (healthy)   5432/tcp
paperless-gotenberg-1   docker.io/gotenberg/gotenberg:8              "/usr/bin/tini -- go…"   gotenberg   About a minute ago   Up About a minute (healthy)   3000/tcp
paperless-tika-1        docker.io/apache/tika:3.3.1.0                "/bin/sh -c 'exec ja…"   tika        About a minute ago   Up About a minute (healthy)   9998/tcp
paperless-webserver-1   ghcr.io/paperless-ngx/paperless-ngx:latest   "/init"                  webserver   About a minute ago   Up About a minute (healthy)   127.0.0.1:8000->8000/tcp

Alle vijf containers moeten (healthy) tonen. Als er een (health: starting) toont, wacht dan nog 30 seconden. Als een container (unhealthy) blijft, bekijk de logs:

docker compose logs gotenberg --tail 20

Superuser aanmaken

docker compose exec webserver createsuperuser

Volg de prompts voor gebruikersnaam, e-mail en wachtwoord. Dit is je beheerdersaccount voor de webinterface.

Toegang tot de webinterface

Als je reverse proxy is geconfigureerd, open https://paperless.example.com in een browser. De Paperless-ngx-inlogpagina wordt geladen. Als je de reverse proxy nog aan het instellen bent, test lokaal:

curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8000
302

De 302 is de doorverwijzing naar de inlogpagina, dus Paperless-ngx antwoordt.

Welke OCR-talen en -modi moet ik configureren?

Paperless-ngx gebruikt Tesseract voor OCR. Taal en verwerkingsmodus configureer je via omgevingsvariabelen. De standaardwaarden werken voor Engelstalige documenten, maar de meeste gebruikers moeten ze aanpassen.

OCR-taal

Stel PAPERLESS_OCR_LANGUAGE in op de drieletterige Tesseract-taalcode van je documenten. Voor meerdere talen, verbind ze met +:

# Enkele taal
PAPERLESS_OCR_LANGUAGE: nld

# Meerdere talen
PAPERLESS_OCR_LANGUAGE: nld+eng+deu

Veelgebruikte taalcodes: eng (Engels), deu (Duits), fra (Frans), spa (Spaans), ita (Italiaans), nld (Nederlands), por (Portugees). De volledige lijst staat in de Tesseract-documentatie.

De containerimage bevat alleen Engels, Duits, Frans, Italiaans en Spaans. Voor elke andere taal zet je de code in PAPERLESS_OCR_LANGUAGES (gescheiden door spaties) en de container installeert die bij het opstarten:

PAPERLESS_OCR_LANGUAGES: nld
PAPERLESS_OCR_LANGUAGE: deu+eng+nld

Meer talen toevoegen aan PAPERLESS_OCR_LANGUAGE verhoogt de OCR-verwerkingstijd per pagina.

OCR-modi

De instelling PAPERLESS_OCR_MODE bepaalt hoe Paperless-ngx omgaat met documenten die al een tekstlaag bevatten (gebruikelijk bij digitaal gemaakte PDF's).

Modus Gedrag Wanneer gebruiken
auto OCR alleen op documenten zonder tekstlaag. Standaard. Ideaal voor gemengde invoer: gescande + digitale PDF's.
redo Alle pagina's opnieuw OCR'en, bestaande tekstlagen vervangen. Je ontvangt documenten met slechte OCR-kwaliteit.
force Document rasteriseren en OCR vanaf nul. Vernietigt de originele tekst. Laatste redmiddel. Produceert grotere bestanden met minder scherpe tekst.
off Nooit OCR. PDF's behouden hun ingebedde tekst, afbeeldingen krijgen er geen. Collecties met alleen digitale documenten.

Sinds Paperless-ngx 3.0 hebben archiefkopieën een eigen instelling, PAPERLESS_ARCHIVE_FILE_GENERATION: auto (standaard) maakt een PDF/A-archief voor scans en afbeeldingen, maar niet voor PDF's die al tekst bevatten, always archiveert elk document en never bewaart alleen het origineel. De oude modi skip en skip_noarchive bestaan niet meer: gebruik auto, plus PAPERLESS_ARCHIVE_FILE_GENERATION: never in plaats van skip_noarchive.

Voor de meeste opstellingen is auto de juiste keuze. Het verwerkt zowel gescande als digitale documenten zonder CPU te verspillen aan het herverwerken van al doorzoekbare documenten.

Als je documenten ontvangt van een scanner die zijn eigen (slechte) OCR uitvoert, zet de modus dan op redo. Let op: redo schakelt het rechtzetten van pagina's uit en valt terug van PAPERLESS_OCR_CLEAN: clean-final naar clean.

OCR-uitvoertype

PAPERLESS_OCR_OUTPUT_TYPE: pdfa (de standaard) produceert PDF/A-bestanden, de archiveringsstandaard. Deze zijn zelfstandig en bevatten ingebedde lettertypen. Houd deze instelling aan, tenzij je een specifieke reden hebt om te wijzigen.

Maak na het wijzigen van OCR-instellingen de webserver-container opnieuw aan. Een gewone docker compose restart houdt de oude omgeving, gebruik dus:

docker compose up -d

Bestaande documenten worden niet opnieuw verwerkt. Om een document opnieuw te OCR'en, gebruik de actie «Reprocess» in het menu van het document in de webinterface.

Hoe werkt automatische tagging in Paperless-ngx?

Paperless-ngx ondersteunt zes matching-algoritmen voor tags, correspondenten en documenttypen. Wanneer een document binnenkomt, vergelijkt elke tag de documentinhoud met het eigen patroon. Als het patroon overeenkomt, wordt de tag automatisch toegepast.

Algoritme Hoe het werkt Wanneer gebruiken Voorbeeld
Any Komt overeen als een woord uit het matchveld voorkomt. Brede categorieën. invoice receipt bill
All Komt overeen als alle woorden voorkomen (willekeurige volgorde). Nauwkeurigere matching zonder positieafhankelijkheid. electricity quarterly
Exact Komt exact overeen met de zin in volgorde. Bedrijfsnamen, rekeningnummers. Acme Corp
Regular Expression Volledige regex-patroonmatching. Gestructureerde data: datums, referentienummers, bedragen. Invoice\s+#?\d{4,}
Fuzzy Benadering met configureerbare drempelwaarde. Inconsistente OCR-uitvoer, lichte spelfouten. Stadtwerke (herkent Stadtwenke)
Auto ML-classifier die leert van je handmatige toewijzingen. Na ~50+ handmatig getagde documenten. (leert van je correcties)

Tags met matchingregels aanmaken

Ga in de webinterface naar Manage > Tags en maak een tag aan. Stel het matching-algoritme en het Match-veld in. Enkele praktische voorbeelden:

  • Tag: Invoice, Algoritme: Any, Match: invoice rechnung facture factuur (vangt facturen in meerdere talen)
  • Tag: Bank, Algoritme: Regular Expression, Match: IBAN\s*[A-Z]{2}\d{2} (herkent elk IBAN-nummer)
  • Tag: Medical, Algoritme: All, Match: patient diagnosis (vereist beide woorden)
  • Correspondent: Electric Company, Algoritme: Exact, Match: Springfield Energy Inc

De Auto-classifier trainen

Het Auto-algoritme gebruikt een machine learning-classifier die Paperless-ngx automatisch hertraint. Om hem te trainen:

  1. Tag handmatig minstens 50 documenten verdeeld over je categorieën
  2. Zorg dat deze documenten niet in je inbox staan (de classifier negeert inbox-documenten)
  3. De classifier hertraint volgens een schema (standaard: elk uur via document_create_classifier)
  4. Nieuwe documenten beginnen automatische toewijzingen te ontvangen

Je kunt handmatig hertrainen:

docker compose exec webserver document_create_classifier

De classifier verbetert naarmate je correcties aanbrengt. Elke correctie voedt de volgende trainingscyclus.

Hoe stel ik documentverwerking in voor Paperless-ngx?

Paperless-ngx verwerkt documenten via drie kanalen: handmatige upload via de webinterface, een bewaakte map op schijf en e-mail ophalen via IMAP.

Upload via de webinterface

Sleep bestanden naar de webinterface. Dit werkt direct na de installatie. Ondersteunde formaten: PDF, PNG, JPEG, TIFF en (met Tika ingeschakeld) DOCX, XLSX, ODT en andere kantoorformaten.

Bewaakte map (consume-directory)

De ./consume-directory die in het Compose-bestand is gemount, wordt bewaakt door een inotify-watcher. Plaats een bestand erin en Paperless-ngx pikt het binnen seconden op.

cp /tmp/scan-001.pdf /opt/paperless-ngx/consume/

Het bestand verdwijnt uit de consume-directory zodra de verwerking is voltooid. Om de verwerking per tag te organiseren, schakel subdirectory-tagging in:

PAPERLESS_CONSUMER_RECURSIVE: true
PAPERLESS_CONSUMER_SUBDIRS_AS_TAGS: true

Met deze instelling krijgt een bestand in consume/invoices/scan.pdf automatisch de tag invoices. Subdirectory's die je als root aanmaakt, moeten eigendom worden van UID 1000 (chown -R 1000:1000 /opt/paperless-ngx/consume), anders mislukt de import na het parsen met Permission denied.

E-mailverwerking (IMAP)

E-mailverwerking wordt volledig geconfigureerd in de webinterface onder Manage > Mail. Je voegt mailaccounts en mailregels toe.

Een mailaccount toevoegen:

  1. Ga naar Manage > Mail > Mail Accounts
  2. Vul de IMAP-server, poort (993 voor TLS), gebruikersnaam en wachtwoord in
  3. Stel de te bewaken map in (bijv. INBOX)

Een mailregel toevoegen:

  1. Ga naar Manage > Mail > Mail Rules
  2. Selecteer het mailaccount
  3. Kies wat te verwerken: alleen bijlagen of de volledige e-mail als PDF
  4. Stel een actie in voor verwerkte e-mails: markeer als gelezen, verplaats naar een map of verwijder
  5. Optioneel wijs een tag, correspondent of documenttype toe

Typische opzet: stuur documenten door naar een specifiek e-mailadres (bijv. scan@jouwdomein.nl), configureer Paperless-ngx om die inbox te bewaken en bijlagen te verwerken. De originelen worden na verwerking verplaatst naar een IMAP-map «Archived».

Hoe organiseer ik opslagpaden en bestandsnamen?

Paperless-ngx slaat documenten op twee plaatsen op: het media-volume bevat de bestanden op schijf, terwijl PostgreSQL de metadata beheert. De variabele PAPERLESS_FILENAME_FORMAT bepaalt hoe gearchiveerde bestanden worden benoemd in de media-directory.

Het Compose-bestand hierboven gebruikt:

PAPERLESS_FILENAME_FORMAT: "{{ created_year }}/{{ correspondent }}/{{ title }}"

Dit creëert een structuur als:

media/documents/archive/
  2026/
    Springfield Energy Inc/
      Electricity Bill January 2026.pdf
    Dr. Smith/
      Lab Results March 2026.pdf

Beschikbare templatevariabelen zijn {{ created_year }}, {{ created_month }}, {{ created_day }}, {{ correspondent }}, {{ document_type }}, {{ title }}, {{ tag_list }} en {{ owner_username }}. De oudere syntaxis met enkele accolades werkt nog, maar logt bij elke start een waarschuwing. Als een variabele leeg is (geen correspondent toegewezen), vervangt Paperless-ngx deze door none.

Na het wijzigen van het bestandsnaamformaat, pas het toe op bestaande documenten:

docker compose exec webserver document_renamer

Wat is de beste backupstrategie voor Paperless-ngx?

Een werkende backup omvat de PostgreSQL-database, de documentbestanden (originelen + archieven + thumbnails) en de Paperless-ngx-metadata (tags, correspondenten, matchingregels). De documentexporter legt dit alles vast in een draagbaar formaat. Combineer het met een databasedump voor snellere database-only restores.

Databasedump

mkdir -p /opt/paperless-ngx/backups
docker compose exec db pg_dump -U paperless paperless | gzip > /opt/paperless-ngx/backups/db-$(date +%Y%m%d).sql.gz

Documentexporter

De exporter maakt een volledige snapshot: documenten, metadata en manifest. Dit is de standaard backupmethode.

docker compose exec webserver document_exporter ../export -c -d

De -c-vlag vergelijkt checksums (exporteert alleen gewijzigde bestanden). De -d-vlag verwijdert bestanden uit de export die niet meer bestaan in Paperless-ngx. Samen houden ze de export-directory als spiegel van de huidige staat.

Automatiseren met cron

Maak een backupscript:

cat > /opt/paperless-ngx/backup.sh << 'SCRIPT'
#!/bin/bash
set -euo pipefail

BACKUP_DIR="/opt/paperless-ngx/backups"
EXPORT_DIR="/opt/paperless-ngx/export"

mkdir -p "$BACKUP_DIR"

# Database dump
docker compose -f /opt/paperless-ngx/docker-compose.yml exec -T db \
  pg_dump -U paperless paperless | gzip > "$BACKUP_DIR/db-$(date +%Y%m%d).sql.gz"

# Document exporter
docker compose -f /opt/paperless-ngx/docker-compose.yml exec -T webserver \
  document_exporter ../export -c -d

# Remove database dumps older than 30 days
find "$BACKUP_DIR" -name "db-*.sql.gz" -mtime +30 -delete

echo "[$(date -Is)] Backup completed" >> "$BACKUP_DIR/backup.log"
SCRIPT

chmod 700 /opt/paperless-ngx/backup.sh

Plan het in met cron (dit behoudt bestaande crontab-items):

(crontab -l 2>/dev/null; echo "0 3 * * * /opt/paperless-ngx/backup.sh") | crontab -

Dit voegt een nachtelijke taak toe om 03:00 uur.

Offsite-synchronisatie

De export-directory en databasedumps moeten de server verlaten. Gebruik rsync of rclone om ze naar een tweede locatie te sturen. Voor een S3-compatibel doel:

rclone sync /opt/paperless-ngx/export remote:paperless-backup/export
rclone sync /opt/paperless-ngx/backups remote:paperless-backup/db-dumps

Voor een andere server via SSH:

rsync -az --delete /opt/paperless-ngx/export/ backup-server:/backups/paperless/export/
rsync -az /opt/paperless-ngx/backups/ backup-server:/backups/paperless/db-dumps/

Voor een diepere duik in Docker volume-backupstrategieën, zie onze handleiding voor Docker-volume-backupstrategieën.

Hoe herstel ik een Paperless-ngx-backup?

Herstellen vereist een schone Paperless-ngx-installatie. Start de stack en importeer dan.

Alleen database herstellen (sneller, bij databasecorruptie of migratie). Stop eerst de webserver en maak een lege database aan, anders bestaan alle tabellen al en herstelt de dump niets:

cd /opt/paperless-ngx
docker compose stop webserver
docker compose exec -T db dropdb -U paperless paperless
docker compose exec -T db createdb -U paperless paperless
gunzip < /opt/paperless-ngx/backups/db-20260320.sql.gz | \
  docker compose exec -T db psql -U paperless paperless
docker compose start webserver

Volledig herstel vanuit de exporter (documenten, tags, correspondenten, alles):

docker compose exec webserver document_importer ../export

Voer de importer uit tegen een lege database. Het herstelt alle metadata en koppelt bestanden uit de export-directory.

Test je herstel regelmatig. Een backup die je nooit hebt hersteld, is geen backup.

Hoe beveilig ik de Paperless-ngx-containers extra?

Het Compose-bestand hierboven dekt al de basis: geheime bestanden in plaats van wachtwoorden in platte tekst, poortbinding op localhost en gebruikersmapping. Hier volgen aanvullende beveiligingsmaatregelen.

Onnodige capabilities verwijderen

Voeg beveiligingsopties toe aan de webserver-service:

webserver:
  # ... bestaande configuratie ...
  security_opt:
    - no-new-privileges:true

Dit voorkomt dat het containerproces extra privileges verkrijgt via setuid-binaries.

Resourcelimieten instellen

Voorkom dat een op hol geslagen OCR-proces alle serverresources verbruikt:

webserver:
  # ... bestaande configuratie ...
  deploy:
    resources:
      limits:
        memory: 2g
        cpus: "2.0"
      reservations:
        memory: 512m

Voor meer over resourcelimieten, zie onze handleiding over Docker Compose-resourcelimieten.

Versie-informatie verbergen

Configureer je reverse proxy om de Server-header te verwijderen. Met Nginx:

server_tokens off;

Paperless-ngx stuurt bij elk antwoord Server: granian mee en voegt een X-Version-header (bijvoorbeeld 3.2.1) toe aan API-antwoorden voor ingelogde gebruikers.

Hoe werk ik Paperless-ngx bij?

Pull de nieuwste images en maak de containers opnieuw aan. De Paperless-ngx-image voert databasemigraties automatisch uit bij het starten.

cd /opt/paperless-ngx
docker compose pull
docker compose up -d

Controleer na de update de logs op migratie-uitvoer:

docker compose logs webserver --tail 30

Zoek naar regels als Applying documents.XXXX_migration_name... OK. Als migraties mislukken, stopt de container. Raadpleeg de release notes voordat je grote versie-upgrades uitvoert. De overstap van 2.x naar 3.x werkt alleen vanaf 2.20.15 en vraagt configuratiewijzigingen (PAPERLESS_DBENGINE, de nieuwe OCR-modi): lees eerst de v3-migratiegids.

Voer altijd je backupscript uit vóór het updaten.

Gaat er iets mis?

Container blijft unhealthy: Bekijk de logs met docker compose logs <service> --tail 50. Veelvoorkomende oorzaken: PostgreSQL-wachtwoord komt niet overeen (genereer .db_password opnieuw en maak het databasevolume opnieuw aan), Redis-verbinding geweigerd (broker nog niet gestart).

OCR produceert onleesbare tekst: Verkeerde taal ingesteld. Controleer of PAPERLESS_OCR_LANGUAGE overeenkomt met je documenten. Voor meertalige documenten voeg je alle relevante taalcodes toe, gescheiden door +.

Documenten verschijnen niet na upload: Controleer het consumer-log:

docker compose logs webserver --tail 50 | grep -i consumer

Veelvoorkomende oorzaak: rechtenprobleem. De consume-directory moet beschrijfbaar zijn door UID 1000 (of de waarde van USERMAP_UID):

chown -R 1000:1000 /opt/paperless-ngx/consume

Automatische tagging werkt niet: De classifier heeft minstens ~50 handmatig getagde documenten nodig. Controleer of de classifier is getraind:

docker compose exec webserver document_create_classifier

Schijfruimte groeit snel: Controleer hoeveel ruimte originelen en archiefkopieën innemen en start daarna de sanity checker, die ook verweesde bestanden in de media-directory meldt:

docker compose exec webserver du -sh /usr/src/paperless/media/documents/originals /usr/src/paperless/media/documents/archive
docker compose exec webserver document_sanity_checker

Controleer ook je OCR-modus. De force-modus maakt aanzienlijk grotere archiefbestanden dan auto.

E-mailverwerking haalt geen mail op: Controleer de IMAP-inloggegevens in de webinterface. Activeer handmatig ophalen om fouten te zien:

docker compose exec webserver mail_fetcher

Voor meer zelfhosting-handleidingen, zie onze Immich-handleiding voor fotobeheer op dezelfde stack.

Paperless-ngx zelf hosten op een VPS met Docker Compose