SSD Nodes Learn Hosting plans →
गाइड Matt Connorलेखक: Matt Connor · अपडेट किया गया: 2026-08-28

Docker Compose के साथ Planka को self-host कैसे करें

Docker Compose का उपयोग करके अपने VPS पर Planka को deploy करें। इस गाइड में Postgres सेटअप, Traefik कॉन्फ़िगरेशन और BASE_URL की उस गलती को ठीक करना शामिल है जो लॉगिन रोकती है।

Planka को self-host करने के लाभ

Planka को self-host करने से आपकी टीम को एक ऐसा Kanban board मिलता है, जिसमें card, list और label का वही मॉडल है जिसे लोग पहले से ही Trello में जानते हैं, और यह आपके द्वारा नियंत्रित VPS पर चलता है। इसमें कोई seat limit या प्रति-उपयोगकर्ता बिलिंग नहीं है, क्योंकि एकमात्र खर्च सर्वर का है। यह गाइड इसे Traefik के पीछे Docker Compose के साथ deploy करती है, जिसमें डेटा के लिए Postgres और उपयोगकर्ताओं द्वारा अपलोड की गई प्रत्येक फाइल के लिए एक named volume का उपयोग किया जाता है।

यह गाइड उन दो से पांच लोगों की टीमों के लिए है जो Trello के free tier से बाहर निकल रहे हैं। यदि आप अभी भी यह तय कर रहे हैं कि कौन सा board इस्तेमाल करना है, तो पहले self-hosted Trello विकल्पों की तुलना पढ़ें। यह गाइड मानती है कि आपने चुनाव कर लिया है और केवल deploy करने की प्रक्रिया को कवर करती है।

आपको Docker Engine और Compose plugin के साथ एक VPS की आवश्यकता है, जिस पर एक DNS A record पॉइंट कर रहा हो। आपको उस सर्वर पर पहले से चल रहे Traefik instance की भी आवश्यकता है जो TLS (transport layer security) को terminate कर रहा हो। यदि Traefik अभी तक सेटअप नहीं है, तो पहले कई Compose apps के सामने एक Traefik reverse proxy सेटअप करें, और यदि नीचे दी गई फाइल अपरिचित लगे तो Docker Compose की बुनियादी जानकारी पढ़ें।

Planka को कितने VPS की आवश्यकता है?

यह प्रोजेक्ट हार्डवेयर की कोई न्यूनतम सीमा प्रकाशित नहीं करता है, इसलिए आपके द्वारा पढ़ी गई किसी भी संख्या को माप के बजाय एक शुरुआती बिंदु मानें। होस्टिंग पेजों पर बार-बार दिखाई जाने वाली 2 vCPU और 4 GB की संख्या प्रदाता का एक सुविधाजनक डिफ़ॉल्ट है, न कि प्रोजेक्ट द्वारा मापी गई कोई आवश्यकता। पाँच लोगों द्वारा उपयोग किए जाने वाले बोर्ड के लिए यह काफी अधिक है।

जो वास्तव में चलता है वह छोटा है: एक Node.js प्रोसेस जो API और बिल्ट फ्रंटएंड को सर्व करती है, और एक Postgres प्रोसेस जो डेटा रखती है। Planka कंटेनर के अंदर एक तीसरा छोटा प्रॉक्सी प्रोसेस चलता है जो इसके आउटगोइंग अनुरोधों को फ़िल्टर करता है। 1 vCPU और 2 GB का प्लान दो से पाँच लोगों के बोर्ड को संभाल सकता है, और अधिकांश अतिरिक्त मेमोरी Postgres कैश के रूप में उपयोग होती है। एक बोर्ड एक हल्का पड़ोसी है, इसलिए यदि उसी VPS पर आपकी टीम के दस्तावेज़ भी रखने हैं, तो पहले उस ऐप के लिए आकार निर्धारित करें: Notion-style workspace के रूप में AFFiNE चलाना Planka के कुछ भी मांगने से पहले ही अपने आप में कुछ गीगाबाइट की मांग करता है।

