Banner Paperless-ngx: documente de hartie scanate transformate in fisiere cautabile si etichetate
Self-hosting

Paperless-ngx cu Docker Compose: OCR, etichete si import automat

Undeva prin casa sau prin birou exista un sertar plin cu hartii. Facturi la curent si internet, contractul de inchiriere, polita RCA, certificate de garantie care se decoloreaza putin in fiecare vara si scrisoarea de la ANAF despre care erai convins ca n-o sa-ti mai trebuiasca niciodata. Ca sa gasesti o anumita pagina iti trebuie douazeci de minute si putin noroc, iar daca sertarul ia apa, ai pierdut tot. Paperless-ngx transforma sertarul intr-o arhiva in care poti cauta: scanezi o pagina sau trimiti un email, aplicatia citeste textul cu OCR, isi da seama cine l-a trimis si ce fel de document e, il eticheteaza si il claseaza. Peste trei ani scrii “garantie frigider” si PDF-ul apare pe ecran in mai putin de o secunda.

In ghidul asta instalam Paperless-ngx cu Docker Compose pe un VPS proaspat, il invatam sa citeasca si romana, si engleza, il punem sa importe automat documente dintr-un folder si dintr-o casuta de email, si construim reguli de potrivire astfel incat facturile si contractele sa se claseze singure. Totul ruleaza pe serverul tau, fara abonament si fara ca un tert sa-ti citeasca facturile.

Ce este, mai exact, Paperless-ngx

Paperless-ngx este un sistem gratuit si open source de management al documentelor. Proiectul e pe github.com/paperless-ngx/paperless-ngx , sub licenta GPL-3.0, iar documentatia oficiala e pe docs.paperless-ngx.com . E succesorul intretinut de comunitate al proiectelor Paperless si Paperless-ng si, in acest moment, cel mai activ proiect open source din zona asta.

Ii dai un document (un PDF, o poza facuta cu telefonul, o imagine scanata, iar cu un add-on optional chiar si fisiere Word, Excel sau emailuri) si face patru lucruri:

  1. Il citeste cu OCR. OCR (recunoastere optica a caracterelor) este procesul prin care pixelii unei pagini scanate devin text real, in care un calculator poate cauta. Paperless-ngx foloseste motorul Tesseract, prin intermediul unui utilitar numit OCRmyPDF.
  2. Pastreaza doua copii. Fisierul original ramane neatins, iar langa el Paperless creeaza o “versiune de arhiva”: un PDF/A cu un strat de text invizibil, ca sa poti selecta si copia text chiar si dintr-o poza stramba facuta cu telefonul.
  3. Il clasifica. Ii atribuie un corespondent, un tip de document, etichete si o cale de stocare, fie dupa reguli scrise de tine, fie cu un mic model de machine learning care invata din corecturile tale.
  4. Il indexeaza pentru cautare full-text, deci cauti in interiorul fiecarui document, nu doar in numele fisierelor.

Cativa termeni pe care ii vom folosi pe tot parcursul ghidului:

  • Corespondent: de la cine vine sau catre cine merge documentul: Enel, Digi, proprietarul apartamentului, contabilul.
  • Tip de document: ce fel de document e: factura, contract, chitanta, fluturas de salariu.
  • Eticheta (tag): o eticheta libera. Un document poate avea oricate: “de platit”, “masina”, “2026”, “taxe”.
  • Cale de stocare (storage path): structura de foldere pe care Paperless o foloseste pentru fisiere pe disc.
  • Container: o aplicatie impachetata cu tot ce ii trebuie, izolata de restul sistemului. Docker ruleaza containere, iar Docker Compose porneste mai multe containere impreuna, dintr-un singur fisier.
  • Volum: spatiu de stocare pe care Docker il tine in afara containerului, ca datele sa supravietuiasca actualizarilor si restarturilor.
  • Port: o “usa” numerotata a serverului, pe care asculta un program: 22 pentru SSH, 80 pentru HTTP, 443 pentru HTTPS.
  • Reverse proxy: un server web pus in fata aplicatiilor, care se ocupa de certificatele HTTPS si trimite fiecare cerere catre aplicatia potrivita.

Cum se leaga piesele intre ele

