SSD Nodes Learn Hosting plans →
Przewodniki Matt ConnorAutor: Matt Connor · Zaktualizowano 2026-08-28

Jak samodzielnie hostować Planka przez Docker Compose

Wdróż Planka na własnym serwerze VPS przy użyciu Docker Compose. Dowiedz się, jak poprawnie skonfigurować Postgres, Traefik oraz zmienną BASE_URL, która blokuje logowanie użytkowników.

Co zyskujesz dzięki samodzielnemu hostowaniu Planka

Samodzielne hostowanie Planka zapewnia zespołowi tablicę Kanban z modelem kart, list i etykiet znanym z Trello, działającą na kontrolowanym przez Ciebie serwerze VPS. Brak limitów liczby stanowisk i opłat za użytkownika sprawia, że jedynym kosztem jest utrzymanie serwera. Niniejszy przewodnik opisuje wdrożenie przy użyciu Docker Compose za serwerem Traefik, z wykorzystaniem Postgres do przechowywania danych oraz nazwanych wolumenów dla plików przesyłanych przez użytkowników.

Przewodnik skierowany jest do zespołów liczących od dwóch do pięciu osób, które rezygnują z darmowego planu Trello. Jeśli wybór oprogramowania do zarządzania zadaniami nie został jeszcze dokonany, należy najpierw zapoznać się z porównaniem alternatyw dla Trello z możliwością samodzielnego hostowania. Niniejszy poradnik zakłada, że decyzja została podjęta i skupia się wyłącznie na procesie wdrożenia.

Wymagany jest serwer VPS z zainstalowanym Docker Engine wraz z wtyczką Compose oraz rekord DNS typu A wskazujący na ten serwer. Niezbędne jest również posiadanie działającej instancji Traefik, która obsługuje terminację TLS (transport layer security) na danej maszynie. Jeśli Traefik nie jest jeszcze skonfigurowany, należy najpierw wdrożyć reverse proxy Traefik przed wieloma aplikacjami Compose, a w przypadku braku biegłości w obsłudze poniższego pliku, zapoznać się z podstawami Docker Compose na serwerze VPS.

Jakich zasobów VPS wymaga Planka?

Projekt nie publikuje minimalnych wymagań sprzętowych, dlatego każdą podaną wartość należy traktować jako punkt wyjścia, a nie sztywny pomiar. Wartości 2 vCPU i 4 GB RAM, powtarzane na stronach hostingowych, są bezpiecznym standardem dostawcy, a nie wymogiem wynikającym z testów projektu. Jest to konfiguracja z dużym zapasem dla tablicy obsługującej pięć osób.

Rzeczywiste obciążenie jest niewielkie: jeden proces Node.js obsługujący API oraz zbudowany frontend, a także jeden proces Postgres przechowujący dane. Trzeci, lekki proces proxy działa wewnątrz kontenera Planka, filtrując wychodzące żądania. Plan z 1 vCPU i 2 GB RAM wystarcza dla tablicy obsługującej od dwóch do pięciu osób, a większość wolnej pamięci jest wykorzystywana przez Postgres jako cache. Tablica jest mało wymagającym sąsiadem, więc jeśli ten sam VPS ma również przechowywać dokumenty zespołu, należy najpierw dobrać rozmiar pod tę aplikację: uruchomienie AFFiNE jako przestrzeni roboczej w stylu Notion wymaga samodzielnie kilku gigabajtów pamięci, zanim Planka zacznie zgłaszać własne zapotrzebowanie.

Dobierz rozmiar dysku przed określeniem ilości pamięci, ponieważ to załączniki są elementem, który stale rośnie. Zmierz własną instancję zamiast polegać na tym akapicie:

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

Pierwsze polecenie wyświetla bieżące zużycie pamięci i procesora dla każdego kontenera. Drugie pokazuje, ile miejsca zajmuje każdy wolumen. Wykonaj oba pomiary po normalnym tygodniu pracy, a nie w dniu instalacji, ponieważ bezczynna tablica nie dostarcza informacji o rzeczywistym użytkowaniu przez zespół.

Przygotowanie pliku Compose

Utwórz katalog i przejmij nad nim uprawnienia, aby uniknąć edycji plików za pomocą sudo.

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

Wygeneruj sekrety do pliku .env w tym samym katalogu, w którym znajduje się plik Compose. Compose automatycznie odczyta ten plik i podstawi wartości.

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