मेमोरी का आकार निर्धारित करने से पहले डिस्क का आकार निर्धारित करें, क्योंकि अटैचमेंट ही वह हिस्सा है जो बढ़ता है। इस पैराग्राफ पर भरोसा करने के बजाय अपने स्वयं के इंस्टेंस को मापें:

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

पहला कमांड प्रति कंटेनर लाइव मेमोरी और CPU को प्रिंट करता है। दूसरा दिखाता है कि प्रत्येक वॉल्यूम कितनी जगह ले रहा है। दोनों रीडिंग एक सामान्य कार्य सप्ताह के बाद लें, न कि इंस्टाल वाले दिन, क्योंकि एक खाली बोर्ड आपकी टीम के बारे में कुछ नहीं बताता है।

Compose file लिखें

डायरेक्टरी बनाएँ और उसका स्वामित्व (ownership) लें, ताकि आपको इन फाइलों को कभी भी sudo के माध्यम से एडिट न करना पड़े।

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

सीक्रेट्स को Compose फाइल के बगल में एक .env फाइल में जनरेट करें। 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 जानबूझकर चुना गया है। एक हेक्स स्ट्रिंग में केवल अंक और a से f तक के अक्षर होते हैं, इसलिए यह उस DATABASE_URL कनेक्शन स्ट्रिंग को नहीं तोड़ सकता जिसमें इसे पेस्ट किया जाता है। स्लैश या एट-साइन (@) वाला बेस64 पासवर्ड एक कनेक्शन त्रुटि उत्पन्न करता है जो गलत होस्टनेम जैसी लगती है, और इसमें आपका एक घंटा बर्बाद हो सकता है। व्यापक पैटर्न Compose फाइल से सीक्रेट्स को बाहर रखना में कवर किया गया है।

अब docker-compose.yml। जहाँ भी kanban.example.com दिखाई दे, उसे अपने होस्टनेम से बदलें।

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:

उस फाइल में लिए गए चार निर्णय स्पष्ट करने योग्य हैं, क्योंकि लोग अक्सर इन्हें बदलते हैं और बाद में पछताते हैं।

  • Planka सर्विस पर कोई ports: ब्लॉक नहीं है। Traefik कंटेनर तक proxy नेटवर्क के माध्यम से पहुँचता है, इसलिए पोर्ट 1337 कभी भी होस्ट पर पब्लिश नहीं होता है। इसे पब्लिश करने से कोई भी आपके प्रॉक्सी और सर्टिफिकेट को बायपास कर सकता है।
  • loadbalancer.server.port=1337 कंटेनर के अंदर के पोर्ट का नाम बताता है। Planka 1337 पर लिसन करता है, और अपस्ट्रीम उदाहरण केवल 3000 पर उस तक पहुँचता है क्योंकि यह पोर्ट को होस्ट पर मैप करता है। यहाँ कोई होस्ट मैपिंग नहीं है, इसलिए Traefik को कंटेनर पोर्ट के बारे में बताना पड़ता है।
  • condition: service_healthy, Postgres हेल्थचेक के साथ काम करता है। इसके बिना Planka डेटाबेस द्वारा कनेक्शन स्वीकार करने से पहले ही शुरू हो जाता है, अपनी पहली क्वेरी में विफल हो जाता है और बंद हो जाता है, जो क्रैश लूप जैसा दिखता है। इसकी कार्यप्रणाली Compose हेल्थचेक और स्टार्टअप ऑर्डरिंग में दी गई है।
  • डेटाबेस सर्विस का नाम जानबूझकर postgres रखा गया है। Planka 2 अपने आउटगोइंग अनुरोधों को एक आंतरिक फिल्टर के माध्यम से रूट करता है जिसकी डिफ़ॉल्ट ब्लॉक लिस्ट localhost,postgres है। सर्विस का नाम बदलें और आप चुपचाप अपने डेटाबेस को उस सूची से हटा देंगे।