Paperless-ngx nu e un singur program, ci un mic stack. Containerul principal ruleaza interfata web, consumatorul de documente si procesele de OCR. PostgreSQL stocheaza metadatele (titluri, etichete, utilizatori, reguli), iar Redis e o coada de sarcini, ca OCR-ul greu sa ruleze in fundal in timp ce interfata ramane rapida. In fata punem Caddy pentru HTTPS automat, iar firewall-ul UFW se asigura ca din internet se poate ajunge doar la SSH, HTTP si HTTPS.

Paperless-ngx pe un VPS DreamServerFirewall UFW: 22, 80, 443 deschiseBrowser / telefonHTTPS pe 443Laptop / scannerrsync in ./consumeEmail facturiIMAP 993, iesireCaddy reverse proxycertificate HTTPS automateContainer Paperless-ngxInterfata web + API :8000Consumator + OCR (ron+eng)Citire email la 10 minReguli + clasificatorsarcini in fundal prin RedisPostgreSQL 17metadate, useri, reguliRedis 7coada de sarcinivolume data + mediaoriginale + arhiva PDF/Afolderul ./exportbackup, copie offsite127.0.0.1:8000Doar porturile 22, 80 si 443 sunt accesibile. Paperless asculta doar pe 127.0.0.1.
Stack-ul pe care il construim: documentele vin prin browser, printr-un folder supravegheat sau prin email, iar totul sta in spatele firewall-ului si al lui Caddy.

De ce ai nevoie

  • Un VPS cu Debian 13 sau Ubuntu 24.04, minim 2 vCPU si 2 GB RAM (4 GB daca adaugi convertoarele optionale pentru Office si email sau scanezi mult deodata).
  • Spatiu pe disc: o pagina scanata ocupa de obicei in jur de 100-300 KB, iar Paperless pastreaza si originalul, si copia de arhiva, deci cateva mii de documente incap linistit in 20-40 GB.
  • Un utilizator cu sudo si acces SSH (nu root).
  • Un domeniu sau subdomeniu, de exemplu docs.firma-ta.ro, cu o inregistrare A catre IP-ul VPS-ului.
  • Optional, o casuta de email dedicata facturilor, cu acces IMAP.
  • Un scanner, o multifunctionala cu scan-to-email sau pur si simplu camera telefonului.

O nota despre virtualizare: Docker merge fara surprize pe un VPS KVM. Intr-un container LXC neprivilegiat, Docker are nevoie de optiunea “nesting” activata, iar unele lucruri (un fisier de swap, incarcarea modulelor de firewall din kernel) pot fi restrictionate. Daca docker run hello-world esueaza pe un plan LXC, cere suportului nostru sa verifice nesting-ul sau alege un plan KVM.

Cata memorie RAM foloseste Paperless-ngx?

In cea mai mare parte a timpului, Paperless sta linistit. Momentul greu este OCR-ul: cat proceseaza o scanare cu multe pagini, containerul principal poate trece scurt peste un gigabyte. De aceea, pe un VPS mic, il limitam la un singur worker. Cifrele de mai jos sunt valori aproximative masurate pe un VPS cu 2 vCPU; la tine pot varia in functie de documente si setari.

RAM aproximativ per container (VPS cu 2 vCPU)040080012001600Consum RAM in MB (aproximativ)ContainerRedis 7~15 MBPostgreSQL 17~60 MBPaperless (in repaus)~550 MBPaperless (varf OCR)~1300 MBGotenberg (optional)~150 MBTika (optional)~350 MBValorile variaza cu documentele si setarile. Planifica 2 GB RAM, 4 GB cu Tika.
Consum aproximativ de memorie: singurul varf real este OCR-ul, deci 2 GB RAM ajung pentru stack-ul de baza cu un singur worker.

Toata procedura dintr-o privire

Parcurgem zece pasi numerotati. Primii sase instaleaza si securizeaza stack-ul, urmatorii trei automatizeaza clasarea, iar ultimul iti protejeaza arhiva.

Instalarea Paperless-ngx in 10 pasi1Server +firewall2InstalareDocker3Folder +secrete4Fisierulcompose5Pornire +cont admin6HTTPS cuCaddy7Import dinfolder8Import dinemail9Etichete +reguli10Backup(exporter)Instalare (1-6)Automatizare (7-9)Protectie (10)
Pasii 1-10 din acest ghid: pasii 1-6 instaleaza stack-ul, pasii 7-9 automatizeaza clasarea, pasul 10 protejeaza arhiva.

