SSD Nodes Learn 🎉 VPS من $5.50/شهر
الأدلة Matt Connorبقلم Matt Connor · آخر تحديث في 2026-08-10

استضافة Planka ذاتياً باستخدام Docker Compose

انشر Planka على VPS عبر Docker Compose مع Postgres وTraefik، واضبط متغيرات إنشاء المدير وBASE_URL لتجنب خطأ تسجيل الدخول الناتج عن إعداد الرابط.

ما تحصل عليه من الاستضافة الذاتية لـPlanka

توفّر لك الاستضافة الذاتية لـPlanka لوحة Kanban لفريقك، باستخدام نموذج البطاقات والقوائم والتسميات الذي يعرفه المستخدمون من Trello، مع تشغيلها على VPS تتحكم به. لا توجد حدود لعدد المقاعد ولا فوترة لكل مستخدم، لأن التكلفة الوحيدة هي تكلفة الخادم. ينشر هذا الدليل التطبيق باستخدام Docker Compose خلف Traefik، مع استخدام Postgres لتخزين البيانات ووحدة تخزين مسماة لكل ملف يرفعه المستخدمون.

أفترض أن القارئ يدير فريقاً من شخصين إلى خمسة أشخاص ينتقلون من الخطة المجانية في Trello. إذا كنت لا تزال تقرر أي لوحة ستستخدم، فاقرأ أولاً مقارنة بدائل Trello ذاتية الاستضافة. يفترض هذا الدليل أن الاختيار قد حُسم، ويغطي عملية النشر فقط.

تحتاج إلى VPS يشغّل Docker Engine مع إضافة Compose، وإلى سجل DNS من النوع A يشير إليه. تحتاج أيضاً إلى مثيل Traefik مُعد مسبقاً لإنهاء TLS (أمان طبقة النقل) على ذلك الخادم. إذا لم يكن Traefik مُعداً بعد، فأنشئ أولاً Reverse Proxy باستخدام Traefik أمام عدة تطبيقات Compose، واقرأ أساسيات Docker Compose على VPS إذا بدا الملف أدناه غير مألوف.

كم يحتاج Planka من موارد VPS؟

لا ينشر المشروع حداً أدنى لمواصفات العتاد، لذلك تعامل مع أي رقم تقرؤه على أنه نقطة بداية، لا قياساً مؤكداً. إنّ مواصفة 2 vCPU و4 GB التي تكررها صفحات الاستضافة هي إعداد افتراضي مريح لدى مزود الخدمة، وليست متطلباً قاسه المشروع. وهي سخية بالنسبة إلى لوحة يستخدمها خمسة أشخاص.

ما يعمل فعلياً صغير الحجم: عملية Node.js واحدة تقدّم API والواجهة الأمامية المبنية، وعملية Postgres واحدة تخزّن البيانات. كما تعمل عملية proxy صغيرة ثالثة داخل حاوية Planka لتصفية طلباتها الصادرة. تكفي خطة بمواصفة 1 vCPU و2 GB للوحة يستخدمها شخصان إلى خمسة أشخاص، وتتحول معظم الذاكرة المتبقية إلى ذاكرة تخزين مؤقت لـPostgres.

حدّد حجم القرص قبل تحديد حجم الذاكرة، لأن المرفقات هي الجزء الذي ينمو. قِس مثيلك بنفسك بدلاً من الاعتماد على هذه الفقرة:

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

يعرض الأمر الأول الذاكرة ووحدة المعالجة المركزية المستخدمة حالياً لكل حاوية. ويعرض الأمر الثاني مقدار المساحة التي يشغلها كل volume. أجرِ القياسين بعد أسبوع عمل عادي، لا في يوم التثبيت، لأن لوحة خاملة لا تخبرك بشيء عن فريقك.

اكتب ملف Compose

أنشئ الدليل وغيّر مالكه، حتى لا تضطر إلى تحرير هذه الملفات من خلال sudo.

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

ولّد الأسرار في ملف .env بجانب ملف Compose. يقرأ Compose هذا الملف تلقائياً ويستبدل القيم.

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 التي تُلصق فيها. أمّا كلمة مرور base64 التي تحتوي على شرطة مائلة أو علامة at فتؤدي إلى خطأ اتصال يبدو كأنه اسم مضيف غير صحيح، وقد يكلّفك ذلك ساعة من العمل. يشرح إبقاء الأسرار خارج ملف 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:

