SSD Nodes Learn Hosting plans →
تعلیمی Matt Connorتحریر: Matt Connor · اپ ڈیٹ شدہ 2026-08-29

Planka کو Docker Compose پر خود host کرنے کا طریقہ

VPS پر Planka deploy کرنے کا مکمل طریقہ: Docker Compose، Postgres، Traefik، admin bootstrap variables اور BASE_URL کی وہ ترتیب جو login میں خرابی پیدا کرتی ہے۔

خود Planka کی میزبانی کرنے سے آپ کو کیا ملتا ہے

خود Planka کی میزبانی کرنے سے آپ کی ٹیم کو ایک Kanban board ملتا ہے، جس میں وہی card، list اور label model استعمال ہوتا ہے جس سے لوگ پہلے ہی Trello میں واقف ہیں، اور یہ آپ کے زیرِ انتظام VPS پر چلتا ہے۔ اس میں users کی تعداد کی کوئی حد اور فی user billing نہیں ہوتی، کیونکہ واحد لاگت server ہے۔ اس guide میں اسے Docker Compose کے ذریعے Traefik کے پیچھے deploy کیا گیا ہے۔ ڈیٹا کے لیے Postgres اور users کی upload کردہ ہر file کے لیے named volume استعمال ہوتا ہے۔

یہ guide 2 سے 5 افراد پر مشتمل اس team کو مدنظر رکھتی ہے جو Trello کے free tier سے منتقل ہو رہی ہو۔ اگر آپ اب بھی یہ طے کر رہے ہیں کہ کون سا board چلانا ہے تو پہلے خود میزبانی والے Trello متبادلوں کا تقابل پڑھیں۔ اس guide میں یہ انتخاب پہلے ہی ہو چکا ہے اور صرف deploy کا طریقہ شامل ہے۔

آپ کو Compose plugin کے ساتھ Docker Engine چلانے والا VPS اور اس کی طرف اشارہ کرنے والا DNS A record درکار ہے۔ اس box پر Traefik کا پہلے سے موجود ہونا بھی ضروری ہے، جو TLS (transport layer security) termination کر رہا ہو۔ اگر Traefik ابھی موجود نہیں ہے تو پہلے متعدد Compose apps کے سامنے Traefik reverse proxy قائم کریں، اور اگر نیچے دی گئی file مانوس نہ لگے تو VPS کے لیے Docker Compose کی بنیادی باتیں پڑھیں۔

Planka کو کتنے VPS وسائل درکار ہیں؟

پروجیکٹ کم از کم مطلوبہ hardware کی سطح شائع نہیں کرتا، اس لیے جو بھی عدد آپ پڑھیں اسے پیمائش کے بجائے ابتدائی نقطۂ آغاز سمجھیں۔ Hosting صفحات پر دہرایا جانے والا 2 vCPU اور 4 GB کا عدد provider کی جانب سے تجویز کردہ آرام دہ default ہے، نہ کہ پروجیکٹ کی ناپی ہوئی ضرورت۔ پانچ افراد کے استعمال والے board کے لیے یہ مقدار کافی زیادہ ہے۔

حقیقت میں چلنے والی چیزیں مختصر ہیں: ایک Node.js process جو API اور built frontend فراہم کرتا ہے، اور ایک Postgres process جو data محفوظ رکھتا ہے۔ Planka container کے اندر ایک تیسرا چھوٹا proxy process بھی چلتا ہے جو اس کی outgoing requests کو filter کرتا ہے۔ 1 vCPU اور 2 GB والا plan دو سے پانچ افراد کے board کے لیے کافی ہے، اور اضافی memory کا زیادہ حصہ Postgres cache کے طور پر استعمال ہوتا ہے۔ Board کم وسائل استعمال کرنے والی سروس ہے، اس لیے اگر اسی VPS پر آپ کی ٹیم کے documents بھی رکھنے ہوں تو پہلے اس ایپ کے مطابق sizing کریں: AFFiNE کو Notion طرز کے workspace کے طور پر چلانا کو Planka کی ضرورت شروع ہونے سے پہلے ہی اپنے لیے چند gigabytes درکار ہوتے ہیں۔