कुछ भी शुरू करने से पहले जाँच लें कि Compose आपके सीक्रेट्स को देख सकता है या नहीं:

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

यह उस फाइल को प्रिंट करता है जिसमें .env मान पहले से ही प्रतिस्थापित (substituted) हैं। खाली मान का अर्थ है कि Compose .env फाइल को नहीं पढ़ रहा है, आमतौर पर ऐसा इसलिए होता है क्योंकि आप किसी अलग डायरेक्टरी से कमांड चला रहे हैं।

एडमिन बूटस्ट्रैप वेरिएबल्स वास्तव में क्या करते हैं

Planka 1.13 के बाद से आपके लिए कोई एडमिन नहीं बनाया जाता है, इसलिए एक नए डेटाबेस में कोई भी ऐसा व्यक्ति नहीं होता जो लॉग इन कर सके। DEFAULT_ADMIN_* ग्रुप इसे ठीक करने के दो तरीकों में से एक है।

स्टार्टअप पर Planka DEFAULT_ADMIN_EMAIL से मेल खाने वाले यूजर को खोजता है। यदि कोई यूजर नहीं मिलता है, तो यह उसके साथ सेट किए गए पासवर्ड, डिस्प्ले नेम और यूजरनेम का उपयोग करके एक यूजर बनाता है। यह खाली डेटाबेस पर पहली बार बूट होने पर होता है, इसलिए ये वेरिएबल्स अकाउंट को मैनेज करने के बजाय उसे बूटस्ट्रैप करते हैं।

DEFAULT_ADMIN_EMAIL एक दूसरा काम भी करता है जो लोगों को उलझा देता है। जब तक यह वेरिएबल सेट रहता है, तब तक इसके द्वारा नामित अकाउंट को इंटरफेस से कोई भी एडिट या डिलीट नहीं कर सकता है। यह एक लॉक-आउट गार्ड है, और यही कारण है कि आप UI में उस अकाउंट का नाम या ईमेल एड्रेस नहीं बदल सकते। वेरिएबल को हटा दें और रीस्टार्ट करें, फिर वह अकाउंट एक सामान्य एडमिन बन जाएगा जिसे आप किसी अन्य की तरह एडिट कर सकते हैं।

पासवर्ड वाली लाइन के मामले में सावधानी बरतें। environment: के अंतर्गत कोई भी जानकारी उसे पढ़ने योग्य होती है जो कंटेनर पर docker inspect चला सकता है, इसलिए DEFAULT_ADMIN_PASSWORD को वहां स्थायी रूप से नहीं होना चाहिए। लॉग इन करें, इंटरफेस में अपना पासवर्ड बदलें, उस लाइन को डिलीट करें, और फिर docker compose up -d को दोबारा चलाएं।

साफ-सुथरा तरीका वेरिएबल्स को पूरी तरह से छोड़ देना है। पूरे DEFAULT_ADMIN_* ग्रुप को कमेंट आउट करें, फिर इंटरैक्टिव तरीके से अकाउंट बनाएं:

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

यह ईमेल, पासवर्ड, डिस्प्ले नेम और एक वैकल्पिक यूजरनेम के लिए प्रॉम्प्ट करता है, और यूजर को सीधे डेटाबेस में लिख देता है। पासवर्ड कभी भी Compose फाइल या कंटेनर एनवायरनमेंट को नहीं छूता है। यदि एक से अधिक व्यक्ति के पास VPS का शेल एक्सेस है, तो इस तरीके का उपयोग करें। यह कमांड depends_on के कारण पहले Postgres को स्टार्ट करती है, इसलिए यह ऐसे स्टैक पर भी काम करता है जो कभी चालू नहीं हुआ हो।

दोनों ही तरीके आपको Planka पासवर्ड को मैन्युअल रूप से मैनेज करने के लिए छोड़ देते हैं, और यदि यह आपकी टीम द्वारा एकत्र किए गए क्रेडेंशियल्स का चौथा सेट है, तो Planka इसके बजाय लॉग इन को OIDC प्रदाता को सौंप सकता है, जैसे कि Authentik जो आपके अपने सिंगल साइन-ऑन सर्वर के रूप में चल रहा हो, जिसमें बूटस्ट्रैप एडमिन को उस दिन के लिए ब्रेक-ग्लास अकाउंट के रूप में रखा जाता है जब प्रदाता डाउन हो।

