SSD Nodes Learn 🎉 VPS החל מ־$5.50/חודש
מדריכים Matt Connorמאת Matt Connor · עודכן 2026-08-13

אירוח עצמי של Planka: מדריך התקנה ב-Docker Compose

למדו כיצד לפרוס את Planka על שרת VPS עם Postgres ו-Traefik. המדריך כולל הגדרות משתני סביבה קריטיים ופתרון לבעיית ה-BASE_URL שגורמת לכשלים בהתחברות למערכת הניהול.

מה מקבלים מאירוח עצמי של Planka

אירוח עצמי של Planka מעניק לצוות שלכם לוח Kanban עם מודל של כרטיסים, רשימות ותוויות שמוכר למשתמשים מ-Trello, כשהוא רץ על שרת VPS שבשליטתכם. אין הגבלת משתמשים ואין חיוב לפי משתמש, שכן העלות היחידה היא השרת עצמו. מדריך זה פורס את המערכת באמצעות Docker Compose מאחורי Traefik, תוך שימוש ב-Postgres עבור הנתונים וב-named volume עבור כל קובץ שמשתמשים מעלים.

קהל היעד של מדריך זה הוא צוותים של שניים עד חמישה אנשים העוזבים את המסלול החינמי של Trello. אם אתם עדיין מתלבטים באיזו מערכת לוחות לבחור, קראו תחילה את השוואת החלופות ל-Trello באירוח עצמי. מדריך זה מניח שההחלטה כבר התקבלה ומתמקד אך ורק בתהליך הפריסה.

עליכם להחזיק שרת VPS המריץ את Docker Engine עם תוסף ה-Compose, ורשומת DNS מסוג A המצביעה אליו. כמו כן, עליכם להחזיק מופע של Traefik שכבר מבצע TLS termination על אותו שרת. אם Traefik אינו מוגדר עדיין, הקימו תחילה reverse proxy מסוג Traefik לפני מספר יישומי Compose, וקראו את יסודות Docker Compose עבור VPS אם הקובץ להלן אינו מוכר לכם.

כמה משאבי VPS נדרשים עבור Planka?

הפרויקט אינו מפרסם דרישות חומרה מינימליות, לכן יש להתייחס לכל נתון כנקודת התחלה ולא כמדידה מחייבת. הנתון של 2 vCPU ו־4 GB שמופיע לעיתים קרובות בדפי אירוח הוא ברירת מחדל נוחה של ספקיות, ולא דרישה שהפרויקט הגדיר. מדובר במשאבים נדיבים עבור לוח עבודה שמשתמשים בו חמישה אנשים.

מה שרץ בפועל הוא קטן: תהליך Node.js אחד שמגיש את ה-API ואת ה-frontend המהודר, ותהליך Postgres אחד שמחזיק את הנתונים. תהליך proxy שלישי וקטן רץ בתוך ה-container של Planka כדי לסנן את הבקשות היוצאות ממנו. תוכנית של 1 vCPU ו-2 GB מספיקה ללוח של שניים עד חמישה אנשים, ורוב הזיכרון הפנוי משמש כ-cache עבור Postgres.

קבעו את גודל הדיסק לפני שאתם קובעים את גודל הזיכרון, כיוון שקבצים מצורפים הם החלק שגדל. מדדו את המופע שלכם במקום להסתמך על פסקה זו:

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

הפקודה הראשונה מציגה את צריכת הזיכרון וה-CPU בזמן אמת לכל container. השנייה מציגה כמה מקום תופס כל volume. בצעו את שתי המדידות לאחר שבוע עבודה רגיל, ולא ביום ההתקנה, כיוון שלוח עבודה במצב סרק אינו מעיד על דפוסי השימוש של הצוות שלכם.

כתיבת קובץ ה-Compose

צרו את הספרייה וקחו עליה בעלות, כדי שלא תצטרכו לערוך את הקבצים הללו דרך sudo.

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