Memory کی sizing سے پہلے disk کی sizing کریں، کیونکہ attachments ہی سب سے زیادہ بڑھتے ہیں۔ اس پیراگراف پر بھروسا کرنے کے بجائے اپنی instance کی پیمائش کریں:

docker stats --no-stream
docker system df -v

پہلی command ہر container کے لیے موجودہ memory اور CPU استعمال دکھاتی ہے۔ دوسری command ہر volume میں موجود جگہ دکھاتی ہے۔ دونوں readings عام working week کے بعد لیں، install کے دن نہیں، کیونکہ idle board آپ کی ٹیم کے بارے میں کوئی مفید معلومات نہیں دیتا۔

Compose فائل لکھیں

ڈائریکٹری بنائیں اور اس کی ملکیت اپنے نام کریں، تاکہ آپ کو یہ فائلیں کبھی بھی sudo کے ذریعے edit نہ کرنا پڑیں۔

sudo mkdir -p /opt/planka
sudo chown "$USER":"$USER" /opt/planka
cd /opt/planka

secrets کو Compose فائل کے ساتھ موجود .env فائل میں generate کریں۔ Compose یہ فائل خودکار طور پر پڑھتا ہے اور values کو substitute کر دیتا ہے۔

umask 077
{
  printf 'SECRET_KEY=%s\n' "$(openssl rand -hex 64)"
  printf 'POSTGRES_PASSWORD=%s\n' "$(openssl rand -hex 24)"
  printf 'ADMIN_PASSWORD=%s\n' "$(openssl rand -hex 12)"
} > .env
chmod 600 .env

openssl rand -hex جان بوجھ کر استعمال کیا گیا ہے۔ Hex string میں صرف digits اور a سے f تک حروف ہوتے ہیں، اس لیے یہ DATABASE_URL connection string میں paste ہونے کے بعد اسے خراب نہیں کر سکتی۔ Slash یا at sign پر مشتمل base64 password ایسی connection error پیدا کر سکتا ہے جو غلط hostname جیسی دکھائی دیتی ہے، اور اس مسئلے کو حل کرنے میں ایک گھنٹہ ضائع ہو سکتا ہے۔ عمومی طریقہ Compose فائل سے secrets باہر رکھنا میں بیان کیا گیا ہے۔

اب docker-compose.yml کریں۔ جہاں جہاں kanban.example.com موجود ہے، دونوں جگہ اسے اپنے hostname سے replace کریں۔

services:
  planka:
    image: ghcr.io/plankanban/planka:2.1.1
    restart: unless-stopped
    volumes:
      - planka-data:/app/data
    environment:
      - BASE_URL=https://kanban.example.com
      - DATABASE_URL=postgresql://planka:${POSTGRES_PASSWORD}@postgres/planka
      - SECRET_KEY=${SECRET_KEY}
      - TRUST_PROXY=true
      - DEFAULT_ADMIN_EMAIL=you@example.com
      - DEFAULT_ADMIN_PASSWORD=${ADMIN_PASSWORD}
      - DEFAULT_ADMIN_NAME=Your Name
      - DEFAULT_ADMIN_USERNAME=admin
    networks:
      - proxy
      - internal
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=proxy"
      - "traefik.http.routers.planka.rule=Host(`kanban.example.com`)"
      - "traefik.http.routers.planka.entrypoints=websecure"
      - "traefik.http.routers.planka.tls.certresolver=default"
      - "traefik.http.services.planka.loadbalancer.server.port=1337"
    depends_on:
      postgres:
        condition: service_healthy

  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    volumes:
      - db-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=planka
      - POSTGRES_USER=planka
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    networks:
      - internal
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U planka -d planka"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  planka-data:
  db-data:

networks:
  proxy:
    external: true
  internal:

