SSD Nodes Learn Hosting plans →
Anleitungen Matt ConnorVon Matt Connor

Planka selbst hosten: Kanban-Board mit Docker Compose

So installieren Sie Planka 2 auf einem VPS mit Docker Compose, Postgres und Traefik. Wichtig: BASE_URL und Admin-Variablen, sonst schlagen Logins fehl.

Was Sie durch das Self-Hosting von Planka erhalten

Mit dem Self-Hosting von Planka erhält Ihr Team ein Kanban-Board mit dem Karten-, Listen- und Label-Modell, das viele bereits aus Trello kennen, auf einem von Ihnen kontrollierten VPS. Es gibt keine Beschränkung der Anzahl von Benutzern und keine Abrechnung pro Benutzer, weil nur die Kosten für den Server anfallen. In dieser Anleitung wird Planka mit Docker Compose hinter Traefik bereitgestellt. Postgres speichert die Daten, und ein benanntes Volume nimmt alle von Benutzern hochgeladenen Dateien auf.

Planka 2 wird unter der eigenen Fair Use License des Projekts veröffentlicht. Das Projekt bezeichnet diese Lizenz als source-available und nicht als Open Source. Der Betrieb für interne Projekte der eigenen Organisation ist zulässig. Wenn Sie Planka Dritten als kommerziellen gehosteten Dienst anbieten, benötigen Sie eine Pro- oder Enterprise-Lizenz.

Die Anleitung richtet sich an ein Team mit zwei bis fünf Personen, das den kostenlosen Tarif von Trello verlässt. Wenn Sie noch entscheiden, welches Board Sie einsetzen möchten, lesen Sie zuerst den Vergleich selbst gehosteter Trello-Alternativen. Diese Anleitung setzt voraus, dass die Entscheidung bereits getroffen wurde, und behandelt nur die Bereitstellung.

Sie benötigen einen VPS mit Docker Engine und dem Compose-Plugin sowie einen DNS-A-Eintrag, der auf diesen Server zeigt. Außerdem muss auf diesem Server bereits eine Traefik-Instanz TLS (Transport Layer Security) terminieren. Wenn Traefik noch nicht vorhanden ist, richten Sie zuerst einen Traefik-Reverse-Proxy vor mehreren Compose-Anwendungen ein. Lesen Sie außerdem die Grundlagen von Docker Compose für einen VPS, wenn Ihnen die folgende Datei nicht vertraut ist.

Wie viel VPS benötigt Planka?

Das Projekt veröffentlicht keine Mindestanforderungen an die Hardware. Betrachten Sie daher jede genannte Zahl als Ausgangspunkt und nicht als Messwert. Die Angaben mit 2 vCPU und 4 GB, die sich auf Hosting-Seiten wiederholen, sind ein komfortabler Standardwert des Anbieters und keine vom Projekt gemessene Anforderung. Für ein Board, das von fünf Personen verwendet wird, ist das großzügig bemessen.

Tatsächlich laufen nur wenige Komponenten: ein Node.js-Prozess stellt die API und das erstellte Frontend bereit, und ein Postgres-Server speichert die Daten. Dieser führt einen überwachenden Prozess sowie für jede offene Verbindung einen Backend-Prozess aus. Im Planka-Container läuft außerdem ein kleiner Proxy-Prozess, der ausgehende Anfragen filtert. Ein Tarif mit 1 vCPU und 2 GB reicht für ein Board mit zwei bis fünf Personen aus. Der größte Teil des freien Speichers wird von Postgres als Cache verwendet. Ein Board benötigt nur wenige Ressourcen. Wenn auf demselben VPS auch die Dokumente Ihres Teams liegen sollen, dimensionieren Sie zuerst für diese Anwendung: AFFiNE als Notion-ähnlichen Arbeitsbereich betreiben benötigt bereits für sich einige Gigabyte, bevor Planka Ressourcen beansprucht.

Dimensionieren Sie den Speicherplatz, bevor Sie den Arbeitsspeicher dimensionieren, weil Anhänge am stärksten wachsen. Messen Sie Ihre eigene Instanz, anstatt diesem Absatz zu vertrauen:

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

Der erste Befehl zeigt den aktuellen Speicher- und CPU-Verbrauch pro Container. Der zweite zeigt, wie viel Speicherplatz jedes Volume enthält. Führen Sie beide Messungen nach einer normalen Arbeitswoche durch und nicht am Installationstag, weil ein ungenutztes Board nichts über Ihr Team aussagt.

