Pendant des années, j’ai conservé mes relevés bancaires, mes factures EDF et mes documents administratifs dans une boîte à chaussures. Deux boîtes à chaussures, à vrai dire. Le jour où je n’ai plus retrouvé une attestation d’assurance demandée par mail 48 heures plus tôt, j’ai décidé que c’était fini. J’avais déjà Paperless-ngx sur la liste des services à déployer sur heighliner – le déménagement dans la boîte à chaussures numérique a pris deux soirées.
Contexte et contraintes
Le besoin est simple : ingérer des documents scannés ou reçus en PDF, les indexer par OCR, et les retrouver en quelques secondes via une recherche full-text. Pas besoin d’une GED d’entreprise – juste quelque chose de fiable qui tourne sans supervision.
L’infrastructure cible : LXC 111 sur heighliner (Proxmox VE 8.3), Debian 12, 2 vCPU, 2 GB RAM, Docker installé à l’intérieur. Le stockage des documents originaux passe par le NAS Synology DS414 via NFS – le partage est monté à /mnt/synology/paperless dans le LXC, et c’est depuis là que le dossier de consommation est exposé.
La stack retenue :
- Paperless-ngx 2.x – le service principal, OCR + indexation + interface web
- Gotenberg – conversion DOCX, PPTX, XLSX en PDF avant ingestion
- Tika – extraction de texte depuis les formats Office sans passer par Gotenberg
- Redis – broker de tâches pour les workers OCR
- PostgreSQL 15 – base de données principale (préféré à SQLite au-delà de quelques centaines de documents)
Montage NFS et structure de répertoires
Avant de toucher à Docker, je configure le montage NFS dans /etc/fstab du LXC :
192.168.40.10:/volume1/paperless /mnt/synology/paperless nfs defaults,_netdev,rw 0 0
Le VLAN Stockage (40) est celui utilisé pour joindre le DS414 depuis les LXC et VMs. L’adresse 192.168.40.10 est l’IP fixe du NAS sur ce segment.
Structure locale dans le LXC :
/opt/paperless/
├── consume/ -> /mnt/synology/paperless/consume (symlink ou bind mount)
├── data/ -> /mnt/synology/paperless/data
├── media/ -> /mnt/synology/paperless/media
├── export/ -> /mnt/synology/paperless/export
└── docker-compose.yml
Le répertoire consume/ est surveillé en continu par Paperless. Tout fichier déposé là est ingéré et supprimé après traitement. Ne jamais y poser un fichier qui n’est pas destiné à l’import.
Docker Compose
version: "3.9"
services:
broker:
image: redis:7
restart: unless-stopped
volumes:
- redisdata:/data
db:
image: postgres:15
restart: unless-stopped
environment:
POSTGRES_DB: paperless
POSTGRES_USER: paperless
POSTGRES_PASSWORD_FILE: /run/secrets/pg_password
volumes:
- pgdata:/var/lib/postgresql/data
secrets:
- pg_password
gotenberg:
image: gotenberg/gotenberg:8
restart: unless-stopped
command:
- gotenberg
- --chromium-disable-javascript=true
- --chromium-allow-list=file:///tmp/.*
tika:
image: ghcr.io/paperless-ngx/tika:latest
restart: unless-stopped
webserver:
image: ghcr.io/paperless-ngx/paperless-ngx:2
restart: unless-stopped
depends_on:
- db
- broker
- gotenberg
- tika
ports:
- "8010:8000"
volumes:
- /opt/paperless/data:/usr/src/paperless/data
- /opt/paperless/media:/usr/src/paperless/media
- /opt/paperless/export:/usr/src/paperless/export
- /opt/paperless/consume:/usr/src/paperless/consume
environment:
PAPERLESS_REDIS: redis://broker:6379
PAPERLESS_DBHOST: db
PAPERLESS_DBNAME: paperless
PAPERLESS_DBUSER: paperless
PAPERLESS_DBPASS_FILE: /run/secrets/pg_password
PAPERLESS_TIKA_ENABLED: 1
PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
PAPERLESS_TIKA_ENDPOINT: http://tika:9998
PAPERLESS_OCR_LANGUAGE: fra+eng
PAPERLESS_OCR_MODE: skip_noarchive
PAPERLESS_TIME_ZONE: Europe/Paris
PAPERLESS_FILENAME_FORMAT: "{created_year}/{correspondent}/{title}"
USERMAP_UID: 1000
USERMAP_GID: 1000
secrets:
- pg_password
volumes:
redisdata:
pgdata:
secrets:
pg_password:
file: ./secrets/pg_password.txt
PAPERLESS_OCR_LANGUAGE: fra+eng charge les modèles Tesseract pour le français et l’anglais. PAPERLESS_OCR_MODE: skip_noarchive évite de ré-OCRiser les PDF qui ont déjà une couche texte – gain de temps significatif sur les factures reçues directement en PDF depuis les portails en ligne.
Lancement :
docker compose -f /opt/paperless/docker-compose.yml up -d
docker compose -f /opt/paperless/docker-compose.yml exec webserver createsuperuser
L’interface web est disponible sur http://192.168.30.111:8010 depuis le VLAN Serveurs. Traefik sur LXC 103 expose le service via HTTPS avec un certificat Let’s Encrypt – paperless.arewel.com pointe dessus.
Types de documents et correspondants
Avant d’importer quoi que ce soit, je structure les métadonnées depuis l’interface Settings :
Types de documents créés :
Correspondants créés :
Ces entrées sont ensuite utilisées par les règles de correspondance automatiques.
Règles de correspondance automatiques
C’est la partie la plus utile – et celle qui demande le plus de tâtonnements. Paperless-ngx peut analyser le texte OCRisé d’un document et appliquer automatiquement des métadonnées si certaines conditions sont remplies.
Configuration depuis Settings > Matching Algorithms :
Règle « EDF »
EDF OU Électricité de FranceRègle « Relevé bancaire »
IBAN ET (débit OU crédit OU solde)Règle « Fiscal »
Déclaration ET impôts (OU Direction générale des finances)Règle « Santé »
Sécurité sociale OU Assurance maladie OU ordonnanceCes règles fonctionnent en post-traitement OCR. Elles ne sont pas infaillibles – un document mal OCRisé passera au travers – mais sur mes 340 documents importés, environ 280 ont été classés automatiquement sans intervention manuelle.
Commence par importer une dizaine de documents manuellement, observe les textes OCRisés dans l’interface (onglet « Content » d’un document), et construis les règles sur ce que Tesseract produit réellement – pas sur ce que tu penses que le texte devrait être.
Workflow d’import
Deux méthodes utilisées en parallèle :
Import via le scanner Brother (ADF)
Mon imprimante Brother avec chargeur automatique génère des PDF à 300 DPI directement. Je configure un dossier de numérisation réseau sur le DS414 via SMB, puis un script cron dans le LXC copie les nouveaux fichiers vers /opt/paperless/consume/ toutes les 5 minutes :
#!/bin/bash
rsync -av /mnt/synology/scan-inbox/ /opt/paperless/consume/
--remove-source-files
--include="*.pdf"
--exclude="*"
Paperless détecte l’arrivée du fichier, lance l’OCR dans les secondes qui suivent, et supprime le fichier source après ingestion réussie.
Import manuel de l’existant
Pour la boîte à chaussures historique, j’ai scanné les documents un par un avec l’ADF puis déposé les PDFs dans le dossier consume. 340 documents sur deux soirées, en triant physiquement au fur et à mesure.
Ce qui a coincé : l’OCR sur les vieux scans
Le premier lot de documents que j’ai tenté d’importer était une pile de factures EDF des années 2015-2019, scannées à l’époque avec un scanner à plat réglé par défaut à 100 DPI. Résultat dans Paperless : du texte illisible, des caractères aléatoires, aucune règle de correspondance déclenchée.
Tesseract a besoin d’un minimum de 200 DPI pour produire un OCR exploitable – 300 DPI est la valeur recommandée. En dessous, le modèle de reconnaissance de caractères ne dispose pas de suffisamment d’information pour distinguer un l d’un 1 ou un O d’un 0.
J’ai tenté une amélioration par prétraitement avec ImageMagick pour remonter la résolution artificielle à 300 DPI :
convert -density 300 -units PixelsPerInch input.pdf output-upscaled.pdf
Sur certains documents, ça améliore marginalement le résultat. Sur d’autres, non. La conclusion pratique : les documents scannés avant 2020 avec du matériel grand public restent partiellement illisibles par OCR. Je les ai tagués manuellement ocr-faible et j’ai accepté la limite.
Les scans récents depuis l’ADF Brother à 300 DPI, eux, donnent des résultats parfaits – Tesseract reconnaît le texte imprimé avec un taux d’erreur quasiment nul sur des documents typiques (polices sans-serif, fond blanc).
Recherche full-text et API REST
L’indexeur Whoosh intégré à Paperless-ngx construit un index full-text sur l’ensemble des contenus OCRisés. La recherche dans l’interface web est quasi instantanée même avec 340 documents.
Quelques requêtes types que j’utilise :
EDF 2024 – toutes les factures EDF de l’annéeIBAN solde – relevés bancairestype:Santé date:[2025 TO 2026] – documents médicaux sur les 18 derniers moisL’API REST est disponible sur /api/ avec authentification par token. Je l’utilise depuis une automatisation Home Assistant pour vérifier si une facture donnée a été importée ce mois-ci. Exemple :
curl -H "Authorization: Token "
"https://paperless.arewel.com/api/documents/?correspondent__name=EDF&created__date__gte=2026-01-01"
Le token d’API Paperless donne un accès complet à tous les documents. Ne le stocker ni dans un fichier de config en clair ni dans un dépôt Git.
Résultats mesurés
Après deux soirées d’import (dont une consacrée à scanner physiquement les vieilles factures) :
ocr-faibleLa RAM du LXC reste confortable : en charge normale (aucun document en cours d’import), les conteneurs consomment environ 600 MB au total. Pendant l’OCR d’un PDF de 10 pages, ça monte à 900 MB – dans les limites allouées.
Sauvegarde
Paperless dispose d’une commande d’export qui produit un ZIP contenant les documents originaux, la base de données et les thumbnails :
docker compose -f /opt/paperless/docker-compose.yml exec webserver
document_exporter /usr/src/paperless/export --use-filename-format
Ce répertoire /opt/paperless/export/ est inclus dans le job Proxmox Backup Server qui sauvegarde le LXC 111 chaque nuit. En plus, une copie hebdomadaire du répertoire data/ et media/ va directement sur le DS414 via un script rsync – au cas où PBS serait lui-même inaccessible.
L’étape suivante est d’automatiser l’export ZIP de Paperless dans un job cron et de le faire versionner sur le NAS – pour avoir un historique des états de la base, indépendant de la sauvegarde LXC complète.
slug: paperless-ngx-gestion-documents
meta: Paperless-ngx 2.x sur LXC Proxmox : OCR Tesseract fr+en, dossier consume NFS Synology, règles automatiques, 340 documents indexés en deux soirées. (~154 chars)
tags: paperless-ngx, OCR, GED, Proxmox, Docker, Tesseract, NAS, Synology, homelab