Pasul 1: Pregatim serverul si firewall-ul

Intra prin SSH cu utilizatorul tau cu sudo si actualizeaza sistemul. Instalam si cateva unelte de care avem nevoie mai tarziu: ufw (firewall-ul), curl, certificatele CA si openssl (pentru generat parole).

sudo apt update && sudo apt full-upgrade -y
sudo apt install -y ufw curl ca-certificates openssl

Pe Ubuntu 24.04, ufw vine deja instalat, dar inactiv; pe Debian 13 nu e instalat implicit, asa ca linia de mai sus rezolva situatia pe ambele. Acum deschidem doar cele trei porturi de care avem nevoie. Permite SSH inainte sa activezi firewall-ul, altfel te blochezi singur pe dinafara (daca ai mutat SSH pe alt port, pune acel numar in loc de 22).

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status

ufw enable cere confirmare; scrie y. La status trebuie sa vezi Status: active si cele trei reguli. Portul 80 e necesar pentru ca prin el Caddy obtine certificatul HTTPS. Intr-un container LXC neprivilegiat, ufw enable poate esua pentru ca containerul nu poate incarca module de firewall in kernel; in cazul asta intreaba suportul cum se face filtrarea traficului pe planul tau.

Verifica daca actualizarea cere un restart. Ubuntu creeaza fisierul /var/run/reboot-required atunci cand e nevoie; Debian nu creeaza implicit acest fisier, asa ca pe Debian da pur si simplu restart daca actualizarea a instalat un pachet linux-image nou.

[ -f /var/run/reboot-required ] && echo "E nevoie de restart" || echo "Nu exista semnal de restart"
sudo reboot

Pasul 2: Instalam Docker si Docker Compose

Instalam Docker din repository-ul oficial Docker, care ne da motorul actual si plugin-ul Compose v2 (comanda docker compose, cu spatiu). Comenzile de mai jos merg si pe Debian, si pe Ubuntu, pentru ca citesc numele distributiei din /etc/os-release.

sudo install -m 0755 -d /etc/apt/keyrings
. /etc/os-release
sudo curl -fsSL "https://download.docker.com/linux/${ID}/gpg" -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/${ID} ${VERSION_CODENAME} stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo usermod -aG docker "$USER"

Ultima linie iti adauga utilizatorul in grupul docker, ca sa nu mai scrii sudo inaintea fiecarei comenzi Docker. Iesi din sesiune si intra din nou ca schimbarea de grup sa aiba efect, apoi testeaza:

docker run --rm hello-world
docker compose version

Ar trebui sa vezi mesajul “Hello from Docker!” si ceva de genul Docker Compose version v2.x.x. Retine ca apartenenta la grupul docker echivaleaza cu acces de root, deci adauga acolo doar utilizatori de incredere.

Pasul 3: Cream folderul proiectului si secretele

Tinem totul in /opt/paperless. Inauntru, consume este “tava de intrare” pe care Paperless o supravegheaza, iar in export vor ajunge backup-urile.

sudo mkdir -p /opt/paperless
sudo chown "$USER":"$USER" /opt/paperless
cd /opt/paperless
mkdir -p consume export
cat > .env <<EOF
POSTGRES_PASSWORD=$(openssl rand -hex 24)
PAPERLESS_SECRET_KEY=$(openssl rand -hex 48)
EOF
chmod 600 .env
id -u; id -g

Fisierul .env contine acum o parola aleatorie pentru baza de date si o cheie secreta aleatorie, pe care Paperless o foloseste ca sa semneze sesiunile. Docker Compose citeste automat .env si inlocuieste valorile in fisierul compose, deci secretele nu apar niciodata in YAML. Ultima comanda afiseaza ID-ul utilizatorului si al grupului, de obicei 1000 si 1000. Noteaza-le: Paperless va rula cu aceleasi ID-uri, ca fisierele din consume si export sa ramana ale tale.

Pasul 4: Scriem fisierul paperless-ngx docker compose

Creeaza /opt/paperless/compose.yaml cu nano compose.yaml si lipeste continutul de mai jos. Inlocuieste docs.firma-ta.ro cu subdomeniul tau real si, daca id -u a afisat altceva decat 1000, ajusteaza USERMAP_UID si USERMAP_GID.