Die Compose-Datei schreiben

Erstellen Sie das Verzeichnis und übertragen Sie den Besitz darauf, damit Sie diese Dateien nie über sudo bearbeiten müssen.

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

Generieren Sie die Secrets in einer .env-Datei neben der Compose-Datei. Compose liest diese Datei automatisch und ersetzt die Werte.

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 ist beabsichtigt. Eine Hex-Zeichenfolge enthält nur Ziffern und die Buchstaben a bis f. Dadurch kann sie die DATABASE_URL-Verbindungszeichenfolge, in die sie eingefügt wird, nicht beschädigen. Ein Base64-Passwort mit einem Schrägstrich oder einem At-Zeichen verursacht einen Verbindungsfehler, der wie ein falscher Hostname aussieht. Das kann Sie eine Stunde kosten. Das allgemeine Vorgehen wird unter Secrets aus der Compose-Datei heraushalten beschrieben.

Führen Sie nun docker-compose.yml aus. Ersetzen Sie kanban.example.com an beiden Stellen durch Ihren eigenen Hostnamen.

services:
  planka:
    image: ghcr.io/plankanban/planka:2.2.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:

Vier Entscheidungen in dieser Datei sollten erläutert werden. Es sind die Einstellungen, die häufig geändert und später bereut werden.

  • Beim Planka-Dienst gibt es keinen ports:-Block. Traefik erreicht den Container über das proxy-Netzwerk. Deshalb wird Port 1337 nie auf dem Host veröffentlicht. Eine Veröffentlichung würde jedem ermöglichen, Ihren Proxy und Ihr Zertifikat zu umgehen.
  • loadbalancer.server.port=1337 bezeichnet den Port innerhalb des Containers. Planka lauscht auf 1337. Das Upstream-Beispiel erreicht den Dienst nur über Port 3000, weil es den Port auf den Host abbildet. Hier gibt es keine Host-Abbildung. Daher muss Traefik der Container-Port mitgeteilt werden.
  • condition: service_healthy wird zusammen mit dem Postgres-Healthcheck verwendet. Ohne diese Einstellung startet Planka, bevor die Datenbank Verbindungen akzeptiert. Die erste Abfrage schlägt fehl und Planka beendet sich. Das sieht wie eine Neustartschleife aus. Die technischen Details finden Sie unter Compose-Healthchecks und Startreihenfolge.
  • Der Datenbankdienst heißt absichtlich postgres. Planka 2 leitet seine ausgehenden Anfragen über einen internen Filter. Dessen Standard-Sperrliste ist localhost,postgres. Wenn Sie den Dienst umbenennen, entfernen Sie Ihre Datenbank unbemerkt aus dieser Liste.

Prüfen Sie, ob Compose Ihre Secrets sehen kann, bevor Sie etwas starten:

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

Der Befehl gibt die Datei aus. Die .env-Werte sind dabei bereits ersetzt. Ein leerer Wert bedeutet, dass Compose die .env-Datei nicht liest. Meistens führen Sie den Befehl aus einem anderen Verzeichnis aus.

Was die Bootstrap-Variablen für den Administrator tatsächlich bewirken

Seit Planka 1.13 wird kein Administrator mehr automatisch angelegt. Eine neue Datenbank enthält daher zunächst niemanden, der sich anmelden kann. Die Gruppe DEFAULT_ADMIN_* ist eine von zwei Möglichkeiten, das zu beheben.

Beim Start sucht Planka nach einem Benutzer, der zu DEFAULT_ADMIN_EMAIL passt. Wenn kein solcher Benutzer vorhanden ist, wird einer mit dem daneben festgelegten Passwort, Anzeigenamen und Benutzernamen angelegt. Das geschieht beim ersten Start mit einer leeren Datenbank. Diese Variablen richten also ein Konto ein, verwalten es aber nicht.

DEFAULT_ADMIN_EMAIL erfüllt noch eine zweite Funktion, die häufig übersehen wird. Solange die Variable gesetzt ist, kann niemand das damit bezeichnete Konto über die Oberfläche bearbeiten oder löschen. Das verhindert eine Aussperrung. Deshalb können Sie dieses Konto auch nicht über die Benutzeroberfläche umbenennen oder seine E-Mail-Adresse ändern. Entfernen Sie die Variable und starten Sie Planka neu. Danach ist das Konto ein gewöhnlicher Administrator, den Sie wie jedes andere Konto bearbeiten können.