تستحق أربعة قرارات في هذا الملف الشرح، لأنّها القرارات التي يغيّرها المستخدمون ثم يندمون عليها.

  • لا توجد كتلة ports: في خدمة Planka. يصل Traefik إلى الحاوية عبر شبكة proxy، لذلك لا يُنشر المنفذ 1337 على المضيف أبداً. نشره يتيح لأي شخص تجاوز الـproxy والشهادة الخاصة بك.
  • يحدد 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. تعني القيمة الفارغة أن Compose لا يقرأ ملف .env، ويحدث ذلك عادةً لأنك تنفّذ الأمر من دليل مختلف.

ما الذي تفعله متغيرات التهيئة الأولية لحساب admin فعلياً

منذ Planka 1.13، لا يُنشأ أي حساب مسؤول تلقائياً، لذلك لا يستطيع أحد تسجيل الدخول إلى قاعدة بيانات جديدة. تُعد مجموعة DEFAULT_ADMIN_* إحدى طريقتين لمعالجة ذلك.

عند بدء التشغيل، يبحث Planka عن مستخدم يطابق DEFAULT_ADMIN_EMAIL. إذا لم يعثر عليه، ينشئ مستخدماً باستخدام كلمة المرور واسم العرض واسم المستخدم المحددة إلى جانبه. يحدث ذلك عند أول تشغيل على قاعدة بيانات فارغة، لذلك تهيّئ هذه المتغيرات حساباً ولا تديره بعد ذلك.

ينفّذ DEFAULT_ADMIN_EMAIL مهمة ثانية قد تسبب الالتباس. ما دام المتغير مضبوطاً، لا يستطيع أي شخص تعديل الحساب الذي يحدده أو حذفه من الواجهة. هذا إجراء لمنع فقدان الوصول، وهو سبب عدم قدرتك أيضاً على إعادة تسمية ذلك الحساب أو تغيير عنوان بريده الإلكتروني من الواجهة. احذف المتغير وأعد التشغيل، فيصبح الحساب مسؤولاً عادياً يمكنك تعديله مثل أي حساب آخر.

يجب الانتباه إلى سطر كلمة المرور. يمكن لأي شخص يستطيع تنفيذ docker inspect على الحاوية قراءة أي قيمة تحت environment:، لذلك يجب ألا يبقى DEFAULT_ADMIN_PASSWORD هناك بشكل دائم. سجّل الدخول، وغيّر كلمة المرور من الواجهة، واحذف ذلك السطر، ثم نفّذ docker compose up -d مرة أخرى.

المسار الأنظف يتجاوز المتغيرات بالكامل. علّق مجموعة DEFAULT_ADMIN_* بأكملها، ثم أنشئ الحساب تفاعلياً:

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

يطلب الأمر عنوان البريد الإلكتروني وكلمة المرور واسم العرض واسم مستخدم اختيارياً، ثم يكتب المستخدم مباشرة إلى قاعدة البيانات. لا تمر كلمة المرور في ملف Compose أو في بيئة الحاوية. استخدم هذا المسار إذا كان أكثر من شخص يملك وصول shell إلى VPS. يبدأ الأمر PostgreSQL أولاً بسبب depends_on، لذلك يعمل على مكدس لم يُشغّل من قبل.

يتركك كلا المسارين مسؤولاً عن إدارة كلمات مرور Planka يدوياً. وإذا كانت هذه رابع مجموعة من بيانات الاعتماد يجمعها فريقك، فيمكن لـPlanka بدلاً من ذلك تفويض عمليات تسجيل الدخول إلى موفّر OIDC مثل Authentik الذي يعمل كخادم تسجيل دخول موحّد تديره بنفسك، مع الإبقاء على مسؤول التهيئة الأولية كحساب طوارئ لاستخدامه في اليوم الذي يتوقف فيه الموفّر.

لماذا يتسبب عدم تطابق BASE_URL مع اسم المضيف في تعطّل تسجيل الدخول

BASE_URL هو العنوان الكامل الذي يكتبه المستخدمون في المتصفح، مع scheme ومن دون شرطة مائلة في النهاية. في هذه الحزمة، يكون العنوان https://kanban.example.com. ينشئ Planka روابطه واتصال WebSocket اعتماداً على هذه القيمة، لذلك لا يؤدي ضبط BASE_URL بشكل خاطئ إلى ظهور خطأ واضح. بدلاً من ذلك، تُحمَّل الصفحة ثم لا يكتمل تحميلها أبداً.