services:
  broker:
    image: docker.io/library/redis:7
    restart: unless-stopped
    volumes:
      - redisdata:/data

  db:
    image: docker.io/library/postgres:17
    restart: unless-stopped
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: paperless
      POSTGRES_USER: paperless
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}

  webserver:
    image: ghcr.io/paperless-ngx/paperless-ngx:2.18
    restart: unless-stopped
    depends_on:
      - db
      - broker
    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_DBHOST: db
      PAPERLESS_DBPASS: ${POSTGRES_PASSWORD}
      PAPERLESS_SECRET_KEY: ${PAPERLESS_SECRET_KEY}
      PAPERLESS_URL: https://docs.firma-ta.ro
      PAPERLESS_TIME_ZONE: Europe/Bucharest
      PAPERLESS_OCR_LANGUAGES: ron
      PAPERLESS_OCR_LANGUAGE: ron+eng
      PAPERLESS_TASK_WORKERS: "1"
      PAPERLESS_THREADS_PER_WORKER: "2"
      PAPERLESS_CONSUMER_RECURSIVE: "true"
      PAPERLESS_CONSUMER_SUBDIRS_AS_TAGS: "true"
      USERMAP_UID: "1000"
      USERMAP_GID: "1000"

volumes:
  data:
  media:
  pgdata:
  redisdata:

Ce fac liniile importante:

  • Tag-urile imaginilor. Fixam Redis la versiunea majora 7 si PostgreSQL la 17. Fixarea PostgreSQL conteaza mult: trecerea la o versiune majora noua (de la 17 la 18) cere dump si restore, iar imaginile PostgreSQL mai noi au schimbat si locul in care tin datele, deci nu sari niciodata o versiune majora din greseala. Pentru Paperless-ngx am fixat linia 2.18, actuala cand am scris ghidul; verifica pagina de release-uri si foloseste versiunea curenta. Cu :latest e mai simplu, dar un banal docker compose pull iti poate aduce o actualizare majora pe care n-ai planificat-o.
  • 127.0.0.1:8000:8000 publica interfata web doar pe adresa locala (loopback) a serverului. Asta e esential: Docker isi scrie propriile reguli de firewall care ocolesc UFW, deci un simplu 8000:8000 ar expune Paperless intregului internet, pe HTTP necriptat, indiferent ce spune UFW. Caddy va ajunge la el local.
  • PAPERLESS_URL trebuie sa fie exact adresa pe care o folosesti in browser, altfel login-ul esueaza cu erori CSRF.
  • PAPERLESS_OCR_LANGUAGES: ron instaleaza pachetul Tesseract pentru romana la pornirea containerului (imaginea vine cu engleza, germana, franceza, italiana si spaniola). PAPERLESS_OCR_LANGUAGE: ron+eng ii spune OCR-ului sa se astepte la ambele limbi, deci diacriticele din facturile romanesti si contractele in engleza sunt recunoscute corect.
  • Worker-i si thread-uri: un singur worker cu doua thread-uri impiedica OCR-ul sa manance toata memoria pe un VPS de 2 GB. Pe o masina cu 4 vCPU si 8 GB poti creste la 2 worker-i.
  • Consumator recursiv, cu subfoldere ca etichete: un fisier pus in consume/facturi/ primeste automat eticheta facturi.

Pasul 5: Pornim Paperless-ngx si cream contul de admin

Descarcam imaginile si pornim stack-ul in fundal:

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

docker compose ps ar trebui sa listeze trei servicii, toate running (webserver-ul poate arata health: starting timp de un minut). Prima pornire dureaza intre unul si trei minute, pentru ca Paperless instaleaza pachetul de limba romana si creeaza tabelele in baza de date. Urmareste log-urile si apasa Ctrl+C cand ai terminat:

docker compose logs -f webserver

Cand vezi o linie care spune ca consumatorul foloseste inotify ca sa supravegheze /usr/src/paperless/consume, aplicatia e gata. Acum cream contul de administrator. Comanda porneste un container temporar, cere un nume de utilizator, un email optional si parola de doua ori, si se termina cu Superuser created successfully.

docker compose run --rm webserver createsuperuser