اس فائل میں چار فیصلوں کی وضاحت ضروری ہے، کیونکہ لوگ عموماً انہی settings کو تبدیل کر کے بعد میں مسئلے کا سامنا کرتے ہیں۔

  • Planka service میں کوئی ports: block نہیں ہے۔ Traefik proxy network کے ذریعے container تک پہنچتا ہے، اس لیے port 1337 host پر publish نہیں کیا جاتا۔ اسے publish کرنے سے کسی کو proxy اور certificate کو bypass کرنے کا راستہ مل جائے گا۔
  • loadbalancer.server.port=1337 container کے اندر موجود port کی نشاندہی کرتا ہے۔ Planka port 1337 پر listen کرتا ہے، جبکہ upstream example صرف port 3000 تک پہنچتا ہے کیونکہ وہ port کو host پر map کرتا ہے۔ یہاں host mapping موجود نہیں، اس لیے Traefik کو container port بتانا ضروری ہے۔
  • condition: service_healthy، Postgres healthcheck کے ساتھ استعمال ہوتا ہے۔ اس کے بغیر Planka database کے connections قبول کرنے سے پہلے start ہو جاتا ہے، اپنی پہلی query پر fail ہوتا ہے اور exit کر جاتا ہے۔ اس کا نتیجہ crash loop جیسا دکھائی دیتا ہے۔ اس طریقہ کار کی تفصیل Compose healthchecks اور startup ordering میں ہے۔
  • Database service کا نام جان بوجھ کر postgres رکھا گیا ہے۔ Planka 2 اپنی outgoing requests کو ایک internal filter کے ذریعے route کرتا ہے، جس کی default block list localhost,postgres ہے۔ Service کا نام تبدیل کرنے سے database خاموشی سے اس list سے خارج ہو جائے گا۔

کچھ بھی start کرنے سے پہلے تصدیق کریں کہ Compose آپ کے secrets پڑھ سکتا ہے:

docker compose config | grep -E 'image:|BASE_URL|POSTGRES_USER'

یہ command ایسی file دکھاتی ہے جس میں .env values پہلے ہی substitute ہو چکی ہوتی ہیں۔ خالی value کا مطلب ہے کہ Compose .env file نہیں پڑھ رہا۔ عام طور پر اس کی وجہ یہ ہوتی ہے کہ آپ command کسی مختلف directory سے چلا رہے ہیں۔

ایڈمن bootstrap variables اصل میں کیا کرتی ہیں

Planka 1.13 کے بعد کوئی administrator خودکار طور پر نہیں بنایا جاتا، اس لیے نئی database میں login کرنے والا کوئی صارف موجود نہیں ہوتا۔ DEFAULT_ADMIN_* group اس مسئلے کو حل کرنے کے دو طریقوں میں سے ایک ہے۔

Startup کے وقت Planka ایسے user کو تلاش کرتا ہے جو DEFAULT_ADMIN_EMAIL سے مطابقت رکھتا ہو۔ اگر ایسا کوئی user موجود نہ ہو تو Planka اس کے ساتھ مقرر password، display name اور username استعمال کرکے ایک user بناتا ہے۔ یہ عمل empty database کے خلاف پہلے boot پر ہوتا ہے، اس لیے یہ variables account کو bootstrap کرتے ہیں، اسے manage نہیں کرتے۔

DEFAULT_ADMIN_EMAIL ایک دوسرا کام بھی کرتا ہے جس کی وجہ سے اکثر لوگ الجھن میں پڑ جاتے ہیں۔ جب تک یہ variable set رہتا ہے، اس کے ذریعے متعین account کو کوئی بھی شخص interface سے edit یا delete نہیں کر سکتا۔ یہ lock-out guard ہے، اور اسی وجہ سے آپ UI میں اس account کا نام یا email address تبدیل نہیں کر سکتے۔ یہ variable ہٹا کر restart کریں، تو account ایک عام admin بن جاتا ہے جسے آپ دوسرے accounts کی طرح edit کر سکتے ہیں۔

Password والی line میں خاص احتیاط کریں۔ environment: کے تحت موجود ہر چیز وہ شخص پڑھ سکتا ہے جو container پر docker inspect چلا سکتا ہو، اس لیے DEFAULT_ADMIN_PASSWORD کو وہاں مستقل طور پر موجود نہیں رہنا چاہیے۔ Login کریں، interface میں اپنا password تبدیل کریں، وہ line delete کریں، پھر docker compose up -d دوبارہ چلائیں۔

زیادہ صاف طریقہ یہ ہے کہ variables مکمل طور پر استعمال نہ کیے جائیں۔ پورے DEFAULT_ADMIN_* group کو comment out کریں، پھر account interactive طریقے سے بنائیں:

docker compose run --rm planka npm run db:create-admin-user