צרו את ה-secrets בתוך קובץ .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 הוא מכוון. מחרוזת hex מכילה רק ספרות ואת האותיות a עד f, לכן היא לא יכולה לשבש את מחרוזת החיבור של DATABASE_URL שאליה היא מוכנסת. סיסמת base64 המכילה לוכסן או סימן שטרודל מייצרת שגיאת חיבור שנראית כמו שם מארח שגוי, וזה עולה לכם בשעה של עבודה. התבנית הרחבה יותר מוסברת ב-שמירה על secrets מחוץ לקובץ ה-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 משתלב עם ה-healthcheck של Postgres. בלעדיו Planka עולה לפני שהמסד נתונים מקבל חיבורים, נכשל בשאילתה הראשונה ונסגר, מה שנראה כמו לולאת קריסה. המנגנון מוסבר ב-בדיקות תקינות וסדר עלייה ב-Compose.
  • שירות מסד הנתונים נקרא postgres בכוונה. Planka 2 מנתב את הבקשות היוצאות שלו דרך מסנן פנימי שרשימת החסימה המוגדרת כברירת מחדל שלו היא localhost,postgres. שינוי שם השירות יסיר בשקט את מסד הנתונים שלכם מהרשימה הזו.

בדקו ש-Compose יכול לראות את ה-secrets שלכם לפני שאתם מתחילים:

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

פעולה זו מדפיסה את הקובץ כאשר ערכי .env כבר מוצבים בו. ערך ריק אומר ש-Compose לא קורא את קובץ ה-.env, בדרך כלל בגלל שאתם מריצים את הפקודה מספרייה אחרת.

מה עושים בפועל משתני ה-bootstrap של מנהל המערכת

החל מגרסה 1.13 של Planka, לא נוצר מנהל מערכת אוטומטית, ולכן במסד נתונים חדש אין אף משתמש שיכול להתחבר. קבוצת המשתנים DEFAULT_ADMIN_* היא אחת משתי הדרכים לפתור זאת.

בעת העלייה, Planka מחפשת משתמש התואם ל-DEFAULT_ADMIN_EMAIL. אם לא נמצא כזה, היא יוצרת משתמש חדש באמצעות הסיסמה, שם התצוגה ושם המשתמש שהוגדרו לצדו. פעולה זו מתבצעת רק בעלייה הראשונה מול מסד נתונים ריק, ולכן משתנים אלו משמשים לאתחול (bootstrap) של חשבון ולא לניהולו השוטף.

למשתנה DEFAULT_ADMIN_EMAIL יש תפקיד נוסף שלעיתים גורם לבלבול. כל עוד המשתנה מוגדר, לא ניתן לערוך או למחוק את החשבון שצוין בו דרך ממשק המשתמש. זהו מנגנון הגנה מפני נעילה, וזו הסיבה שלא ניתן לשנות את שם המשתמש או את כתובת האימייל שלו ב-UI. הסירו את המשתנה ובצעו הפעלה מחדש; לאחר מכן, החשבון יהפוך לחשבון מנהל רגיל שניתן לערוך ככל חשבון אחר.

יש לנהוג בזהירות עם שורת הסיסמה. כל תוכן תחת environment: נגיש לכל מי שיכול להריץ docker inspect על המכולה, ולכן DEFAULT_ADMIN_PASSWORD לא אמור להישאר שם באופן קבוע. התחברו למערכת, שנו את הסיסמה דרך הממשק, מחקו את השורה, ולאחר מכן הריצו שוב את docker compose up -d.

הדרך הנקייה יותר היא לוותר על המשתנים כליל. בצעו comment לכל קבוצת DEFAULT_ADMIN_*, ולאחר מכן צרו את החשבון באופן אינטראקטיבי:

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

הפקודה תבקש אימייל, סיסמה, שם תצוגה ושם משתמש אופציונלי, ותכתוב את המשתמש ישירות למסד הנתונים. הסיסמה לעולם לא מגיעה לקובץ ה-Compose או לסביבת המכולה. השתמשו בדרך זו אם ליותר מאדם אחד יש גישת shell ל-VPS. הפקודה מפעילה את Postgres תחילה בגלל depends_on, כך שהיא עובדת גם על stack שמעולם לא הופעל.

שתי הדרכים משאירות את ניהול הסיסמאות של Planka בידיכם. אם זהו סט האישורים הרביעי שהצוות שלכם אוסף, Planka יכולה להאציל את תהליך ההתחברות לספק OIDC, כגון Authentik הפועל כשרת Single Sign-On עצמאי, כאשר מנהל המערכת שנוצר ב-bootstrap נשמר כחשבון גישת חירום למקרה שספק ה-SSO אינו זמין.