O verificare rapida, locala, ca serverul web raspunde (te astepti la o linie de tipul HTTP/1.1 302 Found, adica o redirectionare catre pagina de login):

curl -sI http://127.0.0.1:8000 | head -n 1

Pasul 6: Punem Paperless-ngx in spatele HTTPS cu Caddy

Caddy este un server web care obtine si reinnoieste singur certificatele Let’s Encrypt. Il gasesti in repository-urile oficiale atat pe Debian 13, cat si pe Ubuntu 24.04 (pe Ubuntu e in componenta “universe”, activata implicit). Asigura-te ca inregistrarea DNS de tip A indica deja spre VPS, apoi:

sudo apt install -y caddy
sudo tee /etc/caddy/Caddyfile > /dev/null <<'EOF'
docs.firma-ta.ro {
    encode gzip
    reverse_proxy 127.0.0.1:8000
}
EOF
sudo systemctl reload caddy
sudo journalctl -u caddy -n 30 --no-pager

Inlocuieste docs.firma-ta.ro cu subdomeniul tau. In cateva secunde, jurnalul ar trebui sa spuna ca certificatul a fost obtinut cu succes. Deschide https://docs.firma-ta.ro in browser, autentifica-te cu contul de admin de la pasul 5 si vei vedea dashboard-ul gol. Trage un PDF in pagina: se incarca, apare o notificare de progres, iar dupa cateva secunde documentul apare in lista, cu textul recunoscut.

Pasul 7: Import automat din folder

Upload-ul din browser e bun pentru un fisier. Pentru restul folosim folderul consume: tot ce ajunge in /opt/paperless/consume este importat, trecut prin OCR si apoi sters din folder. Datorita setarilor de la pasul 4, subfolderele devin etichete.

De pe laptop (Linux, macOS sau Windows cu WSL), copiaza fisierele cu rsync prin SSH:

rsync -av --remove-source-files ~/de-trimis/ user@docs.firma-ta.ro:/opt/paperless/consume/

Preferam rsync in locul lui scp pentru ca scrie intr-un fisier temporar si il redenumeste abia la final, asa ca Paperless nu prinde niciodata un PDF copiat pe jumatate. Optiunea --remove-source-files sterge fiecare fisier din folderul local de-trimis dupa transferul reusit, ca urmatoarea rulare sa nu trimita duplicate; foloseste pentru asta un folder dedicat de “iesire”, nu singura copie a scanarilor tale. Daca iti faci local ~/de-trimis/facturi/ si ~/de-trimis/contracte/, documentele ajung cu etichetele facturi si contracte.

Urmareste importul in timp real pe server:

cd /opt/paperless
docker compose logs -f webserver

Vei vedea o linie despre preluarea fisierului si, dupa cateva secunde pe pagina, un mesaj ca procesarea s-a incheiat. Daca trimiti acelasi fisier de doua ori, Paperless il refuza ca duplicat, exact ce iti doresti.

Ai un scanner de retea? Multe multifunctionale au “scan to email”, care e cea mai simpla varianta: indreapta-l spre casuta de email de la pasul urmator. Firmele mici pot pune aici si PDF-urile facturilor descarcate din e-Factura, la final de luna, toate odata.

Pasul 8: Import automat din email

Aici Paperless devine cu adevarat “fara mana omului”. Creeaza o adresa dedicata, de exemplu facturi@firma-ta.ro, si fie o dai furnizorilor, fie setezi reguli de redirectionare din casuta principala. Paperless se conecteaza prin IMAP (portul 993, conexiune de iesire din VPS, pe care UFW o permite implicit) si importa atasamentele.

In interfata web, deschide Mail din meniul lateral si apasa Add Account (denumirile pot fi traduse daca folosesti interfata in romana):

  • IMAP server: de exemplu mail.firma-ta.ro
  • IMAP port: 993, IMAP security: SSL
  • Username / Password: datele casutei. La furnizorii mari care folosesc autentificare in doi pasi, genereaza o “parola de aplicatie” in loc sa folosesti parola normala.

