VPS पर Paperless-ngx कैसे सेटअप करें: पूरी गाइड
Docker Compose का उपयोग करके VPS पर Paperless-ngx इंस्टॉल करें। इस गाइड में Postgres कॉन्फ़िगरेशन, PAPERLESS_URL सेटिंग्स, OCR भाषाएं और सुरक्षित बैकअप लेने का तरीका जानें।
आप क्या बना रहे हैं
VPS पर Paperless-ngx का उपयोग करने से स्कैन किए गए कागजों का एक फोल्डर खोजने योग्य (searchable) आर्काइव में बदल जाता है। आप एक PDF को watched directory में डालते हैं, सर्वर उस पर OCR (optical character recognition) चलाता है, टेक्स्ट निकालता है, तारीख और संवाददाता (correspondent) का अनुमान लगाता है, और उसे फाइल कर देता है। यह इंस्टॉलेशन चार सेवाओं (services) वाली एक Docker Compose फाइल है। इसके बाद सब कुछ कॉन्फ़िगरेशन है, और यह गाइड अपना अधिकांश समय इसी पर खर्च करती है, क्योंकि इंस्टॉलेशन यहीं विफल होते हैं। यह फोटो लाइब्रेरी नहीं है: OCR और संवाददाता का अनुमान लगाने की प्रक्रिया छुट्टियों की JPEGs के फोल्डर के लिए कोई काम नहीं करती है, इसलिए उन्हें उनके लिए बने फोटो सर्वर में रखें और paperless को केवल कागजों के लिए रखें। वीडियो के लिए भी यही नियम लागू होता है: रिप की गई फिल्मों का संग्रह एक मीडिया सर्वर पर होना चाहिए, जहाँ 90 के दशक के रेंटल स्टोर जैसा दिखने वाला Jellyfin फ्रंट एंड ब्राउज़िंग को सर्च करने से अधिक महत्वपूर्ण बनाता है।
Paperless-ngx मूल Paperless project का maintained community fork है। यह free और self-hosted है, और आपके documents को disk पर plain files के रूप में store करता है। इसलिए अपने archive से आपका access कभी बंद नहीं होता। इसे home box के बजाय VPS पर चलाने से आपके scans कहीं से भी उपलब्ध रहते हैं, और home router पर कोई port खोलने की जरूरत नहीं पड़ती। यह उन files के लिए एक private Nextcloud instance के साथ अच्छी तरह काम करता है जो paper पर नहीं हैं। यही logic उस desktop पर भी लागू होती है जिससे आपका scanner जुड़ा है, क्योंकि उस VPS पर आपका अपना RustDesk relay आपको router में hole किए बिना कहीं से भी उस machine को operate करने देता है।
स्टैक वास्तव में क्या चलाता है
आधिकारिक compose file चार containers शुरू करती है, और यह जानना कि प्रत्येक क्या करता है, logs को पढ़ने योग्य बनाता है।
webserver: स्वयं paperless-ngx image। यह web interface, API, आपके input folder पर नज़र रखने वाला consumer, और OCR करने वाले Celery task workers को चलाती है।db: PostgreSQL। यह metadata, tags, correspondents, और full-text search index tables को रखती है। यह आपके PDFs को स्टोर नहीं करती है।broker: Valkey, एक Redis-compatible key-value store। यह web process और workers के बीच task queue का काम करता है।gotenbergऔरtika: वैकल्पिक, केवल-tikacompose variants में। ये Office documents (.docx,.xlsx,.odt) को PDF में convert करते हैं ताकि paperless उन्हें index कर सके।
जुलाई 2026 तक, postgres compose file docker.io/library/postgres:18 और docker.io/valkey/valkey:9-alpine को pin करती है, और app को ghcr.io/paperless-ngx/paperless-ngx:latest से pull करती है।
आवश्यक शर्तें
- sudo access के साथ एक Ubuntu 24.04 KVM VPS, जिसमें Docker और Compose plugin पहले से installed हो। यदि यह आपके लिए नया है, तो VPS के लिए Docker Compose के बुनियादी सिद्धांतों से शुरुआत करें और फिर वापस आएँ।
- एक domain name जिसका A record VPS की ओर point कर रहा हो। Paperless ऐसे hostname पर serve करने से मना कर देता है जिसके बारे में उसे जानकारी न हो, इसलिए यह आपकी अपेक्षा से पहले ही महत्वपूर्ण हो जाता है।
- Memory सबसे बड़ी बाधा है। PostgreSQL, Valkey, gunicorn और Tesseract OCR worker एक साथ 2 GB RAM में हल्के उपयोग के लिए फिट हो जाते हैं। यदि आप सैकड़ों scans का backlog import करने की योजना बना रहे हैं, तो इसे 4 GB दें, क्योंकि बड़ी multi-page PDF पर OCR करने से memory का उपयोग अचानक बढ़ जाता है, जिससे kernel का out-of-memory killer worker को बंद कर सकता है।
- Disk: आपका archive दो बार store होता है, original file और OCR की गई archive PDF, इसलिए अपने scans के आकार से लगभग दुगुनी जगह का बजट रखें।
आधिकारिक compose files प्राप्त करें
एक interactive installer उपलब्ध है:
bash -c "$(curl --location --silent --show-error https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/install-paperless-ngx.sh)"यह आपसे प्रश्न पूछता है और आपके लिए फाइलें लिखता है। इन्हें मैन्युअल रूप से करना केवल चार commands का काम है और इससे आपको पता रहता है कि सब कुछ कहाँ स्थित है, जो कि एक ऐसे सर्वर पर आवश्यक है जिसका रखरखाव आप स्वयं करेंगे।
mkdir -p ~/paperless && cd ~/paperless
curl -fsSL -o docker-compose.yml https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docker/compose/docker-compose.postgres.yml
curl -fsSL -o docker-compose.env https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docker/compose/docker-compose.env
curl -fsSL -o .env https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docker/compose/.envइसके variants एक ही directory में मौजूद हैं: docker-compose.sqlite.yml, docker-compose.mariadb.yml, और प्रत्येक का एक -tika संस्करण। नए इंस्टॉलेशन के लिए postgres चुनें। कुछ सौ documents के लिए SQLite ठीक है, लेकिन PostgreSQL की तुलना में full-text search index काफी पहले धीमा हो जाता है।
.env फाइल में एक लाइन होती है, COMPOSE_PROJECT_NAME=paperless। यह नाम हर container और volume के लिए prefix बन जाता है, इसलिए इसे डिलीट न करें, अन्यथा बाद में docker compose down -v आपका डेटा नहीं ढूंढ पाएगा।
docker-compose.env को पहली बार start करने से पहले कॉन्फ़िगर करें
दो सेटिंग्स वैकल्पिक नहीं हैं। प्रोजेक्ट द्वारा बताए गए कमांड का उपयोग करके secret key जनरेट करें:
python3 -c "import secrets; print(secrets.token_urlsafe(64))"इसके बाद docker-compose.env को एडिट करें:
PAPERLESS_SECRET_KEY=<the long string you just generated>
PAPERLESS_URL=https://paperless.example.com
PAPERLESS_TIME_ZONE=Europe/Berlin
PAPERLESS_OCR_LANGUAGE=deu+eng
USERMAP_UID=1000
USERMAP_GID=1000PAPERLESS_SECRET_KEY का डिफ़ॉल्ट मान change-me होता है। यह session cookies को साइन करता है, इसलिए इसे बदलने पर कोई भी व्यक्ति डिफ़ॉल्ट मान का उपयोग करके session को forge कर सकता है। इसे पहली बार start करने से पहले ही सेट करें, क्योंकि बाद में इसे बदलने पर सभी users logout हो जाएंगे।
PAPERLESS_URL वह सेटिंग है जो आपका समय बचाती है। Paperless एक Django application है, और Django हर request के Host header को वैलिडेट करता है। PAPERLESS_URL को सेट करें और यह आपके लिए ALLOWED_HOSTS, CORS_ALLOWED_HOSTS और CSRF_TRUSTED_ORIGINS को भर देगा। यदि आप इसे खाली छोड़ते हैं और किसी domain को इस सर्वर पर पॉइंट करते हैं, तो हर पेज Bad Request (400) error देगा और container log में DisallowedHost दिखाई देगा। इसे बिना trailing slash और बिना path के लिखें।
USERMAP_UID और USERMAP_GID उस user को सेट करते हैं जिसके रूप में container चलता है। इन्हें अपने account के साथ मैच करें, जिसे id -u और id -g के साथ चेक किया जा सकता है। यदि वे मैच नहीं करते हैं, तो consume फ़ोल्डर में कॉपी की गई फाइलें consumer द्वारा नहीं पढ़ी जा सकेंगी, और log में import के बजाय permission error दिखाई देगा।
Stack को start करें और पहला user बनाएँ
docker compose pull
docker compose up -d
docker compose run --rm webserver createsuperuser
docker compose logs -f webservercreatesuperuser एक username, एक email और एक password के लिए prompt करता है। इसमें कोई default login नहीं होता है, इसलिए इस चरण को छोड़ने पर आप एक ऐसे sign-in page पर रह जाएंगे जो किसी भी credential को स्वीकार नहीं करेगा। browser में कोशिश करने से पहले उस log line का इंतज़ार करें जो यह बताती है कि server port 8000 पर listening है। पहली बार start होने पर database migrations भी चलते हैं, जिसमें एक या दो मिनट का समय लगता है।
किसी domain को जोड़ने से पहले इसे स्थानीय रूप से (locally) जाँचें:
curl -I http://127.0.0.1:8000302 का /accounts/login/ पर redirect होना यह दर्शाता है कि stack सही ढंग से काम कर रहा है।
इसके सामने HTTPS लगाएँ
स्टॉक compose file 8000:8000 को पब्लिश करती है, जो हर इंटरफेस से बाइंड हो जाता है। एक पब्लिक VPS पर यह आपके पूरे डॉक्यूमेंट आर्काइव को plain HTTP के जरिए किसी भी ऐसे व्यक्ति को दिखा सकता है जिसे पता मिल जाए। पोर्ट लाइन को बदलकर केवल loopback से बाइंड करें:
ports:
- "127.0.0.1:8000:8000"इसके बाद एक reverse proxy में TLS (transport layer security) को टर्मिनेट करें और 127.0.0.1:8000 पर फॉरवर्ड करें। यदि यह बॉक्स पर एकमात्र ऐप है, तो ACME (automatic certificate management environment) क्लाइंट वाला कोई भी प्रॉक्सी काम करेगा। यदि आप एक ही सर्टिफिकेट सेटअप के पीछे कई कंटेनर चला रहे हैं, तो multiple Docker Compose apps के लिए Traefik reverse proxy पैटर्न का पालन करें और webserver सर्विस को बिना किसी पब्लिश पोर्ट के प्रॉक्सी नेटवर्क से जोड़ें।
आप चाहे जो भी प्रॉक्सी इस्तेमाल करें, उसे X-Forwarded-Proto: https भेजना होगा। इसके बिना Django को लगता है कि रिक्वेस्ट HTTP पर आई है, लॉगिन फॉर्म पर ओरिजिन चेक फेल हो जाता है, और आपको एक सही दिखने वाले पेज पर CSRF verification failed. Request aborted. मिलता है। इस फिक्स का दूसरा हिस्सा PAPERLESS_URL को उस सटीक https:// पते पर सेट करना है जिसे आप ब्राउज़र में टाइप करते हैं।
साथ ही प्रॉक्सी की अपलोड साइज लिमिट भी बढ़ाएँ। प्रॉक्सी के जरिए 40 MB का स्कैन, जिसकी बॉडी लिमिट 1 MB पर कैप है, paperless तक पहुँचने से पहले ही रिजेक्ट हो जाता है, और ब्राउज़र एक सामान्य अपलोड फेलियर रिपोर्ट करता है।
consume डायरेक्टरी कैसे काम करती है
Compose फ़ाइल compose डायरेक्टरी से ./consume को कंटेनर के अंदर bind-mount करती है। आप वहाँ जो भी फ़ाइल रखते हैं, उसे import कर लिया जाता है और फिर फ़ोल्डर से हटा दिया जाता है, क्योंकि वह फ़ाइल अब paperless प्रबंधन के अंतर्गत media वॉल्यूम में रहती है।
cp ~/scan-2026-07-14.pdf ~/paperless/consume/
docker compose logs -f webserverआपको यह देखना चाहिए कि consumer फ़ाइल का नाम उठाता है, OCR चलाता है, और अंत में एक लाइन के साथ रिपोर्ट करता है कि दस्तावेज़ जोड़ दिया गया है। एक पेज के स्कैन के लिए पूरा चक्र कुछ सेकंड का होता है, और लंबे दस्तावेज़ के लिए इसमें एक मिनट या उससे अधिक समय लग सकता है।
दो सेटिंग्स फ़ाइलों को खोजने के तरीके को बदलती हैं। PAPERLESS_CONSUMER_RECURSIVE=true paperless को सब-फ़ोल्डर्स में देखने के लिए मजबूर करता है, और PAPERLESS_CONSUMER_SUBDIRS_AS_TAGS=true प्रत्येक सब-फ़ोल्डर के नाम को एक टैग में बदल देता है, इसलिए यदि आप consume/invoices/2026/ में कोई फ़ाइल डालते हैं, तो वह उसे invoices और 2026 के रूप में टैग कर देता है। यह आपके द्वारा बनाया गया सबसे सस्ता फाइलिंग सिस्टम होगा।
डिटेक्शन इसका दूसरा पहलू है। डिफ़ॉल्ट रूप से PAPERLESS_CONSUMER_POLLING_INTERVAL का मान 0 होता है, जिसका अर्थ है कि paperless कर्नल फ़ाइलसिस्टम नोटिफिकेशन का उपयोग करता है, जो तुरंत सक्रिय हो जाते हैं। ये नोटिफिकेशन नेटवर्क फ़ाइलसिस्टम के पार काम नहीं करते हैं। यदि आपकी consume डायरेक्टरी एक NFS या SMB शेयर है ताकि नेटवर्क स्कैनर उस पर लिख सके, तो कुछ भी डिटेक्ट नहीं होगा। इसका समाधान यह है कि interval को एक सकारात्मक संख्या (सेकंड में) पर सेट करें ताकि paperless फ़ोल्डर को स्कैन कर सके।
OCR भाषाएँ और उनकी लागत
PAPERLESS_OCR_LANGUAGE एक तीन-अक्षरों वाला Tesseract कोड लेता है, जो डिफ़ॉल्ट रूप से eng होता है। भाषाओं को प्लस चिह्न के साथ जोड़ें, जैसे deu+eng। Tesseract फिर प्रत्येक भाषा को आज़माता है और सबसे अच्छे परिणाम को चुनता है, इसलिए हर अतिरिक्त भाषा प्रत्येक पृष्ठ पर खर्च होने वाले CPU समय को बढ़ा देती है। एक shared-vCPU VPS पर, यह दस सेकंड में स्कैन पूरा होने और एक मिनट में पूरा होने के बीच का अंतर है। केवल उन्हीं भाषाओं को सूचीबद्ध करें जिनमें आपके दस्तावेज़ वास्तव में लिखे गए हैं।
इमेज में English, German, Italian, Spanish और French शामिल हैं। किसी अन्य भाषा के लिए, उस भाषा को PAPERLESS_OCR_LANGUAGES में स्पेस से अलग की गई सूची के रूप में जोड़ें, उदाहरण के लिए PAPERLESS_OCR_LANGUAGES=tur ces, और फिर restart करें। कंटेनर स्टार्टअप पर Tesseract डेटा पैक डाउनलोड करता है, इसलिए उस बदलाव के बाद पहली बार बूट होने में अधिक समय लगता है।
डेटाबेस और मीडिया का बैकअप लें
PostgreSQL के चलते समय Docker volumes को कॉपी करने से ऐसा बैकअप मिल सकता है जो restore न हो सके। Paperless अपना स्वयं का exporter प्रदान करता है, जो दस्तावेजों और सभी metadata के JSON manifest को ./export bind mount में लिखता है:
docker compose exec webserver document_exporter ../export --delete --no-progress-bar--delete उन exported फाइलों को हटा देता है जो अब वर्तमान दस्तावेज से मेल नहीं खातीं, जिससे यह फोल्डर हमेशा बढ़ते रहने के बजाय एक mirror बना रहता है। जब यह cron से चलता है तो --no-progress-bar आउटपुट को साफ रखता है।
Restore करना उसी फोल्डर के विरुद्ध document_importer है, जिसका अर्थ है कि export directory ही एकमात्र ऐसी चीज है जिसे आपको सुरक्षित रखना है। इसे अपने VPS से encrypted, deduplicated restic backups के साथ एक schedule पर offsite भेजें, और पहले export चलाएं ताकि restic कभी भी अधूरा archive न ले सके।
यह जांचकर बैकअप को सत्यापित करें कि export/manifest.json मौजूद है और फाइलों की संख्या interface में आपके दस्तावेजों की संख्या से मेल खाती है। जिस बैकअप को आपने कभी जांचा नहीं है, वह बैकअप नहीं है। एक nightly export जो चुपचाप विफल होने लगता है, वह और भी बुरा है, इसलिए cron job को उसका exit status अपने स्वयं के ntfy server पर भेजने के लिए कहें। इससे आपको उस सप्ताह ही पता चल जाएगा जब यह खराब होता है, न कि उस दिन जब आपको restore करने की आवश्यकता होती है।
FAQ
मेरे डोमेन को पॉइंट करने के बाद हर पेज "Bad Request (400)" क्यों दिखाता है?
Django ने Host हेडर को अस्वीकार कर दिया है क्योंकि आपका डोमेन ALLOWED_HOSTS में नहीं है। docker-compose.env में PAPERLESS_URL=https://paperless.example.com को सेट करें (अंत में कोई स्लैश न लगाएं), और फिर कंटेनर को फिर से बनाने के लिए docker compose up -d चलाएं। केवल env फ़ाइल को एडिट करने से कुछ नहीं होगा, क्योंकि चल रहा कंटेनर उसी वातावरण को बनाए रखता है जिसके साथ वह शुरू हुआ था।
मैंने consume फ़ोल्डर में एक PDF डाली और कुछ नहीं हुआ। क्या समस्या है?
सबसे पहले docker compose logs webserver की जाँच करें। परमिशन एरर का मतलब है कि USERMAP_UID और USERMAP_GID उस अकाउंट से मेल नहीं खाते जो फ़ाइल का मालिक है, इसलिए उन्हें ठीक करें और कंटेनर को फिर से बनाएं। यदि कोई लॉग लाइन नहीं दिख रही है, तो इसका मतलब है कि फ़ाइल इवेंट कभी प्राप्त ही नहीं हुआ; यह नेटवर्क शेयर पर होता है क्योंकि कर्नल नोटिफिकेशन उन्हें पार नहीं कर पाते। PAPERLESS_CONSUMER_POLLING_INTERVAL को 30 जैसा कुछ सेट करें, इससे paperless हर 30 सेकंड में फ़ोल्डर को स्कैन करेगा।
क्या मैं PostgreSQL के बजाय SQLite के साथ paperless-ngx चला सकता हूँ?
हाँ, docker-compose.sqlite.yml समर्थित है और कम मेमोरी का उपयोग करता है, जो एक छोटे VPS के लिए उपयुक्त है। जैसे-जैसे आपका आर्काइव बढ़ता है, इसका प्रभाव दिखने लगता है: हजारों दस्तावेज़ होने पर फुल-टेक्स्ट सर्च और बल्क टैग एडिट काफी धीमे हो जाते हैं। बाद में माइग्रेट करने का मतलब है एक्सपोर्ट और इम्पोर्ट करना, इसलिए यदि आपको लगता है कि आपका आर्काइव बढ़ता रहेगा, तो अभी PostgreSQL चुनें।
स्कैन के आर्काइव को वास्तव में कितनी डिस्क स्पेस की आवश्यकता होती है?
आपकी सोर्स फ़ाइलों के आकार से लगभग दोगुना। Paperless ओरिजिनल फ़ाइल को बिना छुए रखता है और एक दूसरा OCR किया हुआ PDF स्टोर करता है जिसमें सर्च करने योग्य टेक्स्ट लेयर और छोटे थंबनेल होते हैं। एक 200 KB का केवल-टेक्स्ट स्कैन छोटा रहता है। एक लंबे कॉन्ट्रैक्ट का 30 MB का कलर स्कैन लगभग 60 MB स्टोर करता है। यदि आप एक्सपोर्ट डायरेक्टरी को उसी डिस्क पर रखते हैं, तो वही आर्काइव डिस्क पर तीन बार स्टोर होता है।
क्या मुझे Tika और Gotenberg कंटेनरों की आवश्यकता है?
केवल तभी जब आप चाहते हैं कि Word, Excel या OpenDocument फ़ाइलें आपके PDF के साथ इंडेक्स हों। वे उन फॉर्मेट्स को PDF में बदलते हैं ताकि paperless उन्हें OCR और सर्च कर सके। वे दो और रनिंग कंटेनर और कुछ सौ मेगाबाइट मेमोरी का उपयोग करते हैं, इसलिए यदि आप जो कुछ भी फ़ाइल करते हैं वह पहले से ही PDF या इमेज है, तो छोटे सर्वर पर इन्हें छोड़ दें।