Użycie openssl rand -hex jest celowe. Ciąg szesnastkowy zawiera tylko cyfry oraz litery od a do f, więc nie spowoduje błędów w ciągu połączeniowym DATABASE_URL, do którego zostanie wklejony. Hasło w formacie base64 zawierające ukośnik lub znak małpy generuje błąd połączenia, który jest interpretowany jako błędna nazwa hosta, co prowadzi do długotrwałej diagnostyki. Szerszy opis tego zagadnienia znajduje się w przechowywanie sekretów poza plikiem Compose.

Teraz docker-compose.yml. Zastąp kanban.example.com własną nazwą hosta w obu miejscach, w których występuje.

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:

Cztery decyzje w tym pliku wymagają wyjaśnienia, ponieważ są to elementy, których zmiana często prowadzi do problemów.

  • W usłudze Planka brakuje sekcji ports:. Traefik uzyskuje dostęp do kontenera poprzez sieć proxy, więc port 1337 nie jest publikowany na hoście. Publikacja portu umożliwiłaby obejście proxy i certyfikatów.
  • loadbalancer.server.port=1337 wskazuje port wewnątrz kontenera. Planka nasłuchuje na porcie 1337, a przykłady z dokumentacji często używają portu 3000, ponieważ mapują go na hosta. Tutaj nie ma mapowania na hosta, więc Traefik musi otrzymać informację o porcie kontenera.
  • condition: service_healthy współpracuje z mechanizmem healthcheck bazy Postgres. Bez tego wpisu Planka uruchamia się, zanim baza zacznie akceptować połączenia, co powoduje niepowodzenie pierwszego zapytania i wyjście z aplikacji, co wygląda jak pętla restartów. Mechanizm ten opisano w zdrowie usług i kolejność uruchamiania w Compose.
  • Usługa bazy danych została celowo nazwana postgres. Planka 2 kieruje swoje wychodzące żądania przez wewnętrzny filtr, którego domyślna lista blokowanych adresów to localhost,postgres. Zmiana nazwy usługi spowoduje usunięcie bazy danych z tej listy.

Sprawdź, czy Compose widzi sekrety przed uruchomieniem czegokolwiek:

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

Polecenie to wyświetli plik z podstawionymi wartościami .env. Pusta wartość oznacza, że Compose nie odczytuje pliku .env, co zazwyczaj wynika z uruchomienia polecenia w innym katalogu.

Działanie zmiennych bootstrap administratora

Od wersji Planka 1.13 administrator nie jest tworzony automatycznie, dlatego w nowej bazie danych nie ma użytkownika, który mógłby się zalogować. Grupa DEFAULT_ADMIN_* stanowi jeden z dwóch sposobów rozwiązania tego problemu.

Podczas uruchamiania Planka sprawdza obecność użytkownika pasującego do DEFAULT_ADMIN_EMAIL. Jeśli taki nie istnieje, tworzy go przy użyciu hasła, nazwy wyświetlanej oraz nazwy użytkownika zdefiniowanych w zmiennych. Dzieje się to tylko przy pierwszym uruchomieniu z pustą bazą danych, więc zmienne te służą do inicjalizacji konta, a nie do jego zarządzania.

DEFAULT_ADMIN_EMAIL pełni drugą funkcję, która często zaskakuje użytkowników. Dopóki zmienna jest ustawiona, konto o tej nazwie nie może być edytowane ani usuwane z poziomu interfejsu przez nikogo. Jest to zabezpieczenie przed zablokowaniem dostępu; z tego powodu nie można zmienić nazwy ani adresu e-mail tego konta w UI. Należy usunąć zmienną i zrestartować usługę, aby konto stało się zwykłym administratorem, którego można edytować jak każdego innego.

Należy zachować ostrożność przy linii z hasłem. Wszystko w environment: jest czytelne dla każdego, kto może wykonać docker inspect na kontenerze, dlatego DEFAULT_ADMIN_PASSWORD nie powinno znajdować się tam na stałe. Należy zalogować się, zmienić hasło w interfejsie, usunąć tę linię, a następnie ponownie wykonać docker compose up -d.

Czystszą metodą jest całkowite pominięcie zmiennych. Należy zakomentować całą grupę DEFAULT_ADMIN_*, a następnie utworzyć konto interaktywnie:

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