מדוע 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, לכן כל בקשה מגיעה אליה מכתובת ה-proxy דרך HTTP רגיל בתוך רשת ה-Docker. ללא TRUST_PROXY, היישום מתעלם מה-headers מסוג X-Forwarded-Proto ו-X-Forwarded-For ש-Traefik מגדיר, ולכן הוא סבור שהחיבור אינו מאובטח ומתייחס לכל לקוח כאל כתובת IP משותפת אחת. כאשר הערך מוגדר, היישום קורא את ה-headers הללו ומסכים עם הדפדפן לגבי הסכימה.

Traefik מבצע proxy ל-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, ששוחררה במרץ 2026. בתגיות ישנות יותר, הקצו לה דומיין משנה משלה.

היכן Planka שומרת קבצים מצורפים ואווטארים

Planka 2 שומרת את כל מה שמשתמש מעלה תחת נתיב יחיד בתוך המכולה: /app/data. קבצים מצורפים, אווטארים של משתמשים ותמונות רקע של לוחות – כולם נמצאים תחת נתיב זה. גרסה 1 השתמשה בשלוש ספריות נפרדות, לכן קובץ Compose שהועתק ממדריך ישן עשוי להגדיר mount לנתיבים שכבר אינם קיימים, מה שמותיר את ספריית הנתונים האמיתית ללא מיפוי.

ה־mount היחיד הזה הוא ההבדל בין לוח ששורד שדרוג לבין אובדן נתונים. אם /app/data אינו מוגדר כ-volume, העלאות נשמרות בשכבת ה-writable של המכולה. שכבה זו נמחקת בכל פעם שהמכולה נוצרת מחדש, והמכולה נוצרת מחדש בכל פעם שמשנים את תגית ה-image. הלוח יחזור להיראות תקין, הכרטיסים יהיו שם, אך כל קישור לקובץ מצורף יהיה שבור, כיוון ששורות מסד הנתונים עדיין מצביעות על קבצים שכבר אינם קיימים.

ה-named volume בקובץ ה-Compose לעיל מונע זאת. גם bind mount יעבוד ויקל על גיבוי הקבצים באמצעות כלים סטנדרטיים, אך הוא דורש צעד נוסף. תהליך ה-Node בתוך המכולה רץ תחת UID 1000, לכן ספרייה במארח (host) שבבעלות root תגרום לשגיאת הרשאות בהעלאה הראשונה:

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

השיקולים בבחירה בין השניים מפורטים ב-השוואה בין bind mounts ל-named volumes.

אם הקבצים המצורפים תופסים נפח גדול מהדיסק בתוכנית שלכם, Planka יכולה לכתוב אותם לאחסון תואם S3, באמצעות S3_ENDPOINT, S3_BUCKET ומשתני המפתח התואמים. אלו יכולים להצביע על bucket מאוחסן או על אחסון אובייקטים MinIO בניהול עצמי בשרת אחר. החליטו על כך לפני שהצוות מתחיל למלא את הלוח, כיוון שההגדרה חלה על העלאות חדשות בלבד.

הפעלת ה-stack ובדיקת תקינותו

docker compose pull
docker compose up -d
docker compose ps

הפקודה docker compose ps אמורה להציג את postgres כ-healthy ואת planka כ-running. אם Planka נמצא בלולאת אתחול, הדבר הראשון שיש לבדוק הוא החיבור למסד הנתונים, ולא את היישום עצמו.

docker compose logs -f planka

עלייה תקינה בפעם הראשונה מריצה את ה-migrations של מסד הנתונים ומדווחת שהשרת מאזין בפורט 1337. ודאו שה-schema אכן נוצרה על ידי פנייה ישירה ל-Postgres, במקום להסתמך על הלוג:

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

רשימת טבלאות הכוללת את board ו-card מעידה על כך שה-migrations רצו בהצלחה. השגיאה "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 מעידה על כך שתוויות ה-router לא תואמות, לרוב בגלל שהמכולה אינה מחוברת לרשת proxy. כעת פתחו את האתר והתחברו עם חשבון ה-admin.

בצעו pg_dump לפני כל שדרוג גרסה

שני מאגרי נתונים נפרדים מאחסנים את הלוח שלכם, לכן גיבוי חייב לכסות את שניהם: מסד הנתונים Postgres ואת הנפח (volume) של planka-data. בצעו dump למסד הנתונים בזמן שה-stack פעיל.

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

הדגל -T אינו אופציונלי. בלעדיו, Compose מקצה pseudo-terminal, ושכבת הטרמינל משכתבת את סיומות השורות בזרם הנתונים; כתוצאה מכך מתקבל קובץ dump שנכשל באמצע תהליך השחזור. הכשל מופיע שבועות לאחר מכן, שזהו התזמון הגרוע ביותר האפשרי.

