VPS پر paperless-ngx: دستاویزات خود host کریں
Docker Compose کے ذریعے VPS پر paperless-ngx چلائیں: official Postgres stack، PAPERLESS_URL، consume folder، OCR زبانیں، HTTPS اور backups کی درست ترتیب جانیں۔
آپ کیا بنا رہے ہیں
VPS پر Paperless-ngx چلانے سے اسکین شدہ کاغذات کا فولڈر قابلِ تلاش archive بن جاتا ہے۔ آپ PDF کو watched directory میں رکھتے ہیں، server اس پر OCR (optical character recognition) چلاتا ہے، متن extract کرتا ہے، تاریخ اور correspondent کا اندازہ لگاتا ہے، اور اسے file کر دیتا ہے۔ Installation ایک Docker Compose file میں چار services پر مشتمل ہے۔ اس کے بعد کا تمام کام configuration سے متعلق ہے، اور اس guide کا زیادہ تر حصہ اسی پر ہے، کیونکہ installations عموماً یہیں ناکام ہوتی ہیں۔ یہ photo library نہیں ہے: OCR اور correspondent guessing چھٹیوں کی JPEG فائلوں کے فولڈر کے لیے کوئی فائدہ نہیں دیتے۔ اس لیے انہیں ان کے لیے بنائے گئے photo server میں رکھیں، اور paperless کو کاغذات کے لیے استعمال کریں۔
Paperless-ngx اصل Paperless پروجیکٹ کا maintained community fork ہے۔ یہ مفت اور self-hosted ہے، اور آپ کی دستاویزات کو disk پر plain files کے طور پر محفوظ کرتا ہے، اس لیے آپ کبھی بھی اپنے archive سے محروم نہیں ہوتے۔ اسے گھر کے کمپیوٹر کے بجائے VPS پر چلانے سے آپ کے scans کہیں سے بھی قابل رسائی رہتے ہیں، اور home router پر port کھولنے کی ضرورت نہیں پڑتی۔ یہ ان files کے لیے جن کی شکل کاغذی نہیں ہے، private Nextcloud instance کے ساتھ بھی اچھی طرح کام کرتا ہے۔ یہی اصول اس desktop پر بھی لاگو ہوتا ہے جس سے آپ کا scanner منسلک ہے، کیونکہ اسی VPS پر اپنا RustDesk relay رکھنے سے آپ router میں راستہ کھولے بغیر کہیں اور سے اس machine کو چلا سکتے ہیں۔
اس stack میں حقیقی طور پر کیا چلتا ہے
سرکاری compose file چار 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 کر سکے۔
July 2026 تک postgres compose file docker.io/library/postgres:18 اور docker.io/valkey/valkey:9-alpine کو مقرر کرتی ہے، اور app کو ghcr.io/paperless-ngx/paperless-ngx:latest سے حاصل کرتی ہے۔
ضروریات
sudoرسائی والا Ubuntu 24.04 KVM VPS درکار ہے، اور Docker کے ساتھ Compose plugin پہلے سے نصب ہونا چاہیے۔ اگر یہ حصہ نیا ہے تو VPS کے لیے Docker Compose کی بنیادی معلومات سے شروع کریں اور پھر واپس آئیں۔- ایسا domain name درکار ہے جس کا A record VPS کی طرف اشارہ کرتا ہو۔ Paperless ایسے hostname پر سروس فراہم نہیں کرتا جس کے بارے میں اسے پہلے سے بتایا نہ گیا ہو، اس لیے یہ ضرورت آپ کی توقع سے پہلے اہم ہو جاتی ہے۔
- اصل پابندی memory ہے۔ PostgreSQL، Valkey، gunicorn اور Tesseract OCR worker ہلکے استعمال میں بیک وقت 2 GB میں چل سکتے ہیں۔ اگر آپ سینکڑوں scans کا backlog درآمد کرنا چاہتے ہیں تو 4 GB دیں، کیونکہ بڑے multi-page PDF پر OCR کے دوران memory میں اچانک اضافہ ہوتا ہے اور kernel کا out-of-memory killer worker کو ختم کر سکتا ہے۔
- Disk: آپ کا archive دو مرتبہ محفوظ ہوتا ہے: original file اور OCR کیا گیا 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 کو edit کریں:
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 کے ساتھ ship ہوتا ہے۔ یہ session cookies پر دستخط کرتا ہے، اس لیے اسے اسی default value پر چھوڑنے سے default جاننے والا ہر شخص session forge کر سکتا ہے۔ اسے پہلی مرتبہ start کرنے سے پہلے set کریں، کیونکہ بعد میں اسے تبدیل کرنے سے ہر user logout ہو جائے گا۔
PAPERLESS_URL وہ setting ہے جو آپ کا ایک گھنٹہ بچاتی ہے۔ Paperless ایک Django application ہے، اور Django ہر request کے Host header کی validation کرتا ہے۔ PAPERLESS_URL set کریں، تو یہ آپ کے لیے ALLOWED_HOSTS، CORS_ALLOWED_HOSTS اور CSRF_TRUSTED_ORIGINS خود بھر دیتا ہے۔ اسے خالی چھوڑ کر domain کو اس server کی طرف point کرنے سے ہر page Bad Request (400) واپس کرتا ہے، اور container log میں DisallowedHost ظاہر ہوتا ہے۔ اسے trailing slash اور path کے بغیر لکھیں۔
USERMAP_UID اور USERMAP_GID اس user کا تعین کرتے ہیں جس کے طور پر container چلتا ہے۔ انہیں اپنے account کے مطابق رکھیں۔ اس account کی تصدیق id -u اور id -g سے کریں۔ اگر values match نہ کریں تو 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 موجود نہیں ہوتا، اس لیے یہ مرحلہ چھوڑنے پر آپ ایسے sign-in page پر پہنچ جائیں گے جو کبھی بھی کسی credential کو قبول نہیں کرے گا۔ Browser آزمانے سے پہلے اس log line کا انتظار کریں جس میں بتایا گیا ہو کہ server port 8000 پر listening کر رہا ہے۔ پہلی بار start ہونے پر database migrations بھی چلتی ہیں، جن میں ایک یا دو منٹ لگ سکتے ہیں۔
Domain شامل کرنے سے پہلے اسے مقامی طور پر check کریں:
curl -I http://127.0.0.1:8000302 سے /accounts/login/ پر redirect اس بات کی علامت ہے کہ stack درست طور پر چل رہا ہے۔
اس کے سامنے HTTPS رکھیں
معیاری compose فائل 8000:8000 کو publish کرتی ہے، جو ہر 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 کریں۔ اگر اس machine پر صرف یہی app چل رہی ہے تو کوئی بھی ایسا proxy کافی ہے جس میں ACME (automatic certificate management environment) client موجود ہو۔ اگر ایک ہی certificate setup کے پیچھے کئی containers چل رہے ہیں تو متعدد Docker Compose apps کے لیے Traefik reverse proxy pattern پر عمل کریں اور webserver service کو proxy network سے attach کریں، جبکہ کوئی published port نہ رکھیں۔
آپ جو بھی proxy استعمال کریں، اسے X-Forwarded-Proto: https بھیجنا لازم ہے۔ اس کے بغیر Django سمجھتا ہے کہ request HTTP کے ذریعے آئی ہے، login form پر origin check ناکام ہو جاتا ہے، اور درست نظر آنے والے page پر CSRF verification failed. Request aborted. ظاہر ہوتا ہے۔ اس مسئلے کے حل کا دوسرا حصہ یہ ہے کہ PAPERLESS_URL میں عین وہی https:// address set ہو جو آپ browser میں type کرتے ہیں۔
Proxy کی upload size limit بھی بڑھائیں۔ 1 MB تک bodies محدود کرنے والے proxy کے ذریعے 40 MB کا scan بھیجنے پر request paperless تک پہنچنے سے پہلے reject ہو جاتی ہے، اور 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 kernel filesystem notifications استعمال کرتا ہے۔ یہ notifications فوراً فعال ہو جاتی ہیں۔ یہ notifications network filesystem کے ذریعے منتقل نہیں ہوتیں۔ اگر آپ کی consume ڈائریکٹری NFS یا SMB share ہو تاکہ network scanner اس میں file لکھ سکے، تو کوئی file detect نہیں ہوگی۔ اس کا حل یہ ہے کہ interval کو seconds کی مثبت تعداد پر set کریں، تاکہ paperless اس کے بجائے folder کو scan کرے۔
OCR زبانیں اور ان کی لاگت
PAPERLESS_OCR_LANGUAGE تین حروف پر مشتمل Tesseract کوڈ لیتا ہے، اور طے شدہ قدر eng ہے۔ زبانوں کو جمع کے نشان کے ساتھ یکجا کریں، مثلاً deu+eng۔ اس کے بعد Tesseract ہر زبان آزماتا ہے اور بہترین نتیجہ برقرار رکھتا ہے، اس لیے ہر اضافی زبان ہر صفحے پر صرف ہونے والے CPU وقت کو کئی گنا بڑھا دیتی ہے۔ مشترکہ vCPU والے VPS پر اس کا مطلب یہ ہو سکتا ہے کہ اسکین مکمل ہونے میں دس سیکنڈ کے بجائے ایک منٹ لگے۔ صرف وہی زبانیں درج کریں جن میں آپ کی دستاویزات واقعی لکھی گئی ہیں۔
image میں English، German، Italian، Spanish اور French شامل ہیں۔ کسی دوسری زبان کے لیے اسے PAPERLESS_OCR_LANGUAGES میں space-separated فہرست کے طور پر شامل کریں، مثلاً PAPERLESS_OCR_LANGUAGES=tur ces، پھر restart کریں۔ container آغاز کے وقت Tesseract data packs ڈاؤن لوڈ کرتا ہے، اس لیے اس تبدیلی کے بعد پہلا boot زیادہ وقت لیتا ہے۔
ڈیٹا بیس اور میڈیا کا بیک اپ لیں
PostgreSQL کے چلنے کے دوران Docker volumes کو copy کرنے سے ایسا بیک اپ بن سکتا ہے جو restore نہ ہو سکے۔ Paperless اپنا exporter فراہم کرتا ہے، جو documents کے ساتھ تمام metadata کا JSON manifest بھی ./export bind mount میں لکھتا ہے:
docker compose exec webserver document_exporter ../export --delete --no-progress-bar--delete ان exported files کو حذف کرتا ہے جو موجودہ document سے مطابقت نہیں رکھتے، اس لیے folder ہمیشہ mirror رہتا ہے اور غیر ضروری طور پر بڑھتا نہیں۔ --no-progress-bar اسے cron سے چلانے پر output صاف رکھتا ہے۔
تازہ stack پر اسی folder کے خلاف restore کرنا document_importer ہے، اس لیے محفوظ رکھنے کے لیے صرف export directory ضروری ہے۔ اسے مقررہ schedule کے مطابق offsite بھیجیں۔ اس مقصد کے لیے اپنے VPS سے encrypted، deduplicated restic backups استعمال کریں، اور پہلے export چلائیں تاکہ restic کبھی نامکمل طور پر لکھی گئی archive capture نہ کرے۔
export/manifest.json موجود ہونے کی جانچ کر کے backup کی تصدیق کریں، اور یہ بھی دیکھیں کہ فائلوں کی تعداد interface میں موجود document count سے مطابقت رکھتی ہے۔ جس backup کی کبھی فہرست نہ بنائی گئی ہو، وہ backup نہیں ہے۔ اس سے بھی بدتر صورت یہ ہے کہ nightly export خاموشی سے fail ہونا شروع ہو جائے۔ اس لیے cron job کا exit status اپنے ntfy server کو بھیجیں۔ یوں آپ کو اس ہفتے معلوم ہو جائے گا جب یہ fail ہوگا، نہ کہ اس دن جب restore کرنا ضروری ہو۔
FAQ
ہر صفحہ domain کی طرف اشارہ کرنے کے بعد "Bad Request (400)" کیوں دکھاتا ہے؟
Django نے Host header مسترد کر دیا کیونکہ آپ کا domain ALLOWED_HOSTS میں شامل نہیں ہے۔ docker-compose.env میں PAPERLESS_URL=https://paperless.example.com set کریں، آخر میں slash نہ لگائیں، پھر container دوبارہ بنانے کے لیے docker compose up -d چلائیں۔ صرف env file میں ترمیم کرنے سے کچھ نہیں ہوگا، کیونکہ چلتا ہوا container وہی environment استعمال کرتا ہے جس کے ساتھ وہ شروع ہوا تھا۔
میں نے consume folder میں PDF رکھی، لیکن کچھ نہیں ہوا۔ مسئلہ کیا ہے؟
سب سے پہلے docker compose logs webserver چیک کریں۔ permission error کا مطلب ہے کہ USERMAP_UID اور USERMAP_GID اس account سے مطابقت نہیں رکھتے جو file کا مالک ہے، اس لیے انہیں درست کریں اور container دوبارہ بنائیں۔ اگر log میں کوئی سطر بالکل نہ آئے تو file event پہنچا ہی نہیں۔ یہ network shares پر ہوتا ہے کیونکہ kernel notifications ان shares کے ذریعے منتقل نہیں ہوتیں۔ PAPERLESS_CONSUMER_POLLING_INTERVAL کو مثلاً 30 پر 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 بھی store کرتا ہے۔ 200 KB کی text-only scan کا حجم کم رہتا ہے۔ 30 MB کی طویل contract کی 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 بھی استعمال کرتے ہیں، اس لیے اگر آپ کی تمام filed files پہلے ہی PDF یا image ہیں تو چھوٹے server پر انہیں شامل نہ کریں۔