Polecenie to prosi o podanie adresu e-mail, hasła, nazwy wyświetlanej oraz opcjonalnej nazwy użytkownika, po czym zapisuje dane bezpośrednio w bazie danych. Hasło nigdy nie trafia do pliku Compose ani do środowiska kontenera. Tę metodę należy stosować, jeśli więcej niż jedna osoba ma dostęp do powłoki VPS. Polecenie uruchamia najpierw Postgres ze względu na depends_on, więc działa również na stosie, który nigdy wcześniej nie był uruchomiony.

Obie metody wymagają ręcznego zarządzania hasłami w Planka. Jeśli jest to już czwarty zestaw danych uwierzytelniających w zespole, Planka może delegować logowanie do dostawcy OIDC, takiego jak Authentik działający jako własny serwer single sign-on, przy czym administrator bootstrap pozostaje kontem awaryjnym na wypadek niedostępności dostawcy.

Dlaczego BASE_URL powoduje błędy logowania, gdy nie zgadza się z nazwą hosta

BASE_URL to dokładny adres wpisywany przez użytkowników w przeglądarce, wraz ze schematem i bez ukośnika na końcu. Dla tego stosu jest to https://kanban.example.com. Planka generuje własne linki oraz połączenie WebSocket na podstawie tej wartości, co oznacza, że błędne BASE_URL nie powoduje czytelnego błędu. Strona ładuje się, ale proces ładowania nigdy się nie kończy.

Typowy scenariusz: kopiujesz przykład upstream, pozostawiasz BASE_URL=http://localhost:3000 bez zmian i uzyskujesz dostęp do witryny przez HTTPS na swojej właściwej domenie. Formularz logowania przesyła dane, a poświadczenia są akceptowane. Tablica jednak się nie pojawia. Otwórz konsolę programisty w przeglądarce, a zobaczysz nieudane żądania do /socket.io/, ponieważ klient otrzymał polecenie otwarcia połączenia na żywo do localhost:3000, a na Twoim komputerze ten adres nie istnieje.

TRUST_PROXY=true to druga połowa tego samego problemu. Planka działa za Traefik, więc każde żądanie dociera do niej z adresu proxy przez zwykłe HTTP wewnątrz sieci Docker. Bez TRUST_PROXY aplikacja ignoruje nagłówki X-Forwarded-Proto oraz X-Forwarded-For ustawiane przez Traefik, więc uznaje połączenie za niezabezpieczone i traktuje każdego klienta jako jeden współdzielony adres IP. Po ustawieniu tej opcji aplikacja odczytuje wspomniane nagłówki i zgadza się z przeglądarką co do używanego schematu.

Traefik obsługuje proxy dla WebSockets bez dodatkowej konfiguracji, co jest powodem, dla którego warto go tutaj wybrać. W przypadku nginx, socket.io wymaga własnego bloku location z nagłówkami proxy_set_header Upgrade $http_upgrade oraz proxy_set_header Connection "upgrade", w przeciwnym razie wystąpi ten sam problem z zawieszonym wskaźnikiem ładowania, wynikający z innej przyczyny.

Przeniesienie tablicy na nową nazwę hosta w późniejszym czasie wymaga jednoczesnej zmiany dwóch elementów: wartości BASE_URL oraz reguły Host() w Traefik. Zmiana jednego z nich przy pominięciu drugiego spowoduje powrót do problemu z zawieszonym wskaźnikiem. Serwowanie Planka z podścieżki, takiej jak https://example.com/planka, działa od wersji 2.1.0, wydanej w marcu 2026. W przypadku starszych tagów należy przypisać aplikacji własną subdomenę.

Gdzie Planka przechowuje załączniki i awatary

Planka 2 przechowuje wszystkie pliki przesyłane przez użytkowników w jednej ścieżce wewnątrz kontenera: /app/data. Znajdują się tam załączniki, awatary użytkowników oraz obrazy tła tablic. Wersja 1 korzystała z trzech oddzielnych katalogów, dlatego plik Compose skopiowany ze starszych poradników montuje ścieżki, które już nie istnieją, a właściwy katalog danych pozostaje niepodmontowany.

To pojedyncze podmontowanie decyduje o tym, czy tablica przetrwa aktualizację, czy też spowoduje problemy. Jeśli /app/data nie znajduje się na wolumenie, przesyłane pliki trafiają do warstwy zapisu kontenera. Warstwa ta jest niszczona podczas odtwarzania kontenera, a kontener jest odtwarzany przy każdej zmianie tagu obrazu. Tablica po restarcie wygląda poprawnie, karty są na miejscu, ale wszystkie linki do załączników przestają działać, ponieważ rekordy w bazie danych wskazują na pliki, które już nie istnieją.