जब BASE_URL होस्टनेम से मेल नहीं खाता है तो लॉगिन क्यों विफल हो जाता है

BASE_URL वह सटीक पता है जिसे लोग ब्राउज़र में टाइप करते हैं, जिसमें स्कीम शामिल होती है और अंत में कोई स्लैश नहीं होता है। इस स्टैक के लिए वह https://kanban.example.com है। Planka उस मान से अपने स्वयं के लिंक और अपना WebSocket कनेक्शन बनाता है, जिसका अर्थ है कि गलत BASE_URL आपको कोई स्पष्ट त्रुटि नहीं देता है। यह आपको एक ऐसा पेज देता है जो लोड तो होता है लेकिन कभी पूरी तरह लोड नहीं हो पाता।

सामान्य स्थिति: आप अपस्ट्रीम उदाहरण को कॉपी करते हैं, BASE_URL=http://localhost:3000 को वैसा ही छोड़ देते हैं, और अपने वास्तविक डोमेन पर HTTPS के माध्यम से साइट तक पहुँचते हैं। लॉगिन फॉर्म सबमिट हो जाता है और आपके क्रेडेंशियल्स स्वीकार कर लिए जाते हैं। बोर्ड कभी दिखाई नहीं देता। ब्राउज़र डेवलपर कंसोल खोलें और आप देखेंगे कि /socket.io/ के अनुरोध विफल हो रहे हैं, क्योंकि क्लाइंट को अपना लाइव कनेक्शन localhost:3000 पर खोलने के लिए कहा गया था, और आपके लैपटॉप पर वह पता मौजूद ही नहीं है।

TRUST_PROXY=true उसी समस्या का दूसरा हिस्सा है। Planka, Traefik के पीछे स्थित है, इसलिए प्रत्येक अनुरोध Docker नेटवर्क के भीतर सादे HTTP पर प्रॉक्सी के पते से उस तक पहुँचता है। TRUST_PROXY के बिना, ऐप उन X-Forwarded-Proto और X-Forwarded-For हेडर को अनदेखा कर देता है जिन्हें Traefik सेट करता है, इसलिए यह मानता है कि कनेक्शन असुरक्षित है और प्रत्येक क्लाइंट को एक साझा IP पते के रूप में मानता है। इसे सेट करने पर, ऐप उन हेडर को पढ़ता है और स्कीम के बारे में ब्राउज़र से सहमत हो जाता है।

Traefik बिना किसी अतिरिक्त कॉन्फ़िगरेशन के WebSockets को प्रॉक्सी करता है, जो यहाँ इसे प्राथमिकता देने का एक कारण है। Nginx पर, socket.io को अपने स्वयं के location ब्लॉक की आवश्यकता होती है जिसमें proxy_set_header Upgrade $http_upgrade और proxy_set_header Connection "upgrade" शामिल हों, अन्यथा आपको एक अलग कारण से वही फंसा हुआ स्पिनर दिखाई देगा।

बोर्ड को बाद में किसी नए होस्टनेम पर ले जाने का मतलब है दो चीजों को एक साथ बदलना: BASE_URL मान और Traefik Host() नियम। एक को बदलें और दूसरे को भूल जाएं, तो आप वापस उसी स्पिनर पर आ जाएंगे। Planka को https://example.com/planka जैसे सबपाथ से सर्व करना मार्च 2026 में जारी संस्करण 2.1.0 से काम करता है। पुराने टैग पर, इसे अपना एक सबडोमेन दें।

Planka अटैचमेंट और अवतार कहाँ रखता है

