VPS پر paperless-ngx: دستاویزات خود host کریں
Docker Compose کے ذریعے VPS پر paperless-ngx چلائیں: official Postgres stack، PAPERLESS_URL، consume folder، OCR زبانیں، HTTPS اور backups کی درست ترتیب جانیں۔
آپ کیا بنا رہے ہیں
VPS پر Paperless-ngx چلانے سے اسکین شدہ کاغذات کا ایک searchable archive بن جاتا ہے۔ آپ PDF کو watched directory میں رکھتے ہیں، سرور اس پر OCR (optical character recognition) چلاتا ہے، متن extract کرتا ہے، تاریخ اور correspondent کا اندازہ لگاتا ہے، اور اسے file کر دیتا ہے۔ انسٹالیشن ایک Docker Compose file سے ہوتی ہے جس میں چار services شامل ہیں۔ اس کے بعد کا تمام کام configuration پر مشتمل ہے، اور اس guide کا بیشتر حصہ اسی کے لیے ہے، کیونکہ installations عموماً یہی جگہ پر fail ہوتی ہیں۔ یہ photo library نہیں ہے: OCR اور correspondent guessing چھٹیوں کی JPEGs والے folder کے لیے کوئی فائدہ نہیں رکھتے۔ اس لیے انہیں ان کے لیے بنائے گئے photo server میں رکھیں، اور Paperless کو کاغذات کے لیے استعمال کریں۔ Video کے لیے بھی یہی اصول ہے: ripped films کی collection media server پر ہونی چاہیے، جہاں 90s rental store کے انداز میں بنایا گیا Jellyfin front end browsing کو مقصد بناتا ہے، searching کو نہیں۔
Paperless-ngx اصل Paperless project کا maintain ہونے والا community fork ہے۔ یہ free اور self-hosted ہے، اور آپ کے documents کو disk پر plain files کے طور پر store کرتا ہے، اس لیے آپ کبھی اپنے archive سے lock out نہیں ہوتے۔ اسے home box کے بجائے VPS پر چلانے سے آپ کے scans کہیں سے بھی reachable رہتے ہیں، اور home router پر port کھولنے کی ضرورت نہیں پڑتی۔ یہ ان files کے لیے private Nextcloud instance کے ساتھ بھی اچھی طرح کام کرتا ہے جو کاغذات نہیں ہیں۔ یہی منطق اس desktop پر بھی لاگو ہوتی ہے جس سے آپ کا scanner connected ہے، کیونکہ اسی VPS پر آپ کا اپنا RustDesk relay آپ کو router میں hole بنائے بغیر کہیں اور سے اس machine کو control کرنے دیتا ہے۔
یہ stack دراصل کیا چلاتا ہے
سرکاری compose فائل چار containers شروع کرتی ہے۔ ہر container کا کام معلوم ہو تو 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 میں تبدیل کرتے ہیں تاکہ paperless انہیں index کر سکے۔
October 2026 تک postgres compose file میں docker.io/library/postgres:18 اور docker.io/valkey/valkey:9-alpine کی versions مقرر ہیں، اور app کو ghcr.io/paperless-ngx/paperless-ngx:latest سے حاصل کیا جاتا ہے۔
پیشگی تقاضے
- sudo رسائی والا Ubuntu 24.04 KVM VPS، اور Compose plugin کے ساتھ Docker پہلے سے نصب ہو۔ اگر یہ حصہ نیا ہے تو VPS کے لیے Docker Compose کی بنیادی باتیں سے شروع کریں اور پھر واپس آئیں۔
- ایک domain name جس کا A record VPS کی طرف point کر رہا ہو۔ Paperless ایسے hostname پر HTTPS کے ذریعے sign-in قبول نہیں کرے گا جس کے بارے میں اسے پہلے سے بتایا نہ گیا ہو، اس لیے یہ ضرورت آپ کی توقع سے پہلے اہم ہو جاتی ہے۔
- اصل پابندی memory ہے۔ PostgreSQL، Valkey، Granian web server اور Tesseract OCR worker کو ایک ہی وقت میں resident رکھنے کے لیے ہلکے استعمال میں 2 GB کافی ہیں۔ اگر آپ سینکڑوں scans کا backlog import کرنے کا ارادہ رکھتے ہیں تو 4 GB دیں، کیونکہ بڑے multi-page PDF پر OCR وہ memory spike پیدا کرتا ہے جس سے kernel کا out-of-memory killer worker کو ختم کر دیتا ہے۔
- Disk: آپ کا archive دو بار محفوظ ہوتا ہے: original file اور OCR'd archive PDF کی صورت میں۔ اس لیے اپنے scans کے سائز سے تقریباً دو گنا جگہ مختص کریں۔
سرکاری compose فائلیں حاصل کریں
ایک interactive installer موجود ہے:
bash -c "$(curl --location --silent --show-error https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/install-paperless-ngx.sh)"یہ سوالات پوچھ کر فائلیں آپ کے لیے لکھ دیتا ہے۔ خود یہ کام کرنے کے لیے چار commands کافی ہیں۔ اس طریقے سے آپ کو معلوم رہتا ہے کہ ہر چیز کہاں موجود ہے، جو اس سرور کے لیے ضروری ہے جسے آپ خود maintain کریں گے۔
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، اور ہر variant کا -tika ورژن۔ نئی installation کے لیے postgres منتخب کریں۔ چند سو documents کے لیے SQLite کافی ہے، لیکن PostgreSQL کے مقابلے میں full-text search index بہت پہلے سست ہو جاتا ہے۔
.env فائل میں ایک سطر موجود ہے، COMPOSE_PROJECT_NAME=paperless۔ یہی نام ہر container اور volume کے prefix کے طور پر استعمال ہوتا ہے۔ اسے حذف نہ کریں، ورنہ بعد میں حیران ہوں گے کہ docker compose down -v آپ کا data کیوں نہیں ڈھونڈ سکتا۔
پہلے آغاز سے پہلے docker-compose.env کو configure کریں
دو settings اختیاری نہیں ہیں۔ secret key اس command سے generate کریں جسے project کی documentation میں بتایا گیا ہے:
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 ابتدا میں literal value change-me کے ساتھ آتا ہے۔ یہ session tokens پر دستخط کرتا ہے، اور موجودہ releases اس placeholder کو unset تصور کرتی ہیں۔ key missing، blank یا اب بھی change-me ہونے کی صورت میں paperless start ہونے سے انکار کرتا ہے۔ اس لیے اسے replace کرنے تک stack start نہیں ہوگا۔ اسے پہلے آغاز سے پہلے set کریں، کیونکہ بعد میں اسے تبدیل کرنے سے ہر user logout ہو جائے گا۔
PAPERLESS_URL وہ setting ہے جو آپ کا ایک گھنٹہ بچاتی ہے۔ Paperless ایک Django application ہے، اور Django Host header کے ساتھ ساتھ sign-in form پر browser کی رپورٹ کردہ origin بھی check کرتا ہے۔ PAPERLESS_URL set کرنے سے آپ کا address خودکار طور پر ALLOWED_HOSTS، CORS_ALLOWED_HOSTS اور CSRF_TRUSTED_ORIGINS میں شامل ہو جاتا ہے۔ اسے خالی چھوڑ کر کسی domain کو اس machine کی طرف point کریں تو sign-in page پھر بھی load ہوتا ہے، کیونکہ PAPERLESS_ALLOWED_HOSTS کی default value * ہے۔ لیکن اسے HTTPS پر submit کرنے سے CSRF verification failed. Request aborted. کے ساتھ failure ہوتا ہے، کیونکہ آپ کا domain trusted origin نہیں ہے۔ اسے trailing slash اور path کے بغیر لکھیں۔
USERMAP_UID اور USERMAP_GID وہ user set کرتے ہیں جس کے طور پر container چلتا ہے۔ انہیں اپنے account کے مطابق رکھیں۔ اس کی تصدیق id -u اور id -g سے کریں۔ اگر یہ values مطابقت نہ رکھیں تو consume folder میں copy کی گئی files consumer کے لیے readable نہیں رہتیں، اور log میں import کے بجائے permission error دکھائی دیتا ہے۔
stack شروع کریں اور پہلا user بنائیں
docker compose pull
docker compose up -d
docker compose run --rm webserver createsuperuser
docker compose logs -f webservercreatesuperuser username، email اور password طلب کرتا ہے۔ کوئی default login موجود نہیں ہے۔ اگر آپ یہ مرحلہ چھوڑ دیں تو web interface اسے کھولنے والے پہلے شخص سے superuser بنانے کو کہے گا۔ جب تک port 8000 internet کے لیے کھلا ہو، ضروری نہیں کہ وہ شخص آپ ہوں۔ اس لیے فوراً shell سے account بنائیں۔ browser آزمانے سے پہلے log میں server کے port 8000 پر listening شروع کرنے کی اطلاع آنے کا انتظار کریں۔ پہلی بار start ہونے پر database migrations بھی چلتی ہیں، جن میں ایک یا دو منٹ لگ سکتے ہیں۔
domain شامل کرنے سے پہلے اسے local طور پر check کریں:
curl -I http://127.0.0.1:8000302 کا /accounts/login/ کی طرف redirect ہونا ظاہر کرتا ہے کہ stack درست حالت میں ہے۔
اس کے سامنے HTTPS لگائیں
معیاری compose فائل 8000:8000 شائع کرتی ہے، جو ہر interface سے bind ہوتا ہے۔ Public VPS پر اس کا مطلب ہے کہ جسے بھی address معلوم ہو، وہ آپ کے پورے document archive کو plain HTTP کے ذریعے دیکھ سکتا ہے۔ Port line تبدیل کر کے اسے صرف loopback سے bind کریں:
ports:
- "127.0.0.1:8000:8000"اس کے بعد reverse proxy میں TLS (transport layer security) terminate کریں اور درخواستیں 127.0.0.1:8000 کو forward کریں۔ اگر اس سرور پر یہی واحد ایپ ہے تو ACME (automatic certificate management environment) client والا کوئی بھی proxy کافی ہے۔ اگر ایک ہی certificate setup کے پیچھے متعدد containers چلا رہے ہیں تو متعدد Docker Compose ایپس کے لیے Traefik reverse proxy pattern استعمال کریں اور webserver service کو proxy network سے attach کریں، بغیر کسی published port کے۔
آپ جو بھی proxy استعمال کریں، HTTPS setup میں login form کی origin check عموماً مسئلہ پیدا کرتی ہے۔ Paperless X-Forwarded-Proto کو نظرانداز کرتا ہے جب تک آپ PAPERLESS_PROXY_SSL_HEADER set نہ کریں۔ یہ default طور پر بند ہوتا ہے، اس لیے Django ہر proxied request کو plain HTTP سمجھتا ہے، اور آپ کا browser بھیجی ہوئی https:// origin صرف اسی وقت قبول ہوتی ہے جب وہ trusted فہرست میں شامل ہو۔ PAPERLESS_URL کو browser میں درج کیے گئے عین https:// address پر set کرنے سے وہ address اس فہرست میں شامل ہو جاتا ہے۔ اس کے بغیر درست نظر آنے والے صفحے پر CSRF verification failed. Request aborted. ملتا ہے۔
Proxy کی upload size limit بھی بڑھائیں۔ 40 MB کا scan ایسے proxy کے ذریعے بھیجنے پر، جو request body کو 1 MB تک محدود کرتا ہے، paperless کے request وصول کرنے سے پہلے ہی مسترد ہو جاتا ہے، اور browser عمومی upload failure دکھاتا ہے۔
consume ڈائریکٹری کیسے کام کرتی ہے
Compose فائل ./consume کو compose ڈائریکٹری سے container میں bind-mount کرتی ہے۔ آپ وہاں جو بھی فائل رکھتے ہیں، وہ import ہونے کے بعد اس فولڈر سے حذف کر دی جاتی ہے، کیونکہ فائل اب paperless کے زیر انتظام media volume میں موجود ہوتی ہے۔
cp ~/scan-2026-07-14.pdf ~/paperless/consume/
docker compose logs -f webserverآپ کو consumer کو filename حاصل کرتے، OCR چلتے، اور آخر میں یہ اطلاع دیتے دیکھنا چاہیے کہ document شامل کر دیا گیا ہے۔ ایک صفحے کے scan کے لیے پورا عمل چند seconds میں مکمل ہو جاتا ہے، جبکہ طویل document کے لیے ایک minute یا اس سے زیادہ لگ سکتا ہے۔
دو settings یہ تبدیل کرتی ہیں کہ files کہاں تلاش کی جاتی ہیں۔ PAPERLESS_CONSUMER_RECURSIVE=true paperless کو subfolders میں تلاش کرنے کے قابل بناتی ہے، جبکہ PAPERLESS_CONSUMER_SUBDIRS_AS_TAGS=true ہر subfolder کے نام کو tag میں تبدیل کرتی ہے۔ اس طرح consume/invoices/2026/ میں file رکھنے سے اسے invoices اور 2026 tags مل جاتے ہیں۔ اس سے کم لاگت والا filing system آپ شاید کبھی نہ بنائیں۔
Detection اس عمل کا دوسرا حصہ ہے۔ بطور default PAPERLESS_CONSUMER_POLLING_INTERVAL کی قدر 0 ہوتی ہے، یعنی paperless native filesystem notifications استعمال کرتا ہے، جو فوراً trigger ہو جاتی ہیں۔ Network filesystem پر یہ notifications قابل اعتماد نہیں ہوتیں۔ اگر آپ کا consume folder NFS یا SMB share ہے تاکہ network scanner اس میں files لکھ سکے، تو files بغیر detection کے وہاں موجود رہ سکتی ہیں۔ اس کا حل یہ ہے کہ interval کو seconds کی کسی مثبت تعداد پر set کیا جائے، تاکہ paperless اس کے بجائے folder کو scan کرے۔
OCR زبانیں اور ان کی لاگت
PAPERLESS_OCR_LANGUAGE میں Tesseract کا تین حروف والا code درکار ہوتا ہے، اور default طور پر eng استعمال ہوتا ہے۔ زبانیں plus sign کے ذریعے یکجا کریں، جیسے deu+eng۔ اس کے بعد Tesseract ہر page پر فہرست میں شامل تمام زبانوں کے ساتھ کام کرتا ہے، اس لیے ہر اضافی زبان ہر scan کے لیے CPU time بڑھا دیتی ہے۔ shared-vCPU VPS پر اس کا مطلب یہ ہو سکتا ہے کہ scan دس seconds کے بجائے ایک minute میں مکمل ہو۔ صرف وہی زبانیں درج کریں جن میں آپ کی documents حقیقتاً لکھی گئی ہیں۔
Image میں English، German، Italian، Spanish اور French شامل ہیں۔ کسی دوسری زبان کے لیے اسے space-separated list کے طور پر PAPERLESS_OCR_LANGUAGES میں شامل کریں، مثلاً PAPERLESS_OCR_LANGUAGES=tur ces، اور restart کریں۔ container startup کے وقت Tesseract کے data packs download کرتا ہے، اس لیے اس تبدیلی کے بعد پہلی boot سست ہوگی۔
Database اور میڈیا کا بیک اپ لیں
PostgreSQL کے چلتے ہوئے Docker volumes نقل کرنے سے ایسا بیک اپ بن سکتا ہے جو بحال نہ ہو سکے۔ Paperless اپنا exporter فراہم کرتا ہے، جو documents اور تمام metadata کا JSON manifest ./export bind mount میں لکھتا ہے:
docker compose exec -T webserver document_exporter ../export --delete --no-progress-bar--delete ان exported files کو حذف کرتا ہے جو موجودہ document سے مطابقت نہیں رکھتیں، اس لیے folder ہمیشہ mirror رہتا ہے اور غیر معینہ مدت تک نہیں بڑھتا۔ --no-progress-bar اس وقت output کو صاف رکھتا ہے جب یہ cron سے چلتا ہے، جبکہ -T Compose کو ایسے terminal کے لیے پوچھنے سے روکتا ہے جو cron کے پاس موجود نہیں ہوتا۔
نئی stack پر اسی folder سے restore کرنا document_importer ہے، اس لیے آپ کو صرف export directory کو محفوظ رکھنا ہوتا ہے۔ اسے مقررہ schedule کے مطابق offsite بھیجنے کے لیے اپنے VPS سے encrypted، deduplicated restic backups استعمال کریں، اور پہلے export چلائیں تاکہ restic کبھی نامکمل archive محفوظ نہ کرے۔
بیک اپ کی تصدیق اس طرح کریں کہ export/manifest.json موجود ہو اور file count interface میں موجود documents کی تعداد سے مطابقت رکھتا ہو۔ جس بیک اپ کی کبھی فہرست نہ بنائی گئی ہو، وہ بیک اپ نہیں ہے۔ اس سے بھی بدتر یہ ہے کہ nightly export خاموشی سے ناکام ہونا شروع ہو جائے۔ اس لیے cron job سے اس کا exit status اپنے ntfy server کو بھیجیں؛ یوں آپ کو خرابی کے دن ہی معلوم ہو جائے گا، نہ کہ restore کی ضرورت پڑنے والے دن۔
FAQ
ہر صفحہ "Bad Request (400)" کیوں دکھاتا ہے جب میں اپنا domain اس کی طرف point کرتا ہوں؟
Stock files کے ساتھ ایسا نہیں ہونا چاہیے، کیونکہ PAPERLESS_ALLOWED_HOSTS کی default value * ہے۔ Container log میں DisallowedHost کے ساتھ 400 کا مطلب ہے کہ PAPERLESS_ALLOWED_HOSTS ایسی list پر set ہے جس میں آپ کا domain شامل نہیں۔ docker-compose.env میں PAPERLESS_URL=https://paperless.example.com کو set کریں، آخر میں slash نہ لگائیں، اور paperless اس hostname کو list میں شامل کر دے گا، یا PAPERLESS_ALLOWED_HOSTS والی line ہٹا دیں۔ اس کے بعد container دوبارہ بنانے کے لیے docker compose up -d چلائیں۔ صرف env file میں ترمیم کرنے سے کچھ نہیں ہوگا، کیونکہ چلتا ہوا container وہی environment استعمال کرتا ہے جس کے ساتھ وہ start ہوا تھا۔
میں نے consume folder میں PDF رکھی، لیکن کچھ نہیں ہوا۔ مسئلہ کیا ہے؟
پہلے docker compose logs webserver check کریں۔ Permission error کا مطلب ہے کہ USERMAP_UID اور USERMAP_GID اس account سے match نہیں کرتے جو file کا مالک ہے؛ انہیں درست کریں اور container دوبارہ بنائیں۔ اگر log میں کوئی line ہی نہ آئے تو file event پہنچا ہی نہیں۔ یہ network shares پر ہوتا ہے، کیونکہ وہاں native filesystem notifications قابلِ اعتماد نہیں ہوتیں۔ PAPERLESS_CONSUMER_POLLING_INTERVAL کو 30 جیسی value پر set کریں، اور paperless اس کے بجائے ہر 30 seconds بعد folder scan کرے گا۔
کیا میں PostgreSQL کے بجائے SQLite کے ساتھ paperless-ngx چلا سکتا ہوں؟
ہاں، docker-compose.sqlite.yml supported ہے اور کم memory استعمال کرتا ہے، اس لیے چھوٹے VPS کے لیے موزوں ہے۔ مسئلہ archive کے بڑھنے کے ساتھ ظاہر ہوتا ہے: ہزاروں documents ہونے پر full-text search اور bulk tag edits نمایاں طور پر سست ہو جاتے ہیں۔ بعد میں migration کے لیے export اور import درکار ہوگا، اس لیے اگر آپ کو archive کے مسلسل بڑھنے کی توقع ہے تو ابھی PostgreSQL منتخب کریں۔
Scans کے archive کے لیے حقیقت میں کتنی disk درکار ہوتی ہے؟
تقریباً source files کے حجم سے دو گنا۔ Paperless اصل file کو بغیر تبدیلی کے رکھتا ہے اور searchable text layer کے ساتھ دوسری OCR'd PDF بھی محفوظ کرتا ہے، اس کے علاوہ چھوٹے thumbnails بھی ہوتے ہیں۔ 200 KB کی text-only scan کا حجم کم رہتا ہے۔ کسی طویل contract کی 30 MB colour scan تقریباً 60 MB محفوظ کرے گی۔ اگر export directory اسی disk پر رکھتے ہیں تو اس کا حجم بھی شامل کریں؛ یوں یہی archive disk پر تین گنا جگہ لے گا۔
کیا مجھے Tika اور Gotenberg containers درکار ہیں؟
صرف اس صورت میں جب آپ Word، Excel یا OpenDocument files کو اپنی PDFs کے ساتھ index کرنا چاہتے ہوں۔ یہ formats کو PDF میں convert کرتے ہیں تاکہ paperless ان پر OCR اور search کر سکے۔ یہ دو مزید running containers اور چند سو megabytes memory بھی شامل کرتے ہیں، اس لیے اگر آپ کی تمام files پہلے ہی PDF یا image ہیں تو چھوٹے server پر انہیں چھوڑ دیں۔