Bei der Passwortzeile ist besondere Vorsicht erforderlich. Alles unter environment: kann jeder lesen, der im Container docker inspect ausführen kann. Daher sollte DEFAULT_ADMIN_PASSWORD dort nicht dauerhaft gespeichert werden. Melden Sie sich an, ändern Sie Ihr Passwort in der Oberfläche, löschen Sie die Zeile und führen Sie anschließend docker compose up -d erneut aus.

Der sauberere Weg kommt vollständig ohne diese Variablen aus. Kommentieren Sie die gesamte Gruppe DEFAULT_ADMIN_* aus und legen Sie das Konto anschließend interaktiv an:

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

Der Befehl fragt nach E-Mail-Adresse, Passwort, Anzeigenamen und einem optionalen Benutzernamen. Anschließend schreibt er den Benutzer direkt in die Datenbank. Das Passwort gelangt weder in die Compose-Datei noch in die Container-Umgebung. Verwenden Sie diesen Weg, wenn mehrere Personen Shell-Zugriff auf den VPS haben. Der Befehl startet zuerst Postgres, weil depends_on erforderlich ist. Daher funktioniert er auch mit einem Stack, der noch nie gestartet wurde.

Bei beiden Wegen müssen Sie die Planka-Passwörter selbst verwalten. Bis Version 2.1.1 konnte die Community Edition Anmeldungen an einen OIDC-Provider wie Authentik als eigenen Single-Sign-on-Server übergeben. Mit Version 2.2.0, veröffentlicht im August 2026, wurden OIDC und SSO in PLANKA Pro verschoben. Die Community Edition erhielt in derselben Version die Zwei-Faktor-Authentifizierung (TOTP) für lokale Konten. Aktivieren Sie sie daher zumindest für das Administratorkonto.

Warum BASE_URL Anmeldungen verhindert, wenn sie nicht mit dem Hostnamen übereinstimmt

BASE_URL ist die genaue Adresse, die Benutzer in den Browser eingeben, einschließlich Schema und ohne abschließenden Schrägstrich. Für diesen Stack ist das https://kanban.example.com. Planka erstellt aus diesem Wert eigene Links und seine WebSocket-Verbindung. Ein falscher Wert für BASE_URL führt daher nicht zu einer eindeutigen Fehlermeldung. Stattdessen wird eine Seite geladen, deren Ladevorgang anschließend nicht abgeschlossen wird.

Der häufige Fall: Sie übernehmen das Beispiel des Upstream-Projekts, lassen BASE_URL=http://localhost:3000 unverändert und rufen die Website über HTTPS unter Ihrer tatsächlichen Domain auf. Das Anmeldeformular wird gesendet, und Ihre Anmeldedaten werden akzeptiert. Das Board wird jedoch nicht angezeigt. Öffnen Sie die Entwicklerkonsole des Browsers. Dort sehen Sie, dass Anfragen an /socket.io/ fehlschlagen, weil der Client angewiesen wurde, seine Live-Verbindung zu localhost:3000 herzustellen. Auf Ihrem Laptop ist diese Adresse jedoch nicht vorhanden.

TRUST_PROXY=true ist die andere Hälfte desselben Problems. Planka läuft hinter Traefik. Deshalb erreicht jede Anfrage die Anwendung innerhalb des Docker-Netzwerks von der Adresse des Proxy über plain HTTP. Ohne TRUST_PROXY ignoriert die Anwendung die Header X-Forwarded-Proto und X-Forwarded-For, die Traefik setzt. Sie geht daher davon aus, dass die Verbindung unsicher ist, und behandelt alle Clients als eine gemeinsame IP-Adresse. Wenn die Option gesetzt ist, liest die Anwendung diese Header und verwendet dasselbe Schema wie der Browser.

Traefik leitet WebSockets ohne zusätzliche Konfiguration weiter. Das ist ein Grund, es hier zu bevorzugen. Bei nginx muss der Proxy die Upgrade-Header proxy_set_header Upgrade $http_upgrade und proxy_set_header Connection "upgrade" weiterleiten. Andernfalls erhalten Sie denselben dauerhaft laufenden Ladekreis, allerdings aus einer anderen Ursache. Diese Direktiven können im allgemeinen Block location / stehen. Ein separater Block für /socket.io funktioniert ebenfalls, ist aber nicht erforderlich.