الحالة الشائعة هي نسخ المثال المقدم من الجهة المورّدة وترك BASE_URL=http://localhost:3000 كما هو، ثم الوصول إلى الموقع عبر HTTPS باستخدام نطاقك الفعلي. يُرسل نموذج تسجيل الدخول وتُقبل بيانات الاعتماد. لكن اللوحة لا تظهر. افتح وحدة تحكم المطوّر في المتصفح، وسترى أن الطلبات إلى /socket.io/ تفشل، لأن العميل تلقى تعليمات بفتح اتصاله المباشر إلى localhost:3000، وهذا العنوان غير موجود إطلاقاً على حاسوبك المحمول.

TRUST_PROXY=true هو النصف الآخر من المشكلة نفسها. يعمل Planka خلف Traefik، لذلك يصل كل طلب إليه من عنوان الـproxy عبر HTTP غير المشفّر داخل شبكة Docker. من دون TRUST_PROXY، يتجاهل التطبيق رأسي X-Forwarded-Proto وX-Forwarded-For اللذين يضبطهما Traefik، ولذلك يعتقد أن الاتصال غير آمن ويعامل كل العملاء على أنهم يستخدمون عنوان IP واحداً مشتركاً. عند ضبطه، يقرأ التطبيق هذين الرأسين ويتطابق scheme لديه مع ما يراه المتصفح.

يعمل Traefik على تمرير WebSockets من دون إعداد إضافي، وهذا أحد أسباب تفضيله هنا. أما في nginx، فيحتاج socket.io إلى كتلة location مستقلة تتضمن proxy_set_header Upgrade $http_upgrade وproxy_set_header Connection "upgrade"، وإلا فستحصل على مؤشر التحميل العالق نفسه، ولكن لسبب مختلف.

نقل اللوحة إلى اسم مضيف جديد لاحقاً يتطلب تغيير أمرين معاً: قيمة BASE_URL وقاعدة Host() في Traefik. إذا غيّرت أحدهما ونسيت الآخر، فستعود إلى مؤشر التحميل العالق. يعمل تقديم Planka من مسار فرعي مثل https://example.com/planka ابتداءً من الإصدار 2.1.0، الذي صدر في March 2026. أما في الوسوم الأقدم، فامنحه نطاقاً فرعياً مستقلاً.

مكان احتفاظ Planka بالمرفقات والصور الرمزية

يخزّن Planka 2 كل ما يرفعه المستخدم تحت مسار واحد داخل الحاوية: /app/data. توجد المرفقات والصور الرمزية للمستخدمين وصور خلفيات اللوحات كلها تحته. كان الإصدار 1 يستخدم ثلاثة أدلة منفصلة، لذلك يربط ملف Compose المنسوخ من شرح أقدم مسارات لم تعد موجودة، ويظل دليل البيانات الفعلي من دون ربط.

هذا الربط الواحد هو ما يحدد بقاء اللوحة بعد الترقية أو التسبب في مشكلة كبيرة. إذا لم يكن /app/data موجوداً على volume، تُخزَّن الملفات المرفوعة في طبقة الكتابة الخاصة بالحاوية. تُحذف هذه الطبقة عند إعادة إنشاء الحاوية، وتُعاد الحاوية إلى الإنشاء كلما غيّرت وسم image. تعود اللوحة وتبدو سليمة، وتبقى جميع البطاقات موجودة، لكن كل رابط مرفق يصبح معطلاً، لأن صفوف قاعدة البيانات لا تزال تشير إلى ملفات لم تعد موجودة.

يمنع named volume الموجود في ملف Compose أعلاه حدوث ذلك. يعمل bind mount أيضاً، ويجعل نسخ الملفات احتياطياً باستخدام الأدوات المعتادة أسهل، لكنه يحتاج إلى خطوة إضافية. تعمل عملية Node داخل الحاوية باستخدام UID 1000، لذلك يؤدي وجود دليل على المضيف يملكه root إلى ظهور خطأ صلاحيات عند أول عملية رفع:

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

يشرح المقارنة بين bind mounts وnamed volumes المفاضلة بين الخيارين.

إذا تجاوزت المرفقات سعة القرص المتاحة في خطتك، يستطيع Planka كتابتها إلى مساحة تخزين متوافقة مع S3 بدلاً من ذلك، من خلال S3_ENDPOINT وS3_BUCKET ومتغيرات المفاتيح المطابقة. ويمكن أن يشير ذلك إلى bucket مستضاف أو إلى مخزن كائنات MinIO مستضاف ذاتياً على خادم آخر. اتخذ هذا القرار قبل أن يملأ الفريق اللوحة، لأن الإعداد ينطبق على الملفات المرفوعة الجديدة.

شغّل الحزمة وتحقق من نجاحها

docker compose pull
docker compose up -d
docker compose ps