Nazwany wolumen w powyższym pliku Compose zapobiega tej sytuacji. Bind mount również działa i ułatwia tworzenie kopii zapasowych plików za pomocą standardowych narzędzi, ale wymaga wykonania jednego dodatkowego kroku. Proces Node wewnątrz kontenera działa z UID 1000, więc katalog na hoście należący do root spowoduje błąd uprawnień przy pierwszej próbie przesłania pliku:

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

Porównanie obu rozwiązań znajduje się w sekcji bind mounts a nazwane wolumeny.

Jeśli załączniki zajmą zbyt dużo miejsca na dysku, Planka może zapisywać je w pamięci zgodnej z S3, korzystając z S3_ENDPOINT, S3_BUCKET oraz odpowiednich zmiennych kluczy. Można wskazać zewnętrzny bucket lub samodzielnie hostowany obiektowy magazyn MinIO na innej maszynie. Decyzję należy podjąć, zanim zespół zapełni tablicę, ponieważ ustawienie to dotyczy tylko nowych plików.

Uruchomienie stosu i weryfikacja działania

docker compose pull
docker compose up -d
docker compose ps

docker compose ps powinno wykazać postgres jako healthy oraz planka jako running. Jeśli Planka restartuje się w pętli, w pierwszej kolejności należy sprawdzić połączenie z bazą danych, a nie samą aplikację.

docker compose logs -f planka

Poprawny pierwszy rozruch obejmuje wykonanie migracji bazy danych, po czym serwer zgłasza nasłuchiwanie na porcie 1337. Należy potwierdzić utworzenie schematu, odpytując bezpośrednio Postgres, zamiast polegać wyłącznie na logach:

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

Lista tabel zawierająca board oraz card oznacza, że migracje zostały wykonane. Komunikat "Did not find any relations" oznacza, że Planka nie nawiązała połączenia, dlatego należy porównać DATABASE_URL z wartościami POSTGRES_USER oraz POSTGRES_PASSWORD w pliku .env.

Następnie należy sprawdzić trasę z poziomu własnej maszyny, a nie z VPS:

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

HTTP/2 200 oznacza, że Traefik posiada certyfikat i komunikuje się z kontenerem. Błąd 404 zwrócony przez Traefik oznacza, że etykiety routera nie pasują, najczęściej z powodu niepodłączenia kontenera do sieci proxy. Teraz należy otworzyć stronę i zalogować się na konto administratora.

Wykonaj pg_dump przed każdą aktualizacją wersji

Twoja tablica jest przechowywana w dwóch oddzielnych miejscach, więc kopia zapasowa musi obejmować oba: bazę danych Postgres oraz wolumen planka-data. Wykonaj zrzut bazy danych, gdy stos jest uruchomiony.

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

Flaga -T nie jest opcjonalna. Bez niej Compose przydziela pseudo-terminal, a warstwa terminala nadpisuje znaki końca linii w strumieniu, co prowadzi do powstania pliku zrzutu, który zawiedzie podczas przywracania. Awaria ujawni się dopiero po tygodniach, co jest najgorszym możliwym momentem.

Następnie prześlij pliki. Najpierw znajdź rzeczywistą nazwę wolumenu, ponieważ Compose dodaje do niej prefiks z nazwą katalogu projektu.

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 .

Projekt dostarcza również docker-backup.sh oraz docker-restore.sh w swoim repozytorium, a oficjalna dokumentacja zaleca uruchamianie ich jako zadanie cron w trybie nocnym. Każde z tych podejść jest poprawne. Niedopuszczalna jest natomiast kopia zapasowa, której nigdy nie przywracałeś, więc przywróć ją raz na testowym serwerze VPS i potwierdź, że możesz się zalogować oraz otworzyć załącznik. Ta sama para magazynów danych pojawia się w każdej aplikacji Compose, która akceptuje przesyłanie plików, więc jeśli później zainstalujesz Chatwoot na tym samym serwerze co helpdesk, wypracowana tutaj procedura będzie miała zastosowanie po niewielkiej zmianie nazw wolumenów.