یہ command email، password، display name اور optional username کے لیے prompts دکھاتی ہے، اور user کو براہ راست database میں لکھ دیتی ہے۔ Password کبھی Compose file یا container environment میں نہیں جاتا۔ اگر ایک سے زیادہ افراد کو VPS پر shell access حاصل ہے تو یہ طریقہ استعمال کریں۔ depends_on کی وجہ سے command پہلے Postgres start کرتی ہے، اس لیے یہ ایسے stack پر بھی کام کرتی ہے جو پہلے کبھی up نہ ہوا ہو۔

دونوں طریقوں میں Planka passwords آپ کو خود manage کرنے پڑتے ہیں۔ اگر یہ آپ کی team کے جمع کیے گئے credentials کا چوتھا set ہے تو Planka اس کے بجائے اپنے single sign-on server کے طور پر چلنے والے Authentik جیسے OIDC provider کو logins سونپ سکتا ہے۔ Bootstrap admin کو break-glass account کے طور پر برقرار رکھیں تاکہ provider down ہونے کے دن بھی آپ login کر سکیں۔

جب BASE_URL hostname سے مطابقت نہ رکھے تو logins کیوں ناکام ہوتے ہیں

BASE_URL وہی مکمل address ہے جو لوگ browser میں درج کرتے ہیں، جس میں scheme شامل ہوتی ہے اور آخر میں slash نہیں ہوتا۔ اس stack کے لیے یہ https://kanban.example.com ہے۔ Planka اپنے links اور WebSocket connection اسی value سے بناتا ہے۔ اس لیے غلط BASE_URL واضح error نہیں دکھاتا۔ اس کے بجائے page load ہو جاتا ہے، لیکن loading کبھی مکمل نہیں ہوتی۔

عام صورت یہ ہے: آپ upstream example copy کرتے ہیں، BASE_URL=http://localhost:3000 کو تبدیل نہیں کرتے، اور اپنی اصل domain پر HTTPS کے ذریعے site کھولتے ہیں۔ Login form submit ہو جاتا ہے اور credentials قبول ہو جاتے ہیں۔ Board ظاہر نہیں ہوتا۔ Browser developer console کھولیں تو /socket.io/ کے requests ناکام دکھائی دیں گے، کیونکہ client کو اپنی live connection localhost:3000 پر کھولنے کی ہدایت دی گئی تھی، جبکہ آپ کے laptop پر وہ address موجود ہی نہیں۔

TRUST_PROXY=true اسی مسئلے کا دوسرا حصہ ہے۔ Planka، Traefik کے پیچھے چلتا ہے، اس لیے Docker network کے اندر ہر request proxy کے address سے plain HTTP کے ذریعے اس تک پہنچتی ہے۔ TRUST_PROXY کے بغیر app، Traefik کی جانب سے set کیے گئے X-Forwarded-Proto اور X-Forwarded-For headers نظرانداز کرتی ہے۔ اس لیے اسے connection غیر محفوظ محسوس ہوتی ہے اور وہ ہر client کو ایک ہی مشترکہ IP address سمجھتی ہے۔ اسے set کرنے کے بعد app ان headers کو پڑھتی ہے اور browser کے ساتھ scheme پر مطابقت رکھتی ہے۔

Traefik WebSockets کو اضافی configuration کے بغیر proxy کرتا ہے، اور اسی لیے یہاں اسے ترجیح دینا مناسب ہے۔ nginx میں socket.io کے لیے اپنا location block درکار ہوتا ہے، جس میں proxy_set_header Upgrade $http_upgrade اور proxy_set_header Connection "upgrade" شامل ہوں۔ بصورت دیگر ایک مختلف وجہ سے وہی رکا ہوا spinner دکھائی دے گا۔

بعد میں board کو کسی نئے hostname پر منتقل کرنے کے لیے دو چیزیں ایک ساتھ تبدیل کریں: BASE_URL value اور Traefik کا Host() rule۔ اگر ایک تبدیل کر کے دوسری کو بھول جائیں تو spinner دوبارہ ظاہر ہوگا۔ https://example.com/planka جیسی subpath سے Planka چلانا version 2.1.0 سے supported ہے، جو March 2026 میں جاری ہوا تھا۔ پرانے tags کے ساتھ اسے الگ subdomain دیں۔

Planka میں attachments اور avatars کہاں محفوظ ہوتے ہیں