Apasa Test ca sa confirmi conexiunea, apoi salveaza. Mai departe, apasa Add Rule si seteaza:

  • Account si Folder: contul nou, folderul INBOX.
  • Filtre (optional): dupa expeditor, subiect, continut sau numele atasamentului, de exemplu doar mesajele de la facturare@enel.ro.
  • Maximum age: implicit 30 de zile. Mesajele mai vechi sunt ignorate, deci mareste valoarea daca vrei sa importi si istoricul existent.
  • Consumption scope: “Only process attachments” este alegerea obisnuita.
  • Action: marcheaza ca citit, muta intr-un folder (de exemplu Procesate), marcheaza cu stegulet sau sterge. Mutarea intr-un folder iti tine inbox-ul curat si iti lasa o urma clara.
  • Assign: etichete, tip de document si corespondent. Corespondentul poate fi luat din adresa sau numele expeditorului, ori poti alege unul fix pentru fiecare regula.

Implicit, Paperless verifica emailul la fiecare 10 minute. Regulile se evalueaza in ordine si poti avea mai multe pe acelasi cont: cate una pentru fiecare furnizor important, plus una generala la final.

Pasul 9: Etichete, corespondenti si reguli de potrivire

Acesta e pasul care face ca facturile si contractele sa se claseze singure. Fiecare corespondent, tip de document, eticheta si cale de stocare are un algoritm de potrivire si un camp match. Cand un document este importat, Paperless verifica fiecare regula pe textul obtinut prin OCR si atribuie tot ce se potriveste.

Algoritmii de potrivire

  • None: nu se atribuie niciodata automat.
  • Any word: se potriveste daca apare macar unul dintre cuvinte. digi rcs rds prinde oricare dintre ele.
  • All words: toate cuvintele trebuie sa apara undeva in document.
  • Exact match: trebuie sa apara exact expresia data.
  • Regular expression: un tipar (regex), pentru cand ai nevoie de precizie.
  • Fuzzy word: ca potrivirea exacta, dar tolereaza mici greseli de OCR.
  • Auto: un clasificator de machine learning care invata din documentele pe care le-ai sortat deja manual. Are nevoie de cateva exemple pentru fiecare element si se reantreneaza automat in fiecare ora. Elementele noi au implicit Auto.

Bifeaza Case insensitive la aproape toate regulile. Daca documentele tale contin diacritice, OCR-ul cu ron le va reproduce, deci la regulile bazate pe cuvinte adauga ambele variante de scriere (cu si fara diacritice).

Un set de reguli de pornire

ObiectNumeAlgoritmMatch
CorespondentEnelAny wordenel
CorespondentDigiAny worddigi rcs rds
CorespondentProprietarExact matchpopescu ion
Tip de documentFacturaAny wordfactura invoice
Tip de documentContractRegular expression\bcontract(ul)?\b
Etichetade platitAll wordsfactura scadenta
EtichetamasinaAny wordrca casco itp

Incepe cu reguli explicite, apoi lasa Auto sa preia. Un tipar care merge bine: creeaza corespondenti cu reguli explicite pentru cei mai frecventi zece expeditori, lasa restul pe Auto si corecteaza greselile cand verifici documentele. Fiecare corectura imbunatateste clasificatorul.

Creeaza si o eticheta numita Inbox si bifeaza in setarile ei Inbox tag. Paperless o adauga la fiecare document nou, asa ca obtii o coada de verificare: o data pe saptamana deschizi vizualizarea Inbox, verifici atribuirile si scoti eticheta.

Workflow-uri pentru tot restul

Pentru logica de tip altceva decat “textul contine X”, foloseste Workflows (din meniul lateral). Un workflow are un declansator (Consumption Started, Document Added, Document Updated sau Scheduled), filtre optionale (numele fisierului, sursa: email sau folder consume, etichete existente) si actiuni (adauga sau scoate etichete, proprietar, permisiuni, campuri personalizate, trimite un email sau apeleaza un webhook). Exemplu: orice document venit prin regula de email facturi primeste proprietarul “contabilitate” si eticheta de platit; un alt workflow iti trimite un email cand se adauga un document cu eticheta contract.

Cai de stocare: un arbore de foldere ordonat pe disc

Implicit, fisierele sunt stocate cu nume numerice. La Storage Paths creeaza o cale cu un sablon de tipul {{ correspondent }}/{{ created_year }}/{{ title }} si seteaz-o sa se potriveasca pe toate documentele (sau dupa tip). Acum fisierele de pe disc sunt organizate ca Enel/2026/Factura octombrie.pdf, lizibile si fara Paperless.

