SSD Nodes Learn 🎉 VPS od $5.50/mies.
Przewodniki Matt ConnorAutor: Matt Connor · Zaktualizowano 2026-08-13

Jak wdrożyć Planka przez Docker Compose na własnym VPS

Instrukcja instalacji Planka z Postgres i Traefik. Dowiedz się, jak poprawnie skonfigurować zmienną BASE_URL oraz parametry bootstrap, aby uniknąć błędów logowania w aplikacji.

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 miejsc i opłat za użytkownika sprawia, że jedynym kosztem jest utrzymanie serwera. Niniejszy przewodnik opisuje wdrożenie aplikacji za pomocą Docker Compose z wykorzystaniem Traefik, bazy danych Postgres oraz nazwanych wolumenów dla plików przesyłanych przez użytkowników.

Przewodnik jest przeznaczony dla zespołów liczących od dwóch do pięciu osób, które rezygnują z darmowego planu Trello. Jeśli nadal wybierasz rozwiązanie dla swojego zespołu, najpierw przeczytaj porównanie alternatyw dla Trello do samodzielnego hostowania. Ten przewodnik zakłada, że decyzja została już podjęta i skupia się wyłącznie na procesie wdrożenia.

Wymagany jest serwer VPS z zainstalowanym Docker Engine oraz wtyczką Compose, a także rekord DNS typu A wskazujący na ten serwer. Niezbędna jest również działająca instancja Traefik, która obsługuje terminację TLS (transport layer security). Jeśli Traefik nie jest jeszcze skonfigurowany, najpierw przygotuj reverse proxy Traefik przed kilkoma aplikacjami Compose, a jeśli poniższy plik wydaje się niejasny, zapoznaj 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ść 2 vCPU i 4 GB RAM, powtarzana na stronach dostawców, jest bezpiecznym domyślnym ustawieniem, a nie wymogiem wynikającym z testów projektu. Jest to zasób hojny dla tablicy obsługującej pięć osób.

Rzeczywiste obciążenie jest niewielkie: jeden proces Node.js obsługujący API oraz skompilowany frontend, a także jeden proces Postgres przechowujący dane. Trzeci, niewielki proces proxy działa wewnątrz kontenera Planka, filtrując wychodzące żądania. Plan z 1 vCPU i 2 GB RAM wystarcza dla zespołu od dwóch do pięciu osób, a większość wolnej pamięci jest wykorzystywana przez Postgres jako cache.

W pierwszej kolejności należy dobrać rozmiar dysku, ponieważ to załączniki powodują największy przyrost danych. Należy zmierzyć 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. Pomiary należy wykonać po normalnym tygodniu pracy, a nie w dniu instalacji, ponieważ bezczynna tablica nie dostarcza informacji o rzeczywistym obciążeniu generowanym przez zespół.

Przygotowanie pliku Compose

Utwórz katalog i przejmij nad nim kontrolę, 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 obok pliku Compose. Compose automatycznie odczytuje ten plik i podstawia 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 i litery od a do f, więc nie może uszkodzić ciągu połączeniowego DATABASE_URL, do którego jest wklejany. Hasło w formacie base64 zawierające ukośnik lub znak małpy powoduje błąd połączenia, który wygląda jak błędna nazwa hosta, co generuje godzinę zbędnej diagnostyki. Szerszy schemat postępowania opisano w utrzymywaniu 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óre użytkownicy często zmieniają, a następnie żałują.

  • W usłudze Planka brakuje bloku ports:. Traefik dociera do kontenera przez sieć proxy, więc port 1337 nigdy nie jest publikowany na hoście. Publikacja portu umożliwiłaby obejście proxy i certyfikatu.
  • loadbalancer.server.port=1337 wskazuje port wewnątrz kontenera. Planka nasłuchuje na 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 przyjmować połączenia, co powoduje niepowodzenie pierwszego zapytania i wyjście z aplikacji, co wygląda jak pętla awarii. Mechanizm ten opisano w mechanizmy healthcheck i kolejność uruchamiania w Compose.
  • Usługa bazy danych została celowo nazwana postgres. Planka 2 kieruje własne żądania wychodzące przez wewnętrzny filtr, którego domyślna lista blokad zawiera localhost,postgres. Zmiana nazwy usługi spowodowałaby 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świetla plik z wartościami .env podstawionymi w odpowiednich miejscach. Pusta wartość oznacza, że Compose nie odczytuje pliku .env, co zazwyczaj wynika z uruchomienia polecenia z innego katalogu.