לאחר מכן, בצעו גיבוי לקבצים שהועלו (uploads). מצאו תחילה את שם ה-volume האמיתי, כיוון ש-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 job לילי. כל אחת מהגישות הללו תקינה. מה שאינו תקין הוא גיבוי שמעולם לא שוחזר; לכן, שחזרו גיבוי אחד לשרת VPS זמני פעם אחת, וודאו שניתן להתחבר ולפתוח קובץ מצורף.

הריצו את ה-dump מיד לפני כל שינוי גרסה. גיבוי מאתמול בלילה אינו זהה לגיבוי שבוצע לפני המיגרציה שאתם עומדים להריץ.

קיבוע תגיות וקריאת הערות השחרור

שתי תגיות ה-image בקובץ זה מקובעות בכוונה תחילה.

ghcr.io/plankanban/planka:2.1.1 הוא שחרור ספציפי, העדכני נכון לאוגוסט 2026. latest משתנה בכל פעם שהספק מפרסם גרסה חדשה, לכן docker compose pull שגרתי עלול להוביל להרצת migration של סכימה ברגע שלא בחרת בו. קראו את הערות השחרור לפני שינוי מספר זה, שכן שם מתוארים שינויים שוברים ותיקוני אבטחה. גרסה 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 מחייב ביצוע dump מהגרסה הישנה ושחזור לתוך ספריית נתונים נקייה בגרסה החדשה. זוהי משימה מתוכננת שמתבצעת כשה-stack מושבת, ולא תופעת לוואי של משיכת image.

אם אתם מעבירים התקנת Planka 1.x קיימת במקום להתחיל מאפס, לשדרוג זה יש נוהל מתועד ב-תיעוד הפרויקט, ואין דרך חזרה לגרסה 1 ללא גיבוי שנלקח מראש.

מצבי כשל והודעות שגיאה נפוצות

Planka מבצע אתחול בלולאה והלוג מציין את מסד הנתונים. פרטי ההתחברות ב-DATABASE_URL אינם תואמים לסביבת ה-Postgres. שימו לב ש-POSTGRES_PASSWORD מיושם רק בעת אתחול ראשוני של תיקיית הנתונים, לכן תיקון המשתנה לאחר אתחול ראשון שגוי לא יועיל. עליכם להסיר את ה-volume ב-db-data ולהתחיל מחדש.

ההתחברות מצליחה אך הלוח אינו נטען. הכתובת ב-BASE_URL אינה תואמת לכתובת בשורת הכתובות בדפדפן, או ש-TRUST_PROXY חסר. מסוף הדפדפן מציג בקשות שנכשלו ל-/socket.io/.

העלאת קבצים נכשלת בעוד שאר הפונקציות עובדות. מדובר ב-bind mount שבבעלות root. הריצו את sudo chown -R 1000:1000 על תיקיית ה-host והפעילו מחדש את ה-container.

קבצים מצורפים נעלמו לאחר שדרוג. התיקייה /app/data לא הייתה על volume, לכן הקבצים נשמרו בשכבת ה-container שהוחלפה במהלך השדרוג. שחזרו את הקבצים מגיבוי, ולאחר מכן הוסיפו את ה-volume לפני שתשנו שוב את תגית ה-image.

Traefik מחזיר שגיאת 404. ה-container אינו מחובר לרשת proxy, או שכלל ה-Host() אינו תואם לרשומת ה-DNS שלכם. הפקודה docker compose config מציגה את ה-labels לאחר החלפת המשתנים, שם ניתן לזהות שגיאות הקלדה.

התראות או webhooks אינם מגיעים. גרסה 2 של Planka שולחת בקשות HTTP יוצאות דרך מסנן פנימי, ורשימת החסימה המוגדרת כברירת מחדל כוללת את localhost ו-postgres. webhook המופנה ל-container אחר על אותו host עלול להיחסם כחלק מהתכנון. התאימו את OUTGOING_ALLOWED_HOSTS במקום להסיר את המסנן.

לאחר שהשירות פועל, העומס התפעולי נמוך. עקבו אחר הערות השחרור (release notes), ובצעו dump למסד הנתונים לפני כל שדרוג. אתחול של השרת יחזיר את ה-stack לפעולה באופן אוטומטי בזכות restart: unless-stopped, כל עוד שירות ה-Docker עצמו מוגדר לעלות באתחול, והמדריך Compose stacks that come back after a reboot מכסה את המקרים שבהם זה לא קורה.