Wenn Sie das Board später auf einen neuen Hostnamen verschieben, müssen Sie zwei Dinge gemeinsam ändern: den Wert BASE_URL und die Traefik-Regel Host(). Wenn Sie nur eines davon ändern, bleibt der andere Wert unverändert und der Ladekreis tritt erneut auf. Die Bereitstellung von Planka unter einem Unterpfad wie https://example.com/planka wird ab Version 2.1.0 unterstützt, die im März 2026 veröffentlicht wurde. Verwenden Sie bei älteren Tags stattdessen eine eigene Subdomain.

Wo Planka Anhänge und Avatare speichert

Planka 2 speichert alle Uploads eines Benutzers unter einem einzigen Pfad im Container: /app/data. Anhänge, Benutzeravatare und Hintergrundbilder für Boards befinden sich dort. Version 1 verwendete drei separate Verzeichnisse. Deshalb bindet eine aus einer älteren Anleitung übernommene Compose-Datei Pfade ein, die nicht mehr existieren. Das tatsächliche Datenverzeichnis bleibt dadurch ohne Mount.

Dieser eine Mount entscheidet darüber, ob ein Board ein Upgrade übersteht oder erheblicher manueller Aufwand entsteht. Wenn /app/data nicht auf einem Volume liegt, werden Uploads in der beschreibbaren Schicht des Containers gespeichert. Diese Schicht wird beim Neuerstellen des Containers gelöscht. Der Container wird bei jeder Änderung des Image-Tags neu erstellt. Das Board wird scheinbar vollständig wiederhergestellt, und alle Karten sind vorhanden. Alle Links zu Anhängen sind jedoch ungültig, weil die Datenbankzeilen weiterhin auf nicht mehr vorhandene Dateien verweisen.

Das benannte Volume in der obigen Compose-Datei verhindert dieses Problem. Ein Bind-Mount funktioniert ebenfalls und erleichtert die Sicherung der Dateien mit gewöhnlichen Werkzeugen. Dafür ist jedoch ein zusätzlicher Schritt erforderlich. Der Node-Prozess im Container läuft als UID 1000. Ein Hostverzeichnis, das root gehört, führt beim ersten Upload zu einem Berechtigungsfehler:

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

Der Unterschied zwischen beiden Varianten wird unter Bind-Mounts gegenüber benannten Volumes erläutert.

Wenn Anhänge den Speicherplatz Ihres Tarifs überschreiten, kann Planka sie stattdessen über S3_ENDPOINT, S3_BUCKET und die zugehörigen Schlüsselvariablen in einem S3-kompatiblen Speicher ablegen. Dabei kann es sich um einen gehosteten Bucket oder um einen selbst gehosteten MinIO-Objektspeicher auf einem anderen Server handeln. Legen Sie dies fest, bevor das Team das Board mit Inhalten füllt, da die Einstellung nur für neue Uploads gilt.

Stack starten und die Funktion prüfen

docker compose pull
docker compose up -d
docker compose ps

docker compose ps sollte postgres als healthy und planka als running anzeigen. Wenn Planka in einer Neustartschleife läuft, prüfen Sie zuerst die Datenbankverbindung und nicht die Anwendung.

docker compose logs -f planka

Bei einem erfolgreichen ersten Start werden die Datenbankmigrationen ausgeführt. Danach meldet der Server, dass er auf Port 1337 lauscht. Prüfen Sie direkt mit Postgres, ob das Schema tatsächlich angelegt wurde, statt sich auf das Log zu verlassen:

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

Eine Tabellenliste mit board und card zeigt, dass die Migrationen ausgeführt wurden. „Did not find any relations“ bedeutet, dass Planka nie eine Verbindung hergestellt hat. Vergleichen Sie daher DATABASE_URL mit den Werten POSTGRES_USER und POSTGRES_PASSWORD in Ihrer .env.

Prüfen Sie anschließend die Route von Ihrem eigenen Rechner aus und nicht vom VPS:

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