Wykonaj zrzut bezpośrednio przed każdą zmianą wersji. Kopia zapasowa z ubiegłej nocy nie jest tym samym, co kopia zapasowa wykonana przed migracją, którą zamierzasz przeprowadzić.

Przypinanie tagów i czytanie informacji o wydaniu

Oba tagi obrazów w tym pliku są celowo przypięte.

ghcr.io/plankanban/planka:2.1.1 to konkretne wydanie, aktualne na sierpień 2026 roku. latest zmienia się za każdym razem, gdy autorzy publikują nową wersję, więc rutynowe docker compose pull może spowodować migrację schematu w nieoczekiwanym momencie. Przed zmianą tego numeru należy przeczytać informacje o wydaniu, ponieważ to tam opisano zmiany powodujące niekompatybilność oraz poprawki bezpieczeństwa. Wersja 2.0.3 została opublikowana jako wydanie bezpieczeństwa; jest to dokładnie ten rodzaj informacji, z którym należy się zapoznać, zamiast przyjmować zmiany przypadkowo. Przypinanie jest tutaj łatwe, ponieważ autorzy publikują obrazy, a w przypadku projektów, które tego nie robią, należy zachować taką samą dyscyplinę z dodatkowym krokiem, jak w przypadku openGym zbudowanego na maszynie z pobranego tagu git.

postgres:16-alpine jest przypięte do głównej wersji z poważniejszego powodu. Postgres zapisuje swój katalog danych w formacie powiązanym z główną wersją, a serwer odmawia otwarcia katalogu zapisanego przez inną wersję. Wpisanie postgres:latest i pozwolenie na zmianę tagu na 17 spowoduje, że kontener nie wystartuje:

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.

Nic nie zostaje utracone, a restart również niczego nie naprawi. Przejście na nową główną wersję Postgres oznacza wykonanie zrzutu danych ze starej wersji i przywrócenie ich do świeżego katalogu danych w nowej wersji. Jest to zaplanowane zadanie wykonywane przy wyłączonym stosie, a nie efekt uboczny pobrania obrazu.

W przypadku przenoszenia istniejącej instalacji Planka 1.x zamiast rozpoczynania od zera, aktualizacja ta posiada własną udokumentowaną procedurę w dokumentacji projektu i nie ma możliwości powrotu do wersji 1 bez wykonanej wcześniej kopii zapasowej.

Tryby awaryjne i komunikaty błędów

Planka restartuje się w pętli, a dziennik wskazuje na bazę danych. Dane uwierzytelniające w DATABASE_URL nie są zgodne ze środowiskiem Postgres. Należy pamiętać, że POSTGRES_PASSWORD jest stosowane tylko podczas pierwszej inicjalizacji katalogu danych, więc poprawienie zmiennej po nieudanym pierwszym uruchomieniu nie przyniesie efektu. Konieczne jest usunięcie wolumenu db-data i ponowne rozpoczęcie procesu.

Logowanie kończy się sukcesem, ale tablica nie ładuje się. Wartość BASE_URL nie zgadza się z adresem w pasku przeglądarki lub brakuje TRUST_PROXY. Konsola przeglądarki wykazuje nieudane żądania do /socket.io/.

Przesyłanie plików kończy się niepowodzeniem, podczas gdy reszta działa. Punkt montowania (bind mount) jest własnością użytkownika root. Należy wykonać sudo chown -R 1000:1000 na katalogu hosta i zrestartować kontener.

Załączniki zniknęły po aktualizacji. Katalog /app/data nie znajdował się na wolumenie, więc pliki pozostały w warstwie kontenera, która została zastąpiona podczas aktualizacji. Należy przywrócić pliki z kopii zapasowej, a następnie dodać wolumen przed ponowną zmianą tagu obrazu.

Traefik zwraca błąd 404. Kontener nie znajduje się w sieci proxy lub reguła Host() nie pasuje do rekordu DNS. Polecenie docker compose config wyświetla etykiety po podstawieniu zmiennych, co pozwala na wykrycie literówek.

Powiadomienia lub webhooki nie docierają. Planka 2 wysyła wychodzące żądania HTTP przez wewnętrzny filtr, a domyślna lista blokowanych adresów obejmuje localhost oraz postgres. Webhook skierowany do innego kontenera na tym samym hoście może być blokowany zgodnie z założeniami projektowymi. Należy dostosować OUTGOING_ALLOWED_HOSTS zamiast usuwać filtr.