Planka 2 صارف کی upload کردہ تمام فائلیں container کے اندر ایک ہی path پر محفوظ کرتا ہے: /app/data۔ Attachments، user avatars اور board background images سب اسی path کے اندر موجود ہوتے ہیں۔ Version 1 میں تین الگ directories استعمال ہوتی تھیں، اس لیے کسی پرانی تحریر سے نقل کی گئی Compose file ایسے paths mount کرتی ہے جو اب موجود نہیں ہیں، جبکہ اصل data directory unmounted رہ جاتی ہے۔

یہ single mount اس بات کا تعین کرتا ہے کہ board upgrade کے بعد برقرار رہے گا یا نہیں۔ اگر /app/data کسی volume پر موجود نہ ہو تو uploads container کی writable layer میں محفوظ ہوتی ہیں۔ Container دوبارہ بننے پر یہ layer ختم ہو جاتی ہے، اور image tag تبدیل کرنے پر container ہر بار دوبارہ بنایا جاتا ہے۔ Board بظاہر درست حالت میں واپس آتا ہے، تمام cards موجود ہوتے ہیں، لیکن ہر attachment link ناکام ہو جاتا ہے، کیونکہ database rows اب ایسی files کی طرف اشارہ کر رہی ہوتی ہیں جو موجود نہیں رہتیں۔

اوپر دی گئی Compose file میں موجود named volume اس مسئلے کو روکتا ہے۔ Bind mount بھی کام کرتا ہے اور عام tools سے files کا backup لینا آسان بناتا ہے، لیکن اس کے لیے ایک اضافی مرحلہ درکار ہے۔ Container کے اندر Node process UID 1000 کے طور پر چلتا ہے، اس لیے root کی ملکیت والی host directory میں پہلی upload پر permission error آتا ہے:

sudo chown -R 1000:1000 /opt/planka/data

دونوں طریقوں کے باہمی trade-off کی تفصیل bind mounts اور named volumes کا موازنہ میں دی گئی ہے۔

اگر آپ کے plan میں attachments کے باعث disk بھرنے لگے تو Planka انہیں S3-compatible storage میں بھی لکھ سکتا ہے۔ اس کے لیے S3_ENDPOINT، S3_BUCKET اور متعلقہ key variables استعمال ہوتے ہیں۔ یہ کسی hosted bucket یا دوسرے server پر موجود self-hosted MinIO object store کی طرف اشارہ کر سکتے ہیں۔ Team کے board کو بھرنے سے پہلے یہ فیصلہ کریں، کیونکہ یہ setting صرف نئی uploads پر لاگو ہوتی ہے۔

اسٹیک شروع کریں اور اس کے درست چلنے کی تصدیق کریں

docker compose pull
docker compose up -d
docker compose ps

docker compose ps میں postgres کو healthy اور planka کو running دکھائی دینا چاہیے۔ اگر Planka مسلسل restart loop میں جا رہا ہو تو سب سے پہلے database connection چیک کریں، app کو نہیں۔

docker compose logs -f planka

صحت مند first boot کے دوران database migrations چلتی ہیں، پھر server کے port 1337 پر listening کرنے کی اطلاع ملتی ہے۔ Log پر انحصار کرنے کے بجائے Postgres سے براہ راست پوچھ کر تصدیق کریں کہ schema واقعی لاگو ہو چکا ہے:

docker compose exec postgres psql -U planka -d planka -c '\dt'

اگر table list میں board اور card شامل ہوں تو اس کا مطلب ہے کہ migrations چل چکی ہیں۔ "Did not find any relations" کا مطلب ہے کہ Planka نے کبھی connection قائم نہیں کیا۔ اس لیے اپنے .env میں موجود POSTGRES_USER اور POSTGRES_PASSWORD values کے ساتھ DATABASE_URL کا موازنہ کریں۔

اس کے بعد route کو VPS سے نہیں بلکہ اپنی machine سے چیک کریں:

curl -I https://kanban.example.com

HTTP/2 200 کا مطلب ہے کہ Traefik کے پاس certificate موجود ہے اور وہ container تک پہنچ رہا ہے۔ Traefik کی طرف سے دیا گیا 404 اس بات کی نشاندہی کرتا ہے کہ router labels match نہیں ہوئے۔ اس کی عام وجہ یہ ہے کہ container proxy network سے attached نہیں ہے۔ اب site کھولیں اور admin account سے log in کریں۔