HTTP/2 200 bedeutet, dass Traefik ein Zertifikat verwendet und den Container erreicht. Ein von Traefik gelieferter 404-Fehler bedeutet, dass kein Router zur Anfrage passt: Die Host()-Regel passt nicht zum angeforderten Hostnamen, oder Traefik hat die Labels nicht übernommen. Ein 502-Fehler bedeutet, dass der Router gepasst hat, Traefik den Container aber nicht erreichen konnte, beispielsweise weil der Container nicht mit dem proxy-Netzwerk verbunden ist. Öffnen Sie nun die Website und melden Sie sich mit dem Administratorkonto an.

Vor jedem Versionssprung ein pg_dump erstellen

Zwei getrennte Speicher enthalten Ihre Board-Daten. Eine Sicherung muss daher beide abdecken: die Postgres-Datenbank und das planka-data-Volume. Erstellen Sie den Datenbank-Dump, während der Stack läuft.

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

Das -T ist nicht optional. Ohne diese Option weist Compose ein Pseudo-Terminal zu. Die Terminalschicht ändert dann die Zeilenenden im Datenstrom. Dadurch entsteht eine Dump-Datei, deren Wiederherstellung vorzeitig fehlschlägt. Der Fehler tritt möglicherweise erst Wochen später auf. Das ist der ungünstigste Zeitpunkt.

Sichern Sie anschließend die Uploads. Ermitteln Sie zuerst den tatsächlichen Volume-Namen, da Compose den Namen des Projektverzeichnisses voranstellt.

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 .

Das Projekt enthält außerdem docker-backup.sh und docker-restore.sh in seinem Repository. Die offizielle Dokumentation richtet dafür einen nächtlichen Cron-Job ein. Beide Ansätze sind geeignet. Nicht geeignet ist eine Sicherung, die Sie nie wiederhergestellt haben. Stellen Sie daher einmal eine Sicherung auf einem Test-VPS wieder her. Bestätigen Sie anschließend, dass Sie sich anmelden und einen Anhang öffnen können. Dasselbe Paar von Speichern findet sich in jeder Compose-Anwendung, die Uploads akzeptiert. Wenn Sie später Chatwoot auf demselben Server wie Ihr Supportsystem betreiben, können Sie die hier erstellte Routine mit kaum mehr als geänderten Volume-Namen übernehmen.

Führen Sie den Dump unmittelbar vor jeder Versionsänderung aus. Eine Sicherung von letzter Nacht ist nicht dasselbe wie eine Sicherung unmittelbar vor der Migration, die Sie jetzt ausführen wollen.

Tags festschreiben und Release Notes lesen

Beide Image-Tags in dieser Datei sind absichtlich festgeschrieben.

ghcr.io/plankanban/planka:2.2.1 ist ein bestimmtes Release, das im Oktober 2026 aktuell ist. latest ändert sich bei jeder Veröffentlichung durch das Upstream-Projekt. Ein routinemäßiges docker compose pull kann dadurch zu einem Zeitpunkt eine Schema-Migration einspielen, den Sie nicht selbst gewählt haben. Lesen Sie die Release Notes, bevor Sie diese Nummer ändern. Dort werden inkompatible Änderungen und Sicherheitskorrekturen beschrieben. Version 2.0.3 wurde als Security Release veröffentlicht. Genau solche Änderungen sollten Sie bewusst prüfen, statt sie versehentlich zu übernehmen. Das gilt auch für 2.2.1, das im August 2026 veröffentlicht wurde. Diese Version behebt eine Path-Traversal-Schwachstelle, durch die ein angemeldeter Benutzer beliebige Dateien auf Instanzen mit lokalem Dateispeicher lesen konnte. Das ist die Konfiguration in dieser Anleitung. Der Sicherheitshinweis nennt 2.1.1 und frühere Versionen als betroffen. Wenn Sie von 2.1.x kommen, lesen Sie zuerst die Hinweise zu 2.2.0. Dieses Release deaktiviert Benutzer, die sich bisher ausschließlich über SSO angemeldet haben, bis ein Administrator ihnen ein Passwort zuweist. Das Festschreiben des Tags ist hier einfach, weil das Upstream-Projekt überhaupt Images veröffentlicht. Wenn ein Projekt keine Images bereitstellt, gilt dieselbe Disziplin mit einem zusätzlichen Schritt, wie bei openGym, das aus einem ausgecheckten Git-Tag auf dem System erstellt wird.