يجب أن يعرض docker compose ps القيمة postgres على أنّها healthy، والقيمة planka على أنّها running. إذا كان Planka يعيد التشغيل في حلقة، فتحقق أولاً من اتصال قاعدة البيانات، وليس من التطبيق.

docker compose logs -f planka

تُجري عملية الإقلاع الأولى السليمة ترحيلات قاعدة البيانات، ثم تعرض رسالة تفيد بأن الخادم يستمع على المنفذ 1337. تحقّق من تطبيق المخطط فعلياً عبر الاستعلام من Postgres مباشرة، بدلاً من الاعتماد على السجل:

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

تعني قائمة الجداول التي تتضمن board وcard أنّ الترحيلات نُفّذت. تعني الرسالة "Did not find any relations" أنّ Planka لم يتصل بقاعدة البيانات قط، لذا قارن DATABASE_URL بقيمتي POSTGRES_USER وPOSTGRES_PASSWORD في .env.

ثم اختبر المسار من جهازك أنت، وليس من VPS:

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

تعني HTTP/2 200 أنّ Traefik يحتفظ بشهادة وأنّه يصل إلى الحاوية. تعني استجابة 404 التي يقدّمها Traefik أنّ تسميات الموجّه لم تتطابق، وغالباً لأنّ الحاوية غير متصلة بشبكة proxy. افتح الموقع الآن وسجّل الدخول باستخدام حساب المسؤول.

نفّذ pg_dump قبل كل ترقية للإصدار

تُخزَّن بيانات لوحة التحكم في مخزنين منفصلين، لذلك يجب أن تشمل النسخة الاحتياطية كلاً من قاعدة بيانات Postgres ووحدة التخزين planka-data. نفّذ تفريغ قاعدة البيانات أثناء تشغيل الحزمة.

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

إن -T إلزامي. بدونه يخصّص Compose طرفيةً زائفة، وتعيد طبقة الطرفية كتابة نهايات الأسطر في الدفق، فتحصل على ملف تفريغ يفشل في منتصف عملية الاستعادة. يظهر الفشل بعد أسابيع، وهذا أسوأ وقت ممكن لاكتشافه.

ثم انسخ الملفات المرفوعة. اعثر أولاً على اسم وحدة التخزين الفعلي، لأن Compose يسبقه باسم دليل المشروع.

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 في مستودعه، وتضع الوثائق الرسمية هذه الملفات ضمن مهمة cron ليلية. كلا الأسلوبين مناسب. لكن النسخة الاحتياطية التي لم تختبر استعادتها ليست مناسبة. لذلك استعد نسخة منها مرة واحدة على VPS مخصّص للاختبار، وتأكد من قدرتك على تسجيل الدخول وفتح مرفق.

نفّذ التفريغ مباشرة قبل كل تغيير في الإصدار. فالنسخة الاحتياطية التي أُنشئت الليلة الماضية ليست النسخة الاحتياطية التي أُنشئت قبل عملية الترحيل التي توشك على تشغيلها.

ثبّت الوسوم واقرأ ملاحظات الإصدار

وسما الصورة في هذا الملف مثبتان عن قصد.

ghcr.io/plankanban/planka:2.1.1 إصدار محدد، وهو الإصدار الحالي حتى August 2026. أما latest فيتغير كلما نشر المشروع الأصلي إصداراً جديداً، لذلك قد تؤدي عملية docker compose pull دورية إلى تطبيق ترحيل لمخطط قاعدة البيانات في وقت لم تختره. اقرأ ملاحظات الإصدار قبل تغيير هذا الرقم، لأنها توضّح التغييرات غير المتوافقة وإصلاحات الأمان. نُشر الإصدار 2.0.3 كإصدار أمني، وهذا تحديداً من الأمور التي ينبغي قراءتها بدلاً من تطبيقها بالصدفة.

يُثبّت postgres:16-alpine على إصدار رئيسي لسبب أكثر أهمية. يكتب 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 التسميات بعد استبدال المتغيرات، وهناك تظهر الأخطاء الإملائية.

لا تصل الإشعارات أو webhooks أبداً. يرسل Planka 2 طلبات HTTP الصادرة عبر مرشح داخلي، وتشمل قائمة الحظر الافتراضية localhost وpostgres. قد يُحظر webhook الموجّه إلى حاوية أخرى على المضيف نفسه عن قصد. عدّل OUTGOING_ALLOWED_HOSTS بدلاً من إزالة المرشح.