Planka 2 उपयोगकर्ता द्वारा अपलोड की गई हर चीज़ को कंटेनर के अंदर एक ही पाथ /app/data के तहत स्टोर करता है। अटैचमेंट, उपयोगकर्ता अवतार और बोर्ड बैकग्राउंड इमेज सभी इसी के अंदर रहते हैं। वर्जन 1 में तीन अलग-अलग डायरेक्टरी का उपयोग होता था, इसलिए पुराने लेख से कॉपी की गई Compose फाइल उन पाथ को माउंट करती है जो अब मौजूद नहीं हैं, और वास्तविक डेटा डायरेक्टरी अनमाउंट रह जाती है।

वह एक सिंगल माउंट ही उस बोर्ड के बीच का अंतर है जो अपग्रेड के बाद भी सुरक्षित रहता है और उस बोर्ड के बीच जो एक खराब दोपहर का कारण बनता है। यदि /app/data किसी वॉल्यूम पर नहीं है, तो अपलोड कंटेनर की राइटेबल लेयर में चले जाते हैं। जब कंटेनर को फिर से बनाया जाता है तो वह लेयर नष्ट हो जाती है, और हर बार जब आप इमेज टैग बदलते हैं तो कंटेनर फिर से बनाया जाता है। बोर्ड वापस आने पर ठीक दिखता है, सभी कार्ड वहां होते हैं, लेकिन हर अटैचमेंट लिंक डेड हो जाता है, क्योंकि डेटाबेस रो अभी भी उन फाइलों की ओर इशारा करती हैं जो अब मौजूद नहीं हैं।

ऊपर दी गई Compose फाइल में नामित वॉल्यूम इसे रोकता है। एक बाइंड माउंट भी काम करता है और फाइलों को सामान्य टूल्स के साथ बैकअप लेना आसान बनाता है, लेकिन इसके लिए एक अतिरिक्त स्टेप की आवश्यकता होती है। कंटेनर के अंदर Node प्रोसेस UID 1000 के रूप में चलती है, इसलिए root के स्वामित्व वाली होस्ट डायरेक्टरी पहले अपलोड पर परमिशन एरर देती है:

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

दोनों के बीच के ट्रेड-ऑफ को बाइंड माउंट बनाम नामित वॉल्यूम में समझाया गया है।

यदि अटैचमेंट आपके प्लान के डिस्क स्पेस से अधिक हो जाते हैं, तो Planka उन्हें S3_ENDPOINT, S3_BUCKET और संबंधित की-वेरिएबल्स के माध्यम से S3-संगत स्टोरेज में लिख सकता है। यह किसी होस्टेड बकेट या किसी दूसरे बॉक्स पर सेल्फ-होस्टेड MinIO ऑब्जेक्ट स्टोर की ओर इशारा कर सकता है। टीम द्वारा बोर्ड भरने से पहले ही इसका निर्णय ले लें, क्योंकि यह सेटिंग नए अपलोड पर लागू होती है।

स्टैक को स्टार्ट करें और जांचें कि यह काम कर रहा है या नहीं

docker compose pull
docker compose up -d
docker compose ps

docker compose ps को यह दिखाना चाहिए कि postgres, healthy है और planka, running है। यदि Planka लूप में रीस्टार्ट हो रहा है, तो सबसे पहले डेटाबेस कनेक्शन की जांच करें, न कि ऐप की।

docker compose logs -f planka

एक सफल पहले बूट (first boot) में डेटाबेस माइग्रेशन चलते हैं और फिर सर्वर पोर्ट 1337 पर लिसन (listen) करने की रिपोर्ट देता है। लॉग पर भरोसा करने के बजाय सीधे Postgres से पूछकर पुष्टि करें कि स्कीमा वास्तव में लोड हो गया है:

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

टेबल लिस्ट में board और card का होना यह दर्शाता है कि माइग्रेशन चल गए हैं। "Did not find any relations" का मतलब है कि Planka कभी कनेक्ट ही नहीं हुआ, इसलिए DATABASE_URL की तुलना अपने .env में मौजूद POSTGRES_USER और POSTGRES_PASSWORD मानों से करें।