postgres:16-alpine ist aus einem wichtigeren Grund auf eine Major-Version festgeschrieben. Postgres schreibt sein Datenverzeichnis in einem Format, das an die Major-Version gebunden ist. Der Server verweigert das Öffnen eines Verzeichnisses, das von einer anderen Major-Version geschrieben wurde. Schreiben Sie postgres:latest und lassen den Tag über 16 hinaus weiterlaufen, startet der Container nicht. Das Image für Version 17 beendet sich beispielsweise mit:

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.

Dabei gehen keine Daten verloren. Ein Neustart behebt das Problem ebenfalls nicht. Der Wechsel auf eine neue Postgres-Major-Version erfordert entweder einen Dump der alten Version und dessen Wiederherstellung in einem neuen Datenverzeichnis der neuen Version oder die Ausführung von pg_upgrade. Dieser Befehl konvertiert die Daten ohne Dump, benötigt jedoch gleichzeitig die Server-Binärdateien der alten und der neuen Version. In beiden Fällen handelt es sich um eine geplante Arbeit bei beendetem Stack, nicht um einen Nebeneffekt eines Image-Pulls.

Wenn Sie eine vorhandene Planka-1.x-Installation aktualisieren, statt eine neue Installation zu beginnen, gibt es dafür ein eigenes dokumentiertes Verfahren in der Projektdokumentation. Ohne ein vorher erstelltes Backup gibt es keinen Weg zurück zu Version 1.

Fehlerbilder und die dabei ausgegebenen Zeichenfolgen

Planka startet in einer Schleife neu, und im Log wird die Datenbank genannt. Die Zugangsdaten in DATABASE_URL stimmen nicht mit der Postgres-Umgebung überein. Beachten Sie, dass POSTGRES_PASSWORD nur angewendet wird, wenn das Datenverzeichnis zum ersten Mal initialisiert wird. Wenn Sie die Variable nach einem fehlerhaften ersten Start korrigieren, ändert das nichts. Sie müssen das db-data-Volume entfernen und den Stack erneut starten.

Die Anmeldung funktioniert, aber das Board wird nie geladen. BASE_URL stimmt nicht mit der Adresse in der Browserzeile überein, oder TRUST_PROXY fehlt. Die Browserkonsole zeigt fehlgeschlagene Anfragen an /socket.io/.

Uploads schlagen fehl, während alles andere funktioniert. Ein Bind-Mount gehört root. Führen Sie sudo chown -R 1000:1000 für das Verzeichnis auf dem Host aus und starten Sie den Container neu.

Anhänge sind nach einem Upgrade verschwunden. /app/data lag nicht auf einem Volume. Die Dateien befanden sich daher in der Container-Schicht, die durch das Upgrade ersetzt wurde. Stellen Sie die Dateien aus einem Backup wieder her. Fügen Sie anschließend das Volume hinzu, bevor Sie den Image-Tag erneut ändern.

Traefik gibt 404 zurück. Es hat kein Router zur Anfrage gepasst. Die Host()-Regel passt nicht zu Ihrem DNS-Eintrag, oder die Labels wurden Traefik nicht übergeben. docker compose config zeigt die Labels nach der Ersetzung. Dort werden Tippfehler sichtbar. Ein 502 bedeutet dagegen, dass die Route gepasst hat, der Container aber nicht erreichbar war. Prüfen Sie daher, ob er sich im proxy-Netzwerk befindet.

Benachrichtigungen oder Webhooks treffen nie ein. Planka 2 sendet ausgehende HTTP-Anfragen über einen internen Filter. Die standardmäßige Blockliste umfasst localhost und postgres. Ein auf localhost gerichteter Webhook wird absichtlich blockiert. Sobald Sie OUTGOING_ALLOWED_HOSTS setzen, wird außerdem jeder Host blockiert, der nicht in dieser Liste steht. Richten Sie den Webhook auf den Servicenamen des anderen Containers. Wenn Sie eine Allowlist verwenden, fügen Sie diesen Namen zu OUTGOING_ALLOWED_HOSTS hinzu, anstatt den Filter zu entfernen.

Sobald der Stack läuft, ist der Betriebsaufwand gering. Lesen Sie die Release Notes, und sichern Sie die Datenbank vor jedem Upgrade. Nach einem Reboot wird der Stack aufgrund von restart: unless-stopped automatisch wieder gestartet, sofern der Docker-Dienst beim Booten aktiviert ist. Compose-Stacks, die nach einem Reboot wieder gestartet werden behandelt die Fälle, in denen das nicht geschieht.