ہر version bump سے پہلے pg_dump لیں

آپ کے board کا ڈیٹا دو الگ stores میں موجود ہے، اس لیے backup میں دونوں شامل ہونے چاہییں: Postgres database اور planka-data volume۔ Stack چلنے کے دوران database کا dump لیں۔

docker compose exec -T postgres pg_dump -U planka -d planka > "planka-db-$(date +%F).sql"

-T اختیاری نہیں ہے۔ اس کے بغیر Compose ایک pseudo-terminal مختص کرتا ہے، اور terminal layer stream میں line endings دوبارہ لکھ دیتی ہے۔ نتیجتاً ایسی dump file بنتی ہے جو restore کے دوران درمیان میں fail ہو جاتی ہے۔ یہ failure کئی ہفتے بعد ظاہر ہوتا ہے، یعنی بالکل ایسے وقت جب اس کا ظاہر ہونا سب سے زیادہ نقصان دہ ہوتا ہے۔

اب uploads کا backup لیں۔ پہلے اصل volume name معلوم کریں، کیونکہ Compose اس کے آگے project directory name کا prefix لگا دیتا ہے۔

docker volume ls | grep planka
docker run --rm -v planka_planka-data:/data -v "$PWD":/backup alpine \
  tar czf /backup/planka-files-$(date +%F).tgz -C /data .

یہ project اپنے repository میں docker-backup.sh اور docker-restore.sh بھی فراہم کرتا ہے، اور official documentation میں انہیں nightly cron job پر چلانے کی ہدایت ہے۔ دونوں میں سے کوئی بھی طریقہ درست ہے۔ لیکن ایسا backup قابلِ اعتماد نہیں جسے آپ نے کبھی restore نہ کیا ہو۔ اس لیے ایک مرتبہ اسے scratch VPS پر restore کریں، پھر تصدیق کریں کہ آپ log in کر سکتے ہیں اور attachment کھول سکتے ہیں۔ یہی دو stores ہر ایسی Compose app میں موجود ہوتے ہیں جو uploads قبول کرتی ہے۔ اس لیے اگر بعد میں آپ اپنے support desk کے ساتھ اسی box پر Chatwoot چلائیں، تو یہاں بنایا گیا routine volume names تبدیل کرنے کے علاوہ تقریباً ویسے ہی استعمال ہو جائے گا۔

ہر version change سے فوراً پہلے dump چلائیں۔ گزشتہ رات کا backup اس backup کے برابر نہیں جو اس migration سے پہلے لیا گیا ہو جسے آپ ابھی چلانے والے ہیں۔

ٹیگز کو pin کریں اور release notes پڑھیں

اس فائل میں دونوں image tags جان بوجھ کر pin کیے گئے ہیں۔

ghcr.io/plankanban/planka:2.1.1 ایک مخصوص release ہے، جو August 2026 تک موجودہ ہے۔ latest upstream کے publish کرنے پر بدل جاتا ہے، اس لیے معمول کا docker compose pull ایسے وقت schema migration شامل کر سکتا ہے جب آپ نے اس کا انتخاب نہ کیا ہو۔ اس number کو تبدیل کرنے سے پہلے release notes پڑھیں، کیونکہ breaking changes اور security fixes وہیں بیان کیے جاتے ہیں۔ Version 2.0.3 کو security release کے طور پر publish کیا گیا تھا۔ یہی وہ قسم کی تبدیلی ہے جسے حادثاتی طور پر شامل کرنے کے بجائے پہلے پڑھنا چاہیے۔ یہاں pinning آسان ہے کیونکہ upstream images publish کرتا ہے۔ جہاں project کوئی image publish نہ کرے، وہاں بھی یہی discipline درکار ہے، لیکن ایک اضافی مرحلے کے ساتھ، جیسے checkout کیے گئے git tag سے سرور پر build کیا گیا openGym۔