Pasul 10: Backup la tot (si actualizari in siguranta)

Arhiva ta valoreaza cat backup-ul ei. Paperless include un document exporter care scrie in folderul export fiecare original, fiecare PDF de arhiva si un manifest.json cu toate metadatele (etichete, corespondenti, utilizatori, reguli). Ruleaza-l o data manual:

cd /opt/paperless
docker compose exec -T webserver document_exporter ../export
ls export | head

La rularile urmatoare actualizeaza doar ce s-a schimbat. Adauga --delete daca vrei ca fisierele documentelor sterse din Paperless sa dispara si din export. Programeaza-l in fiecare noapte cu crontab -e:

0 3 * * * cd /opt/paperless && docker compose exec -T webserver document_exporter ../export > /dev/null 2>&1

Un backup pe acelasi disc nu e backup, asa ca copiaza folderul export pe alta masina, ideal criptat, de exemplu cu rsync pe un al doilea server sau cu un utilitar care cripteaza, precum restic. Exportul este si “usa de iesire”: fisierele sunt PDF-uri si JSON obisnuite, iar document_importer le readuce intr-o instalare noua.

Pentru actualizare, citeste notele de release, schimba tag-ul Paperless-ngx in compose.yaml, apoi:

cd /opt/paperless
docker compose pull
docker compose up -d
docker image prune -f

Ruleaza exporter-ul chiar inainte de fiecare actualizare, ca sa ai o copie proaspata daca ceva merge prost.

Optional: documente Office si emailuri intregi cu Tika

Din cutie, Paperless lucreaza cu PDF-uri si imagini. Ca sa importi fisiere Word, Excel, LibreOffice sau emailuri intregi ca .eml (optiunea “Process message as .eml” din regulile de email), adauga doua containere ajutatoare: Gotenberg converteste documentele in PDF, iar Apache Tika le extrage textul. Adauga aceste servicii in compose.yaml (la aceeasi indentare ca db):

  gotenberg:
    image: docker.io/gotenberg/gotenberg:8
    restart: unless-stopped
    command:
      - "gotenberg"
      - "--chromium-disable-javascript=true"
      - "--chromium-allow-list=file:///tmp/.*"

  tika:
    image: docker.io/apache/tika:latest
    restart: unless-stopped

Apoi adauga gotenberg si tika la depends_on pentru webserver, iar in environment liniile:

      PAPERLESS_TIKA_ENABLED: "1"
      PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
      PAPERLESS_TIKA_ENDPOINT: http://tika:9998

Aplici cu docker compose up -d. Dupa cum arata graficul de mai sus, asta adauga in jur de 500 MB de RAM, deci planifica 4 GB. Imaginea Tika foloseste :latest pentru ca e un convertor fara stare; fixeaza o versiune anume daca vrei instalari perfect reproductibile.

Probleme frecvente si greseli comune

“CSRF verification failed” sau 403 la login. PAPERLESS_URL nu se potriveste exact cu adresa din browser (http in loc de https, www, o greseala de tastare). Corecteaza in compose.yaml si ruleaza docker compose up -d.

Fisierele stau in folderul consume si nu se intampla nimic. Uita-te intai in log-uri. Cauza obisnuita sunt permisiunile: fisierele trebuie sa poata fi citite de utilizatorul din USERMAP_UID. Daca folderul e un mount de retea (NFS, SMB), evenimentele inotify nu ajung; adauga PAPERLESS_CONSUMER_POLLING: "30" ca Paperless sa verifice la fiecare 30 de secunde.

Textul OCR e varza sau diacriticele sunt gresite. Verifica PAPERLESS_OCR_LANGUAGE: ron+eng si cauta in log-urile de pornire instalarea pachetului de romana. Pentru documentele importate inainte de corectura, selecteaza-le in lista si foloseste actiunea in masa de refacere a OCR-ului.

Containerul se restarteaza sau VPS-ul ingheata la un import mare. E varful de OCR. Pastreaza PAPERLESS_TASK_WORKERS la 1, scade thread-urile la 1 sau adauga un fisier de swap pe KVM. Intr-un container LXC neprivilegiat de obicei nu poti adauga swap, asa ca alege un plan cu mai mult RAM.