FAQ

Warum lädt Planka nach der Anmeldung endlos?

Die Zugangsdaten wurden akzeptiert, aber die Live-Verbindung konnte nicht hergestellt werden. Planka erstellt seine WebSocket-URL aus BASE_URL. Wenn diese Variable weiterhin http://localhost:3000 enthält, Sie die Website aber unter https://kanban.example.com aufrufen, versucht der Browser, eine Verbindung zu einer Adresse herzustellen, die auf Ihrem Rechner nicht existiert. Die Entwicklerkonsole zeigt fehlgeschlagene Anfragen an /socket.io/. Setzen Sie BASE_URL auf die exakte öffentliche Adresse ohne abschließenden Schrägstrich. Fügen Sie TRUST_PROXY=true hinzu, damit die Anwendung den X-Forwarded-Proto-Header Ihres Reverse Proxy berücksichtigt. Führen Sie anschließend docker compose up -d aus.

Wie erstelle ich den ersten Planka-Administrator?

Seit Version 1.13 wird kein Administrator mehr automatisch erstellt. Setzen Sie entweder DEFAULT_ADMIN_EMAIL mit dem zugehörigen Passwort sowie den Variablen für Namen und Benutzernamen und starten Sie den Stack. Alternativ können Sie docker compose run --rm planka npm run db:create-admin-user ausführen und die Eingabeaufforderungen beantworten. Der interaktive Befehl ist auf einem gemeinsam genutzten Server sicherer, weil das Passwort nicht in die Container-Umgebung gelangt, in der docker inspect es auslesen kann. Wenn DEFAULT_ADMIN_EMAIL anschließend gesetzt bleibt, ist dieses Konto für Änderungen und Löschung über die Oberfläche gesperrt.

Wo speichert Planka Anhänge und Avatare?

In Planka 2 liegen alle hochgeladenen Dateien innerhalb des Containers unter /app/data. Dazu gehören Anhänge, Benutzeravatare und Board-Hintergründe. Binden Sie diesen Pfad an ein benanntes Volume. Wenn das Volume nicht eingebunden ist, liegen die Dateien in der beschreibbaren Schicht des Containers. Beim nächsten Neuerstellen des Containers werden sie gelöscht. Das geschieht bei jedem Upgrade des Images. Ein Bind-Mount funktioniert ebenfalls. Der Node-Prozess läuft jedoch mit UID 1000. Führen Sie daher sudo chown -R 1000:1000 für das Verzeichnis auf dem Host aus. Andernfalls schlagen Uploads mit einem Berechtigungsfehler fehl.

Wie viel RAM benötigt ein selbst gehostetes Planka?

Das Projekt nennt keine Mindestanforderungen an die Hardware. Die auf Hosting-Seiten häufig genannten 2 vCPU und 4 GB sind der Standard eines Anbieters und keine Messung. Für ein kleines Board ist diese Ausstattung großzügig. Die gesamte Arbeitslast besteht aus einem Node-Prozess und einem Postgres-Server. Dieser startet für jede offene Verbindung einen kleinen Backend-Prozess. Ein Tarif mit 1 vCPU und 2 GB reicht daher für ein Team mit zwei bis fünf Personen. Führen Sie nach einer normalen Woche docker stats --no-stream aus und dimensionieren Sie anhand Ihrer eigenen Werte. Überwachen Sie den Datenträger genauer als den Arbeitsspeicher, weil die Anhänge den Speicherbedarf erhöhen.

Wie aktualisiere ich Planka ohne Datenverlust?

Sichern Sie die Datenbank und archivieren Sie das Uploads-Volume unmittelbar vor dem Upgrade. Verwenden Sie nicht den Zeitplan der letzten Nacht. Verwenden Sie docker compose exec -T postgres pg_dump -U planka -d planka > planka-db.sql und behalten Sie -T bei, damit das Pseudo-Terminal die umgeleitete Ausgabe nicht beschädigt. Lesen Sie die Release Notes für jede übersprungene Version. Ändern Sie den Image-Tag auf ein bestimmtes Release statt auf latest. Führen Sie anschließend docker compose pull und docker compose up -d aus und überwachen Sie das Log auf die Migration. Lassen Sie den Postgres-Tag auf seine Major-Version festgelegt. Der Server verweigert den Zugriff auf ein Datenverzeichnis, das von einer anderen Major-Version geschrieben wurde.