FAQ

מדוע Planka נטען ללא סוף לאחר ההתחברות?

פרטי ההתחברות התקבלו, אך החיבור החי (live connection) נכשל. Planka בונה את כתובת ה-WebSocket שלו מתוך BASE_URL. אם משתנה זה עדיין מוגדר כ-http://localhost:3000 בזמן שאתם ניגשים לאתר דרך https://kanban.example.com, הדפדפן ינסה לפתוח socket לכתובת שאינה קיימת במכונה שלכם. מסוף המפתחים (developer console) יציג בקשות שנכשלו ל-/socket.io/. הגדירו את BASE_URL לכתובת הציבורית המדויקת ללא לוכסן בסוף, הוסיפו את TRUST_PROXY=true כדי שהיישום יכבד את ה-header מסוג X-Forwarded-Proto מה-reverse proxy שלכם, ולאחר מכן הריצו את docker compose up -d.

כיצד יוצרים את משתמש ה-admin הראשון ב-Planka?

החל מגרסה 1.13 לא נוצר מנהל מערכת באופן אוטומטי. ניתן להגדיר את DEFAULT_ADMIN_EMAIL יחד עם משתני הסיסמה, השם ושם המשתמש התואמים ולהפעיל את ה-stack, או להריץ את docker compose run --rm planka npm run db:create-admin-user ולענות על ההנחיות. הפקודה האינטראקטיבית בטוחה יותר בשרת משותף, כיוון שהסיסמה אינה נכנסת לסביבת ה-container שבה docker inspect יכול לקרוא אותה. השארת DEFAULT_ADMIN_EMAIL מוגדר לאחר מכן תנעל את החשבון מפני עריכה ומחיקה דרך הממשק.

היכן Planka שומר קבצים מצורפים ותמונות פרופיל?

כל הקבצים שהועלו נמצאים תחת /app/data בתוך ה-container ב-Planka 2, כולל קבצים מצורפים, תמונות פרופיל של משתמשים ורקעים ללוחות. בצעו mount לנתיב זה על גבי volume בעל שם. אם הוא לא מחובר (unmounted), הקבצים יישמרו בשכבת ה-writable של ה-container וייהרסו בפעם הבאה שה-container ייווצר מחדש, דבר שקורה בכל שדרוג image. גם bind mount יעבוד, אך תהליך ה-Node רץ תחת UID 1000, לכן הריצו את sudo chown -R 1000:1000 על תיקיית ה-host, אחרת העלאות ייכשלו בשל שגיאת הרשאות.

כמה זיכרון RAM דורש Planka באירוח עצמי?

הפרויקט אינו מפרסם דרישות חומרה מינימליות. הנתון של 2 vCPU ו-4 GB שחוזר על עצמו בדפי אירוח הוא ברירת מחדל של ספק ולא מדידה בפועל, והוא נדיב מאוד עבור לוח קטן. תהליך Node אחד ותהליך Postgres אחד הם כל עומס העבודה, לכן תוכנית של 1 vCPU ו-2 GB תספיק לצוות של שניים עד חמישה אנשים. הריצו את docker stats --no-stream לאחר שבוע עבודה רגיל וקבעו את הגודל לפי הנתונים שלכם. עקבו אחר הדיסק יותר מאשר אחר הזיכרון, כיוון שהקבצים המצורפים הם אלו שגדלים.

כיצד משדרגים את Planka מבלי לאבד נתונים?

בצעו dump למסד הנתונים וגבו את ה-volume של ההעלאות מיד לפני השדרוג, לא לפי לוח הזמנים של הלילה הקודם. השתמשו ב-docker compose exec -T postgres pg_dump -U planka -d planka > planka-db.sql, תוך שמירה על -T כדי שה-pseudo-terminal לא ישבש את הפלט המופנה. קראו את הערות השחרור (release notes) עבור כל גרסה שאתם מדלגים עליה, שנו את ה-tag של ה-image לגרסה ספציפית במקום latest, ולאחר מכן הריצו את docker compose pull ו-docker compose up -d ועקבו אחר הלוג עבור ה-migration. השאירו את ה-tag של Postgres נעול על גרסת ה-major שלו, כיוון שהשרת יסרב לפתוח תיקיית נתונים שנכתבה על ידי גרסת major אחרת.