इसके बाद VPS से नहीं, बल्कि अपनी मशीन से रूट की जांच करें:

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

HTTP/2 200 का मतलब है कि Traefik के पास सर्टिफिकेट है और वह कंटेनर तक पहुंच रहा है। Traefik द्वारा 404 एरर मिलने का मतलब है कि राउटर लेबल मैच नहीं हुए, जिसका सबसे आम कारण यह है कि कंटेनर proxy नेटवर्क से जुड़ा नहीं है। अब साइट खोलें और एडमिन अकाउंट से लॉग इन करें।

हर version bump से पहले pg_dump लें

आपके बोर्ड का डेटा दो अलग-अलग जगहों पर रहता है, इसलिए बैकअप में दोनों को शामिल करना अनिवार्य है: Postgres डेटाबेस और planka-data वॉल्यूम। स्टैक के चलते समय ही डेटाबेस का डंप लें।

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

-T वैकल्पिक नहीं है। इसके बिना Compose एक pseudo-terminal आवंटित कर देता है, और टर्मिनल लेयर स्ट्रीम में लाइन एंडिंग्स को फिर से लिख देती है। परिणामस्वरूप, आपको एक ऐसी डंप फाइल मिलती है जो रिस्टोर के दौरान बीच में ही विफल हो जाती है। यह विफलता हफ्तों बाद सामने आती है, जो कि सबसे खराब स्थिति है।