Po uruchomieniu obciążenie operacyjne jest niewielkie. Należy monitorować informacje o wydaniach (release notes) i wykonywać zrzut bazy danych przed każdą aktualizacją. Restart systemu przywraca stos automatycznie dzięki restart: unless-stopped, pod warunkiem, że usługa Docker jest włączona przy starcie systemu, a Stosy Compose uruchamiane po restarcie opisuje przypadki, w których tak się nie dzieje.

FAQ

Dlaczego Planka ładuje się w nieskończoność po zalogowaniu?

Dane logowania zostały zaakceptowane, ale połączenie na żywo nie. Planka buduje adres URL WebSocket na podstawie BASE_URL. Jeśli ta zmienna nadal wskazuje na http://localhost:3000, podczas gdy użytkownik łączy się z witryną przez https://kanban.example.com, przeglądarka próbuje otworzyć gniazdo pod adresem, który nie istnieje w systemie. Konsola programisty wykazuje nieudane żądania do /socket.io/. Należy ustawić BASE_URL na dokładny adres publiczny bez końcowego ukośnika, dodać TRUST_PROXY=true, aby aplikacja uwzględniała nagłówek X-Forwarded-Proto z reverse proxy, a następnie wykonać docker compose up -d.

Jak utworzyć pierwszego administratora w Planka?

Od wersji 1.13 administrator nie jest tworzony automatycznie. Należy ustawić DEFAULT_ADMIN_EMAIL wraz z odpowiadającymi mu zmiennymi hasła, imienia i nazwy użytkownika, a następnie uruchomić stos, albo wykonać docker compose run --rm planka npm run db:create-admin-user i odpowiedzieć na pytania w interaktywnym trybie. Polecenie interaktywne jest bezpieczniejsze na współdzielonym serwerze, ponieważ hasło nie trafia do środowiska kontenera, gdzie mogłoby zostać odczytane przez docker inspect. Pozostawienie ustawionego DEFAULT_ADMIN_EMAIL blokuje możliwość edycji i usunięcia tego konta z poziomu interfejsu.

Gdzie Planka przechowuje załączniki i awatary?

Wszystkie przesłane pliki w Planka 2 znajdują się wewnątrz kontenera w /app/data, wliczając w to załączniki, awatary użytkowników i tła tablic. Należy zamontować tę ścieżkę jako wolumen nazwany. Jeśli wolumen nie zostanie zamontowany, pliki trafią do warstwy zapisu kontenera i zostaną usunięte przy jego ponownym tworzeniu, co dzieje się przy każdej aktualizacji obrazu. Można również użyć bind mount, jednak proces Node działa z UID 1000, więc należy wykonać sudo chown -R 1000:1000 na katalogu hosta, w przeciwnym razie przesyłanie plików zakończy się błędem uprawnień.

Ile pamięci RAM potrzebuje samodzielnie hostowana Planka?

Projekt nie publikuje minimalnych wymagań sprzętowych. Wartość 2 vCPU i 4 GB pamięci RAM, powtarzana na stronach hostingowych, jest domyślną ofertą dostawcy, a nie wynikiem pomiarów; dla małej tablicy jest to wartość hojna. Całe obciążenie stanowi jeden proces Node i jeden proces Postgres, więc plan z 1 vCPU i 2 GB pamięci RAM obsłuży zespół od dwóch do pięciu osób. Po tygodniu normalnej pracy należy wykonać docker stats --no-stream i dobrać zasoby na podstawie własnych danych. Należy monitorować dysk uważniej niż pamięć, ponieważ to załączniki zajmują coraz więcej miejsca.

Jak zaktualizować Planka bez utraty danych?

Należy wykonać zrzut bazy danych i zarchiwizować wolumen z przesłanymi plikami bezpośrednio przed aktualizacją, a nie polegać na harmonogramie z poprzedniej nocy. Należy użyć docker compose exec -T postgres pg_dump -U planka -d planka > planka-db.sql, zachowując -T, aby pseudo-terminal nie uszkodził przekierowanego wyjścia. Należy zapoznać się z informacjami o wydaniu dla każdej pominiętej wersji, zmienić tag obrazu na konkretne wydanie zamiast latest, a następnie wykonać docker compose pull i docker compose up -d, monitorując dziennik pod kątem migracji. Tag Postgres należy przypiąć do głównej wersji, ponieważ serwer odmawia otwarcia katalogu danych zapisanego przez inną wersję główną.