بعد تشغيله، يكون العبء التشغيلي صغيراً. راقب ملاحظات الإصدار، وأنشئ نسخة من قاعدة البيانات قبل كل ترقية. تعيد إعادة التشغيل المكدس تلقائياً بسبب restart: unless-stopped، ما دام Docker مفعّلاً عند الإقلاع، ويغطي مكدسات Compose التي تعود بعد إعادة التشغيل الحالات التي لا يحدث فيها ذلك.

FAQ

لماذا يظل Planka في حالة تحميل مستمر بعد تسجيل الدخول؟

تم قبول بيانات الاعتماد، لكن الاتصال المباشر لم يُنشأ. ينشئ Planka عنوان URL الخاص بـWebSocket من BASE_URL، لذلك إذا بقي هذا المتغير مضبوطاً على http://localhost:3000 بينما تصل إلى الموقع عبر https://kanban.example.com، يحاول المتصفح فتح مقبس إلى عنوان غير موجود على جهازك. يعرض console المطوّر طلبات فاشلة إلى /socket.io/. اضبط BASE_URL على العنوان العام الدقيق من دون شرطة مائلة في النهاية، وأضف TRUST_PROXY=true لكي يلتزم التطبيق بالرأس X-Forwarded-Proto الذي يرسله Reverse Proxy، ثم شغّل docker compose up -d.

كيف أنشئ مستخدم Planka الإداري الأول؟

منذ الإصدار 1.13، لا يُنشأ أي مسؤول تلقائياً. يمكنك إما ضبط DEFAULT_ADMIN_EMAIL مع متغيرات كلمة المرور والاسم واسم المستخدم المطابقة له ثم بدء الـstack، أو تشغيل docker compose run --rm planka npm run db:create-admin-user والإجابة عن المطالبات. يُعد الأمر التفاعلي أكثر أماناً على الخادم المشترك، لأن كلمة المرور لا تدخل إلى بيئة الحاوية حيث يستطيع docker inspect قراءتها. يؤدي إبقاء DEFAULT_ADMIN_EMAIL مضبوطاً بعد ذلك إلى منع تعديل هذا الحساب وحذفه من الواجهة.

أين يخزّن Planka المرفقات والصور الرمزية؟

توجد جميع الملفات المرفوعة ضمن /app/data داخل الحاوية في Planka 2، بما في ذلك المرفقات والصور الرمزية للمستخدمين وخلفيات اللوحات. اربط هذا المسار بوحدة تخزين مسماة. إذا لم تكن الوحدة مركّبة، تبقى الملفات في طبقة الكتابة الخاصة بالحاوية وتُحذف عند إعادة إنشاء الحاوية في المرة التالية، ويحدث ذلك مع كل ترقية للصورة. يعمل bind mount أيضاً، لكن عملية Node تعمل بالمعرّف UID 1000، لذلك شغّل sudo chown -R 1000:1000 على دليل المضيف، وإلا تفشل عمليات الرفع بسبب خطأ في الصلاحيات.

ما مقدار RAM الذي يحتاج إليه Planka المستضاف ذاتياً؟

لا ينشر المشروع حداً أدنى لمواصفات العتاد. إن قيمة 2 vCPU و4 GB المتكررة في صفحات الاستضافة هي إعداد افتراضي لدى مزود الخدمة، وليست نتيجة قياس، وهي سخية بالنسبة إلى لوحة صغيرة. تتكون أعباء العمل بالكامل من عملية Node واحدة وعملية Postgres واحدة، لذلك تكفي خطة بمواصفات 1 vCPU و2 GB لفريق يتراوح عدده بين شخصين وخمسة أشخاص. شغّل docker stats --no-stream بعد أسبوع عادي، وحدد الحجم استناداً إلى أرقامك الفعلية. راقب القرص باهتمام أكبر من الذاكرة، لأن المرفقات هي التي تنمو.

كيف أرقّي Planka من دون فقدان البيانات؟

أفرغ قاعدة البيانات وأرشف وحدة تخزين الملفات المرفوعة مباشرة قبل الترقية، وليس وفق الجدول المجدول لليلة السابقة. استخدم docker compose exec -T postgres pg_dump -U planka -d planka > planka-db.sql، مع الإبقاء على -T حتى لا تتسبب pseudo-terminal في إتلاف المخرجات المعاد توجيهها. اقرأ ملاحظات الإصدار لكل إصدار تتجاوزه، وغيّر وسم الصورة إلى إصدار محدد بدلاً من latest، ثم شغّل docker compose pull وdocker compose up -d وراقب السجل بحثاً عن عملية الترحيل. أبقِ وسم Postgres مثبتاً على إصداره الرئيسي، لأن الخادم يرفض فتح دليل بيانات كُتب بواسطة إصدار رئيسي مختلف.