इसके बाद uploads की बारी है। सबसे पहले वास्तविक वॉल्यूम नाम का पता लगाएं, क्योंकि Compose इसे प्रोजेक्ट डायरेक्टरी नाम के साथ प्रीफिक्स (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 .

यह प्रोजेक्ट अपनी रिपॉजिटरी में docker-backup.sh और docker-restore.sh भी प्रदान करता है, और आधिकारिक डॉक्यूमेंटेशन इन्हें nightly cron job पर चलाने का सुझाव देता है। दोनों में से कोई भी तरीका सही है। जो तरीका सही नहीं है, वह है ऐसा बैकअप जिसे आपने कभी रिस्टोर करके नहीं देखा। इसलिए, एक बार किसी स्क्रैच VPS पर इसे रिस्टोर करें और पुष्टि करें कि आप लॉग इन कर सकते हैं और अटैचमेंट खोल सकते हैं। यही दो स्टोरेज हर उस Compose ऐप में होते हैं जो अपलोड स्वीकार करते हैं, इसलिए यदि आप बाद में अपने सपोर्ट डेस्क के साथ उसी बॉक्स पर Chatwoot इंस्टॉल करते हैं, तो यहाँ बनाई गई प्रक्रिया केवल वॉल्यूम नाम बदलकर आसानी से लागू की जा सकती है।

हर version change से ठीक पहले डंप चलाएं। पिछली रात का बैकअप उस बैकअप के समान नहीं है जो माइग्रेशन शुरू करने से ठीक पहले लिया गया हो।

टैग्स को पिन करें और रिलीज़ नोट्स पढ़ें

उस फ़ाइल में दोनों इमेज टैग्स को जानबूझकर पिन किया गया है।

ghcr.io/plankanban/planka:2.1.1 एक विशिष्ट रिलीज़ है, जो अगस्त 2026 तक अद्यतित (current) है। latest तब बदल जाता है जब भी अपस्ट्रीम इसे पब्लिश करता है, इसलिए एक सामान्य docker compose pull ऐसे समय पर स्कीमा माइग्रेशन ला सकता है जिसे आपने नहीं चुना है। उस नंबर को बदलने से पहले रिलीज़ नोट्स पढ़ें, क्योंकि वहीं पर ब्रेकिंग बदलावों और सुरक्षा सुधारों का विवरण दिया जाता है। वर्ज़न 2.0.3 को एक सुरक्षा रिलीज़ के रूप में पब्लिश किया गया था, और यही वह जानकारी है जिसे आप अचानक से प्रभावित होने के बजाय पहले से पढ़ना चाहेंगे। यहाँ पिनिंग आसान है क्योंकि अपस्ट्रीम इमेज पब्लिश करता है, और जहाँ कोई प्रोजेक्ट इमेज पब्लिश नहीं करता, वहाँ आपको वही अनुशासन एक अतिरिक्त चरण के साथ अपनाना होगा, जैसा कि चेक-आउट किए गए git टैग से बॉक्स पर openGym बिल्ड करने के मामले में है।

postgres:16-alpine को एक बड़े वर्ज़न (major version) पर पिन करने का कारण अधिक गंभीर है। Postgres अपनी डेटा डायरेक्टरी को एक ऐसे फॉर्मेट में लिखता है जो उसके मेजर वर्ज़न से जुड़ा होता है, और सर्वर किसी अलग वर्ज़न द्वारा लिखी गई डायरेक्टरी को खोलने से इनकार कर देता है। यदि आप postgres:latest लिखते हैं और टैग को 17 पर रोल होने देते हैं, तो कंटेनर स्टार्ट नहीं होगा:

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.

इसमें कुछ भी खोता नहीं है, और न ही रीस्टार्ट करने से कुछ ठीक होता है। नए Postgres मेजर वर्ज़न पर जाने का मतलब है पुराने वर्ज़न से डंप लेना और नए वर्ज़न पर एक नई डेटा डायरेक्टरी में रिस्टोर करना। यह स्टैक को डाउन करके किया जाने वाला एक नियोजित कार्य है, न कि इमेज पुल करने का कोई दुष्प्रभाव।

यदि आप नए सिरे से शुरुआत करने के बजाय किसी मौजूदा Planka 1.x इंस्टॉलेशन को माइग्रेट कर रहे हैं, तो उस अपग्रेड की अपनी प्रलेखित प्रक्रिया प्रोजेक्ट डॉक्यूमेंटेशन में दी गई है, और पहले से बैकअप लिए बिना वर्ज़न 1 पर वापस जाने का कोई रास्ता नहीं है।

विफलता के प्रकार और वे संदेश जो आपको दिखाई देंगे

Planka लूप में रीस्टार्ट हो रहा है और लॉग में डेटाबेस का नाम है। DATABASE_URL में दिए गए क्रेडेंशियल्स Postgres एनवायरनमेंट से मेल नहीं खाते हैं। ध्यान दें कि POSTGRES_PASSWORD केवल तभी लागू होता है जब डेटा डायरेक्टरी पहली बार इनिशियलाइज़ की जाती है, इसलिए खराब फर्स्ट बूट के बाद वेरिएबल को ठीक करने से कुछ नहीं होगा। आपको db-data वॉल्यूम को हटाकर फिर से शुरू करना होगा।

लॉगिन सफल होता है लेकिन बोर्ड लोड नहीं होता है। BASE_URL ब्राउज़र बार में दिए गए पते से मेल नहीं खाता है, या TRUST_PROXY गायब है। ब्राउज़र कंसोल /socket.io/ पर विफल अनुरोधों को दिखाता है।

बाकी सब ठीक काम कर रहा है लेकिन अपलोड विफल हो रहे हैं। एक बाइंड माउंट का मालिक root है। होस्ट डायरेक्टरी पर sudo chown -R 1000:1000 चलाएं और कंटेनर को रीस्टार्ट करें।

अपग्रेड के बाद अटैचमेंट गायब हो गए हैं। /app/data किसी वॉल्यूम पर नहीं था, इसलिए फाइलें कंटेनर लेयर में थीं जिसे अपग्रेड के दौरान बदल दिया गया। बैकअप से फाइलें रिस्टोर करें, और इमेज टैग को दोबारा बदलने से पहले वॉल्यूम जोड़ें।

Traefik 404 त्रुटि देता है। कंटेनर proxy नेटवर्क पर नहीं है, या Host() नियम आपके DNS रिकॉर्ड से मेल नहीं खाता है। docker compose config प्रतिस्थापन के बाद लेबल दिखाता है, जहाँ टाइपो (typos) स्पष्ट हो जाते हैं।

नोटिफिकेशन या वेबहुक नहीं आ रहे हैं। Planka 2 अपने आउटगोइंग HTTP अनुरोधों को एक इंटरनल फिल्टर के माध्यम से भेजता है, और डिफ़ॉल्ट ब्लॉक लिस्ट में localhost और postgres शामिल हैं। उसी होस्ट पर किसी अन्य कंटेनर के लिए लक्षित वेबहुक को डिज़ाइन के अनुसार ब्लॉक किया जा सकता है। फिल्टर को हटाने के बजाय OUTGOING_ALLOWED_HOSTS को एडजस्ट करें।

एक बार चलने के बाद इसका ऑपरेशनल लोड कम होता है। रिलीज़ नोट्स पर नज़र रखें, और हर अपग्रेड से पहले डेटाबेस का डंप लें। restart: unless-stopped के कारण रीबूट होने पर स्टैक अपने आप वापस आ जाता है, बशर्ते Docker सर्विस खुद बूट पर इनेबल हो, और रीबूट के बाद वापस आने वाले Compose स्टैक उन मामलों को कवर करता है जहाँ ऐसा नहीं होता है।

FAQ

Planka login के बाद हमेशा लोड क्यों होता रहता है?

Credentials स्वीकार कर लिए गए थे लेकिन live connection नहीं हुआ। Planka अपना WebSocket URL BASE_URL से बनाता है, इसलिए यदि वह variable अभी भी http://localhost:3000 दिखाता है जबकि आप साइट को https://kanban.example.com पर access कर रहे हैं, तो browser एक ऐसे address पर socket खोलने की कोशिश करता है जो आपकी machine पर मौजूद नहीं है। Browser console में /socket.io/ के लिए failing 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 start करें, या 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 कहाँ store करता है?

Planka 2 में सभी uploaded files container के अंदर /app/data में रहती हैं, जिसमें attachments, user avatars और board backgrounds शामिल हैं। उस path को एक named volume पर mount करें। यदि यह unmounted है, तो files container की writable layer में रहती हैं और अगली बार container recreate होने पर नष्ट हो जाती हैं, जो हर image upgrade पर होता है। Bind mount भी काम करता है, लेकिन Node process UID 1000 के रूप में चलती है, इसलिए host directory पर sudo chown -R 1000:1000 चलाएँ अन्यथा uploads permission error के कारण विफल हो जाएंगे।

self-hosted Planka को कितनी RAM चाहिए?

Project कोई न्यूनतम hardware आवश्यकता प्रकाशित नहीं करता है। Hosting pages पर दोहराया गया 2 vCPU और 4 GB का आंकड़ा एक provider का default है, न कि कोई मापन, और यह एक छोटे board के लिए बहुत अधिक है। एक Node process और एक Postgres process ही पूरा workload है, इसलिए 1 vCPU और 2 GB का plan दो से पांच लोगों की टीम के लिए पर्याप्त है। एक सामान्य सप्ताह के बाद docker stats --no-stream चलाएँ और अपने आंकड़ों के आधार पर size तय करें। Memory की तुलना में disk पर अधिक ध्यान दें, क्योंकि attachments ही बढ़ते हैं।

मैं data खोए बिना Planka को upgrade कैसे करूँ?

Upgrade से ठीक पहले database का dump लें और uploads volume को archive करें, न कि पिछली रात के schedule पर। docker compose exec -T postgres pg_dump -U planka -d planka > planka-db.sql का उपयोग करें, और -T को बनाए रखें ताकि pseudo-terminal redirected output को corrupt न करे। जिन versions को आप छोड़ रहे हैं, उनके release notes पढ़ें, image tag को latest के बजाय किसी विशिष्ट release पर बदलें, फिर docker compose pull और docker compose up -d चलाएँ और migration के लिए log को monitor करें। Postgres tag को उसके major version पर ही pinned रहने दें, क्योंकि server किसी भिन्न major version द्वारा लिखे गए data directory को खोलने से मना कर देता है।