Działanie zmiennych bootstrap administratora

Od wersji Planka 1.13 administrator nie jest tworzony automatycznie, więc w świeżej bazie danych nie ma użytkownika, który mógłby się zalogować. Grupa DEFAULT_ADMIN_* to jeden z dwóch sposobów na rozwiązanie tego problemu.

Podczas uruchamiania Planka sprawdza, czy istnieje użytkownik pasujący do DEFAULT_ADMIN_EMAIL. Jeśli nie, tworzy go przy użyciu hasła, nazwy wyświetlanej i nazwy użytkownika zdefiniowanych obok. Dzieje się to przy pierwszym uruchomieniu na pustej bazie danych, więc zmienne te służą do inicjalizacji konta, a nie do zarządzania nim.

DEFAULT_ADMIN_EMAIL pełni drugą funkcję, która często zaskakuje użytkowników. Dopóki zmienna jest ustawiona, konta o wskazanej nazwie nie można edytować ani usunąć z poziomu interfejsu. Jest to zabezpieczenie przed zablokowaniem dostępu; dlatego nie można zmienić nazwy tego konta ani jego adresu e-mail 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.

W przypadku linii z hasłem należy zachować ostrożność. Wszystko w environment: jest czytelne dla każdego, kto może uruchomić 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 uruchomić docker compose up -d.

Czystszą metodą jest całkowite pominięcie tych 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, a następnie zapisuje użytkownika bezpośrednio w bazie danych. Hasło nigdy nie trafia do pliku Compose ani do środowiska kontenera. Z tej metody należy korzystać, 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łędny BASE_URL nie powoduje czytelnego błędu. Zamiast tego strona ładuje się, ale proces ten nigdy nie zostaje zakończony.

Typowy scenariusz: kopiujesz przykład upstream, pozostawiasz BASE_URL=http://localhost:3000 bez zmian i uzyskujesz dostęp do witryny przez HTTPS pod swoją właściwą domeną. Formularz logowania przesyła dane, a poświadczenia są akceptowane. Tablica jednak się nie pojawia. Otwórz konsolę programisty w przeglądarce, a zobaczysz, że żądania do /socket.io/ kończą się niepowodzeniem, 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 zmiennej aplikacja odczytuje 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 preferować. 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 problemu z zawieszaniem się strony. Serwowanie Planka ze ścieżki podrzędnej, 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 zamontowanie decyduje o tym, czy tablica przetrwa aktualizację, czy też spowoduje utratę danych. Jeśli /app/data nie znajduje się na wolumenie, przesyłane pliki trafiają do warstwy zapisu kontenera. Warstwa ta jest niszczona przy każdym odtworzeniu kontenera, co dzieje się za każdym razem, gdy zmieniany jest tag 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. Montowanie typu bind mount również działa i ułatwia tworzenie kopii zapasowych plików za pomocą standardowych narzędzi, ale wymaga 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 bind mounts against named volumes.

Jeśli rozmiar załączników przekroczy dostępną przestrzeń dyskową, Planka może zapisywać je w pamięci zgodnej z S3 za pomocą S3_ENDPOINT, S3_BUCKET oraz odpowiadających im zmiennych kluczy. Może to być zewnętrzny bucket lub własna instancja MinIO na innym serwerze. Decyzję należy podjąć, zanim zespół zacznie korzystać z tablicy, 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ć, że schemat został poprawnie utworzony, odpytując bezpośrednio Postgres, zamiast polegać wyłącznie na dzienniku zdarzeń:

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 zwracany 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ę przy użyciu konta 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"

