Kanał Urzędu Miejskiego w Starym Sączu na videoportalu gminy, w przeglądarce i na telefonie, z karminowym akcentem

Programowanie

Videoportal Gminy Stary Sącz

Własny serwis wideo gminy na PeerTube: motyw spójny z portalem i zgodny z WCAG, aktualizacja PeerTube i PostgreSQL bez utraty nagrań oraz cache, dzięki któremu transmisje sesji rady przestały się zacinać.

11.10.2026

Gmina Stary Sącz ma własny serwis wideo pod adresem video.starysacz.um.gov.pl. Są tam nagrania i transmisje sesji Rady Miejskiej, filmy z wydarzeń i materiały promocyjne. Kanał urzędu ma już ponad 140 filmów.

Portal działa na PeerTube, otwartym odpowiedniku YouTube, na serwerach gminy. Bez reklam, bez algorytmu podsuwającego cudze filmy i bez przekazywania danych widzów platformom zewnętrznym.

Moje zadanie było trzyelementowe: podnieść zaległą wersję systemu, rozwiązać problemy z transmisjami na żywo i dopasować wygląd do nowego portalu gminy.

Kanał Urzędu Miejskiego w Starym Sączu na videoportalu gminy, w przeglądarce i na telefonie, z karminowym akcentem
Videoportal gminy na komputerze i telefonie

Motyw spójny z portalem gminy

Videoportal wyglądał jak każda instancja PeerTube. Przygotowałem własny motyw, który bierze z portalu gminy fonty, kształty i neutralne kolory. Akcent jest karminowy, z korony w herbie, żeby od razu było widać, że to osobny serwis tej samej gminy.

  • fonty self-hosted Atkinson Hyperlegible Next i Bricolage Grotesque, z polskimi znakami,
  • tryb jasny i ciemny według ustawień systemu oraz wariant wysokiego kontrastu,
  • wszystkie pary tekstu i tła z kontrastem co najmniej 4,5:1, obrys pól formularzy 3:1,
  • wyraźny fokus klawiatury i oznaczenie bieżącej pozycji w menu,
  • opisy filmów i komentarze w 16 pikselach zamiast 14.

Motyw jest osobną paczką z własnym numerem wersji. Wbudowany motyw PeerTube zostaje na miejscu, więc w razie problemu wystarczy jedno przełączenie w panelu.

Strona nagrania sesji Rady Miejskiej w motywie jasnym i ciemnym
Nagranie sesji w motywie jasnym i ciemnym

Aktualizacja bez utraty nagrań

Portal stał na PeerTube 7.2 i PostgreSQL 13. Obie wersje miały już następców, a PostgreSQL 13 zbliżał się do końca wsparcia. Aktualizację zrobiłem w dwóch krokach, każdy ze skryptem i pełną kopią:

  • PeerTube 7.2 do 8.2 z migracjami bazy,
  • PostgreSQL 13 do 17 i PeerTube 8.3,
  • aktualizacja yt-dlp, którego PeerTube używa do importu filmów,
  • stare kontenery zostały zatrzymane, ale nieusunięte, do czasu potwierdzenia, że wszystko działa.

Przy okazji wyszedł błąd, którego nikt nie zauważył: kontener od sześciu dni zgłaszał stan „unhealthy”, bo test zdrowia używał narzędzia, którego nie było w nowym obrazie. Teraz test pyta po prostu API PeerTube.

Transmisje sesji, które się nie zacinają

Najbardziej odczuwalny problem dotyczył transmisji na żywo. Przy 30-40 widzach sesji rady część osób dostawała błędy przekroczenia czasu. Każdy widz pobierał te same, duże fragmenty filmu prosto z serwera PeerTube.

Rozwiązaniem jest cache w reverse proxy. nginx tnie segmenty wideo na kawałki po 1 MB i trzyma je w pamięci podręcznej przez dwie godziny. Playlista odświeża się co 5 sekund, więc transmisja nadal idzie na żywo.

Schemat: PeerTube wystawia segmenty transmisji, reverse proxy nginx przechowuje je w cache w kawałkach po 1 MB, widzowie pobierają je z cache
Jak cache w proxy odciąża serwer wideo podczas transmisji

Druga poprawka była mniej widoczna, ale ważna. PeerTube widział każdego widza jako adres serwera proxy. Przez to liczniki wyświetleń były zaniżone, a ochrona przed zgadywaniem haseł nie mogła działać. Po poprawieniu konfiguracji zaufanych proxy portal widzi prawdziwe adresy.

Ochrona całego proxy

Skoro i tak pracowałem na serwerze proxy, wdrożyłem na nim CrowdSec. Analizuje logi wszystkich stron, które przez niego przechodzą, i blokuje adresy na poziomie zapory. Korzysta też ze wspólnej listy adresów zgłaszanych przez innych użytkowników.

Do podglądu blokad i alertów napisałem prosty, wewnętrzny panel, który odświeża się co 30 sekund.

Treści, których wymaga prawo

Videoportal gminy to też serwis publiczny. Dostał deklarację dostępności, informację o ochronie danych osobowych i osobną klauzulę dla transmisji sesji, na wzór portalu gminy. Poczta wychodząca działa przez serwer pocztowy urzędu.

Transmisję sesji ogląda czasem kilkadziesiąt osób, czasem kilkaset. Dla każdej z nich to jedyna droga, żeby zobaczyć, jak radni głosują. Ona po prostu musi działać.

- Aleksander Kowal

Stack

  • PeerTube 8.3 w Dockerze, PostgreSQL 17,
  • własny motyw PeerTube z wersjonowaniem i CI na OneDev,
  • nginx (Nginx Proxy Manager) z cache HLS w module slice,
  • CrowdSec z bouncerem na zaporze.