postgres:16-alpine کو major version پر pin کرنے کی وجہ زیادہ اہم ہے۔ Postgres اپنی data directory کو major version سے وابستہ format میں لکھتا ہے، اور server کسی دوسری version سے لکھی ہوئی directory کھولنے سے انکار کر دیتا ہے۔ postgres:latest لکھیں، tag کو 17 تک roll ہونے دیں، اور container start نہیں ہو گا:

FATAL:  database files are incompatible with server
DETAIL:  The data directory was initialized by PostgreSQL version 16, which is not compatible with this version 17.

کوئی data ضائع نہیں ہوتا، اور restart کرنے سے بھی مسئلہ حل نہیں ہوتا۔ نئے Postgres major پر منتقل ہونے کے لیے پرانی version سے dump لے کر نئی version کی fresh data directory میں restore کرنا ضروری ہے۔ یہ stack کے بند ہونے کے دوران کیا جانے والا منصوبہ بند کام ہے، image pull کا ضمنی نتیجہ نہیں۔

اگر آپ fresh install شروع کرنے کے بجائے موجودہ Planka 1.x install منتقل کر رہے ہیں، تو اس upgrade کا اپنا documented procedure project documentation میں موجود ہے۔ اس کے علاوہ، پہلے سے backup لیے بغیر version 1 پر واپس جانے کا کوئی طریقہ نہیں۔

خرابی کی صورتیں اور نظر آنے والی strings

Planka بار بار restart ہوتی ہے اور log میں database کا نام آتا ہے۔ DATABASE_URL میں موجود credentials، Postgres environment سے مطابقت نہیں رکھتے۔ یاد رکھیں کہ POSTGRES_PASSWORD صرف data directory کو پہلی بار initialize کرتے وقت لاگو ہوتا ہے۔ اس لیے پہلی boot میں غلطی کے بعد variable درست کرنے سے کچھ تبدیل نہیں ہوتا۔ آپ کو db-data volume حذف کرکے دوبارہ شروع کرنا ہوگا۔

Login کامیاب ہوتا ہے، لیکن board کبھی load نہیں ہوتا۔ BASE_URL، browser bar میں موجود address سے مطابقت نہیں رکھتا، یا TRUST_PROXY موجود نہیں ہے۔ Browser console میں /socket.io/ کو کی جانے والی ناکام requests نظر آتی ہیں۔

باقی سب کچھ کام کرتا ہے، لیکن uploads ناکام ہوتے ہیں۔ Bind mount کی ملکیت root کے پاس ہے۔ Host directory پر sudo chown -R 1000:1000 چلائیں اور container کو restart کریں۔

Upgrade کے بعد attachments غائب ہوگئیں۔ /app/data کسی volume پر موجود نہیں تھا، اس لیے files container layer میں محفوظ تھیں جسے upgrade نے replace کردیا۔ Backup سے files restore کریں، پھر image tag کو دوبارہ تبدیل کرنے سے پہلے volume شامل کریں۔

Traefik 404 واپس کرتا ہے۔ Container proxy network پر موجود نہیں ہے، یا Host() rule آپ کے DNS record سے مطابقت نہیں رکھتا۔ docker compose config substitution کے بعد labels دکھاتا ہے؛ یہیں typos نمایاں ہوتے ہیں۔

Notifications یا webhooks کبھی موصول نہیں ہوتے۔ Planka 2 اپنی outgoing HTTP requests ایک internal filter کے ذریعے بھیجتا ہے، اور default block list میں localhost اور postgres شامل ہیں۔ اسی host پر موجود دوسرے container کو بھیجے جانے والا webhook design کے مطابق block ہوسکتا ہے۔ Filter ہٹانے کے بجائے OUTGOING_ALLOWED_HOSTS کو adjust کریں۔

چلنے کے بعد operational load کم رہتا ہے۔ Release notes دیکھتے رہیں، اور ہر upgrade سے پہلے database dump کریں۔ restart: unless-stopped کی وجہ سے reboot کے بعد stack خود بحال ہوجاتا ہے، بشرطیکہ Docker service خود boot کے وقت enabled ہو۔ اگر ایسا نہ ہو تو reboot کے بعد بحال ہونے والے Compose stacks میں متعلقہ صورتیں بیان کی گئی ہیں۔

FAQ

لاگ اِن کرنے کے بعد Planka مسلسل لوڈ کیوں ہوتا رہتا ہے؟