Docker nu porneste pe un plan LXC. Nesting-ul nu e activat pentru container. Cere suportului sau foloseste un VPS KVM.

Emailurile nu se importa. Foloseste butonul Test de la contul de email, verifica numele folderului (unele servere folosesc nume de tipul INBOX.Procesate) si nu uita filtrul de vechime maxima de 30 de zile. Atasamentele PDF protejate cu parola nu pot fi trecute prin OCR si vor esua.

Erori de certificat in Caddy. Inregistrarea A nu indica inca spre VPS sau portul 80 e blocat. Verifica sudo ufw status si sudo journalctl -u caddy.

Note de securitate

  • Nu publica niciodata portul 8000 fara 127.0.0.1. Docker ocoleste UFW, deci legarea pe loopback e cea care tine efectiv Paperless privat.
  • Parola puternica pentru admin si autentificare in doi pasi. Versiunile 2.x recente suporta autentificare TOTP in doi pasi din setarile profilului; activeaz-o pentru fiecare cont.
  • Conturi separate. Da membrilor familiei sau angajatilor utilizatori normali, cu permisiunile de care au nevoie, in loc sa imparti contul de superuser. Paperless suporta proprietari si permisiuni la nivel de document.
  • Protejeaza secretele. .env contine parola bazei de date si cheia secreta; pastreaza-l cu chmod 600 si in afara oricarui repository Git.
  • Fisierele nu sunt criptate pe disc. Oricine are root pe server poate citi documentele. Foloseste SSH doar cu chei, tine sistemul actualizat si cripteaza backup-urile offsite.
  • Fara FTP sau SMB public pentru scannere. Daca un scanner trebuie sa trimita fisiere, foloseste scan-to-email sau un transfer prin SSH, niciodata un share deschis spre internet.
  • Unde stau datele. Facturile si contractele contin date personale. Gazduite pe un VPS in data center-ul nostru din Romania, raman in UE si sub controlul tau, ceea ce simplifica discutiile despre GDPR.

Deci, merita Paperless-ngx?

Daca ai mai mult decat o cutie de pantofi cu documente, cu siguranta. Dupa o dupa-amiaza de configurare ai o arhiva care citeste romana si engleza, isi ia singura facturile din email, le claseaza pe furnizor si pe tip, si gaseste orice pagina intr-o secunda. Costul pe termen lung: un VPS mic si cinci minute pe saptamana ca sa verifici eticheta Inbox.

Poti rula stack-ul paperless-ngx docker compose din acest ghid pe un VPS de la noi in cateva minute, cu documentele stocate in Romania. Daca preferi sa nu te ocupi singur de Docker, backup-uri si actualizari, echipa noastra de administrare servere poate instala, securiza si intretine Paperless-ngx pentru tine.

Intrebari frecvente

Pot folosi Paperless-ngx de pe telefon?

Da. Interfata web e responsive si merge in orice browser de mobil, iar pozele cu documente le poti incarca direct de pe telefon. Exista si aplicatii mobile facute de comunitate care folosesc API-ul Paperless.

Paperless-ngx modifica fisierele originale?

Nu. Originalul e stocat neatins; rezultatul OCR ajunge intr-un PDF de arhiva separat si in indexul de cautare. Poti descarca oricand oricare dintre versiuni.

De cat spatiu pe disc am nevoie?

In jur de 100-300 KB pe pagina scanata pentru original, plus cam tot atat pentru copia de arhiva. O gospodarie cu cateva mii de documente ramane de obicei sub 20 GB; o firma mica cu ani de facturi ar trebui sa planifice 40 GB sau mai mult si sa urmareasca cresterea.

Pot renunta mai tarziu la Paperless-ngx?

Da. Exporter-ul scrie PDF-uri obisnuite si un manifest JSON cu toate metadatele, iar cu un sablon de cale de stocare fisierele de pe disc sunt deja organizate in foldere lizibile. Nimic nu ramane blocat intr-un format proprietar.

Avem Incredere & Suntem Membri

Suntem membri ai principalelor organizatii de infrastructura internet.

RIPE NCC MANRS PeeringDB RoTLD DSIX SBIX 4IXP LOCIX Euro-IX RIPE NCC MANRS PeeringDB RoTLD DSIX SBIX 4IXP LOCIX Euro-IX