Parametr -T nie jest opcjonalny. Bez niego Compose przydziela pseudo-terminal, a warstwa terminala nadpisuje znaki końca linii w strumieniu, co prowadzi do powstania pliku zrzutu, który zawiedzie w trakcie przywracania. Awaria ujawni się dopiero po kilku 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. Niedopuszczalne jest natomiast posiadanie kopii zapasowej, 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.

Wykonuj 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ć.

Przypięcie tagów i lektura informacji o wydaniu

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

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 poprawiające bezpieczeństwo; jest to dokładnie ten rodzaj informacji, z którym należy się zapoznać, zamiast przyjmować zmiany przypadkowo.

postgres:16-alpine jest przypięte do wersji głównej z ważniejszego powodu. Postgres zapisuje katalog danych w formacie powiązanym z wersją główną, 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ą wersję główną Postgres wymaga wykonania zrzutu danych ze starej wersji i przywrócenia go w świeżym katalogu danych nowej wersji. Jest to zaplanowane zadanie wykonywane przy wyłączonym stosie, a nie efekt uboczny pobrania obrazu.

Jeśli przenosisz istniejącą instalację Planka 1.x zamiast zaczynać od zera, ta aktualizacja posiada własną udokumentowaną procedurę w dokumentacji projektu i nie ma możliwości powrotu do wersji 1 bez wcześniejszego wykonania kopii zapasowej.

Tryby awarii i komunikaty, które zobaczysz

Planka restartuje się w pętli, a dziennik wskazuje na bazę danych. Poświadczenia w DATABASE_URL nie zgadzają się ze środowiskiem Postgres. Pamiętaj, że POSTGRES_PASSWORD jest stosowane tylko podczas pierwszej inicjalizacji katalogu danych, więc poprawienie zmiennej po nieudanym pierwszym uruchomieniu nic nie zmieni. Należy usunąć wolumen db-data i rozpocząć proces od nowa.

Logowanie kończy się sukcesem, ale tablica nigdy się nie ładuje. BASE_URL nie zgadza się z adresem w pasku przeglądarki lub brakuje TRUST_PROXY. Konsola przeglądarki pokazuje 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ą root. Uruchom sudo chown -R 1000:1000 na katalogu hosta i zrestartuj kontener.

Załączniki zniknęły po aktualizacji. /app/data nie znajdowało się na wolumenie, więc pliki pozostały w warstwie kontenera, która została zastąpiona podczas aktualizacji. Przywróć pliki z kopii zapasowej, a następnie dodaj wolumen, zanim ponownie zmienisz tag obrazu.

Traefik zwraca 404. Kontener nie znajduje się w sieci proxy lub reguła Host() nie pasuje do rekordu DNS. docker compose config pokazuje etykiety po podstawieniu, co pozwala wykryć literówki.

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. Zamiast usuwać filtr, dostosuj OUTGOING_ALLOWED_HOSTS.

Gdy usługa działa, obciążenie operacyjne jest niewielkie. Monitoruj informacje o wydaniach (release notes) i wykonuj 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, które wracają 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, a użytkownik łączy się z adresem 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 ukośnika na końcu, dodać TRUST_PROXY=true, aby aplikacja honorował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 docker inspect mogłoby je odczytać. Pozostawienie ustawionego DEFAULT_ADMIN_EMAIL blokuje to konto przed edycją i usunięciem z poziomu interfejsu.

Gdzie Planka przechowuje załączniki i awatary?

Wszystkie przesłane pliki w Planka 2 znajdują się wewnątrz kontenera w ścieżce /app/data, w tym 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 utworzeniu, co ma miejsce 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 instancja Planka?

Projekt nie publikuje minimalnych wymagań sprzętowych. Wartość 2 vCPU i 4 GB RAM, powtarzana na stronach hostingowych, jest domyślną ofertą dostawcy, a nie wynikiem pomiarów i jest wartością zawyżoną dla małej tablicy. Całe obciążenie stanowi jeden proces Node i jeden proces Postgres, więc plan z 1 vCPU i 2 GB 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 uważniej monitorować dysk niż pamięć, ponieważ to załączniki generują przyrost danych.

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. Należy pozostawić tag Postgres przypięty do wersji głównej, ponieważ serwer odmawia otwarcia katalogu danych zapisanego przez inną wersję główną.