Credentials قبول ہو گئے، لیکن live connection قائم نہیں ہوا۔ Planka اپنا WebSocket URL BASE_URL سے بناتا ہے۔ اگر اس variable کی قدر اب بھی http://localhost:3000 ہو، جبکہ آپ site کو https://kanban.example.com پر کھول رہے ہوں، تو browser ایسے address سے socket کھولنے کی کوشش کرتا ہے جو آپ کی machine پر موجود نہیں۔ Developer console میں /socket.io/ کو ناکام requests دکھائی دیں گی۔ BASE_URL کو trailing slash کے بغیر درست public address پر set کریں، TRUST_PROXY=true شامل کریں تاکہ app آپ کے reverse proxy کے X-Forwarded-Proto header کو استعمال کرے، پھر docker compose up -d چلائیں۔

پہلا Planka admin user کیسے بنائیں؟

Version 1.13 کے بعد administrator خودکار طور پر نہیں بنتا۔ یا تو DEFAULT_ADMIN_EMAIL کو اس کے متعلقہ password، name اور username variables کے ساتھ set کرکے stack شروع کریں، یا docker compose run --rm planka npm run db:create-admin-user چلائیں اور prompts کے جوابات دیں۔ Shared server پر interactive command زیادہ محفوظ ہے، کیونکہ password اس container environment میں داخل نہیں ہوتا جسے docker inspect پڑھ سکتا ہے۔ بعد میں DEFAULT_ADMIN_EMAIL کو set رکھنے سے یہ account interface سے edit یا delete نہیں کیا جا سکتا۔

Planka attachments اور avatars کہاں محفوظ کرتا ہے؟

Planka 2 میں تمام uploaded files، جن میں attachments، user avatars اور board backgrounds شامل ہیں، container کے اندر /app/data کے تحت محفوظ ہوتی ہیں۔ اس path کو named volume پر mount کریں۔ اگر یہ mount نہ ہو تو files container کی writable layer میں رہتی ہیں اور container دوبارہ بننے پر ضائع ہو جاتی ہیں۔ ہر image upgrade کے دوران container دوبارہ بنتا ہے۔ Bind mount بھی استعمال کیا جا سکتا ہے، لیکن Node process UID 1000 کے طور پر چلتا ہے۔ اس لیے host directory پر sudo chown -R 1000:1000 چلائیں، ورنہ uploads permission error کے ساتھ ناکام ہو جائیں گی۔

Self-hosted Planka کو کتنی RAM درکار ہے؟

Project کم از کم hardware requirements شائع نہیں کرتا۔ Hosting pages پر دہرایا جانے والا 2 vCPU اور 4 GB کا figure کسی provider کی default configuration ہے، measurement نہیں، اور چھوٹے board کے لیے یہ کافی زیادہ ہے۔ پورا workload ایک Node process اور ایک Postgres process پر مشتمل ہوتا ہے، اس لیے 1 vCPU اور 2 GB plan دو سے پانچ افراد کی team کے لیے کافی ہے۔ معمول کے ایک ہفتے کے بعد docker stats --no-stream چلائیں اور اپنے اعداد و شمار کی بنیاد پر capacity مقرر کریں۔ Memory کے مقابلے میں disk کو زیادہ قریب سے monitor کریں، کیونکہ storage بنیادی طور پر attachments کی وجہ سے بڑھتی ہے۔

Data ضائع کیے بغیر Planka کو upgrade کیسے کریں؟

Upgrade سے فوراً پہلے database dump بنائیں اور uploads volume کا archive تیار کریں۔ صرف گزشتہ رات کے scheduled backup پر انحصار نہ کریں۔ docker compose exec -T postgres pg_dump -U planka -d planka > planka-db.sql استعمال کریں اور -T برقرار رکھیں تاکہ pseudo-terminal redirected output کو خراب نہ کرے۔ ہر اس version کے release notes پڑھیں جسے آپ skip کر رہے ہیں، image tag کو latest کے بجائے کسی مخصوص release پر تبدیل کریں، پھر docker compose pull اور docker compose up -d چلائیں اور migration کے لیے log monitor کریں۔ Postgres tag کو اس کے major version پر pinned رکھیں، کیونکہ server کسی مختلف major version سے لکھے گئے data directory کو کھولنے سے انکار کر دیتا ہے۔