Files
content/news/architektura-demo-git-cms.md
T

9.6 KiB

title, description, date, category, author, cover, lang, draft
title description date category author cover lang draft
Jak działa to demo: portal statyczny + CMS oparty o git Architektura rozwiązania, przydatne linki i porównanie klas rozwiązań: strona w 100% statyczna z graficznym edytorem treści vs CMS z własną bazą danych. 2026-07-23 demo Cyfronet /uploads/diagrams/cover-git-cms.svg pl false

Ten portal to statyczne pliki HTML generowane z plików Markdown trzymanych w repozytorium git. Redaktor dostaje graficzny edytor w przeglądarce — a mimo to po stronie publicznej nie działa żadna aplikacja ani baza: między czytelnikiem a treścią jest wyłącznie serwer plików. Jedyny działający serwis (Gitea) obsługuje edycję i stoi poza ścieżką czytelnika — wracamy do tego uczciwie niżej. Ten artykuł został napisany i opublikowany dokładnie tą ścieżką.

Od zapisu do publikacji

Pięć kroków publikacji: zapis w edytorze → commit w repo → detekcja zmiany → build strony → publikacja

Publikacja jest automatyczna — zapis w edytorze po chwili sam pojawia się na stronie, bez żadnego ręcznego deployu. Każda zmiana to commit, więc pełna historia treści i możliwość cofnięcia są w gicie za darmo.

Jak to wygląda na maszynie

Architektura na maszynie demo: redaktor zapisuje przez Sveltię do Gitei, timer systemd uruchamia jednorazowy kontener builda Astro, wynik trafia do wolumenu releases, a nginx serwuje czytelnikom wyłącznie statyczne pliki

Dla porównania — ta sama maszyna z klasycznym CMS-em. Układ diagramu jest celowo identyczny, żeby różnice było widać na pierwszy rzut oka: tu każdy element działa bez przerwy, a panel logowania i aplikacja są wystawione do internetu.

Architektura klasycznego CMS z bazą danych: aplikacja z publicznym panelem admina i renderowaniem na żądanie działa non stop, obok baza danych wymagająca backupów i wolumen mediów

Gdzie co jest

Co Gdzie
Portal strona główna tego serwisu
Edytor treści /admin/ (link „Content editor" w stopce)
Gitea (repo ctao/portal) port 3000 na maszynie demo
Konto demo użytkownik ctao (hasło u prowadzącego demo)
Dokumentacja wdrożenia katalog deploy/ w repo kodu: README.md (runbook)

Całość działa w podmanie na jednej maszynie: kontener Gitei, kontener nginx i jednorazowy kontener builda odpalany przez systemd timer.

Dlaczego strona statyczna

Porównanie powierzchni ataku: CMS z bazą wystawia publicznie aplikację, panel logowania, bazę i pluginy — tu publiczne są tylko pliki HTML, a edycja idzie przez git dla zalogowanych

  • Bezpieczeństwo: publicznie wystawione są tylko pliki. Nie istnieje panel admina dostępny z internetu, baza do wykradzenia ani runtime z CVE.
  • Utrzymanie: nie ma aplikacji, która musi być monitorowana i aktualizowana pod presją łatek bezpieczeństwa. Do utrzymania zostaje git (który i tak utrzymujemy) i krótki skrypt builda.
  • Szybkość: statyczny HTML to najszybsza możliwa strona — istotne też dla SEO.
  • Historia: wersjonowanie treści to naturalna cecha gita, nie płatna funkcja produktu.

Dwie klasy rozwiązań

Linia podziału jest często mylona: nie chodzi o to, czy treść leży w bazie czy w plikach, tylko o to, czy między czytelnikiem a treścią stoi działająca aplikacja.

Statyczne + git-CMS (to demo) CMS serwujący stronę aplikacją
Przykłady Sveltia, Decap (+ Astro / Hugo / Eleventy) Strapi, WordPress, Drupal, Grav, TinaCMS
Treść żyje w plikach Markdown w gicie zwykle w bazie; Grav — w plikach, Tina — w gicie
W produkcji działa serwer plików aplikacja (zwykle + baza), non stop
Utrzymanie skrypt builda + serwis gitowy patche, aktualizacje, backupy bazy
Historia zmian git, wbudowana zależnie od produktu (bywa płatna)

Dwa doprecyzowania, żeby tabela nie upraszczała: Grav trzyma treść w plikach bez żadnej bazy — ale stronę i tak serwuje aplikacja PHP, więc pod względem powierzchni ataku i utrzymania należy do prawej kolumny. TinaCMS trzyma treść wręcz w Markdownie w gicie, ale do działania edytora wymaga stale działającego backendu z bazą — jest hybrydą, która dziedziczy koszty obu światów.

Ograniczenia poszczególnych rozwiązań, które zweryfikowaliśmy podczas researchu:

  • Strapi — historia wersji treści nie istnieje w darmowym self-hosted (tylko płatne plany Growth/Enterprise). Wymaga stale działającego Node + Postgresa i regularnych aktualizacji.
  • WordPress — największy ekosystem, ale i największa historia podatności (głównie pluginy); publiczny panel logowania i PHP do ciągłego patchowania.
  • Grav (PHP, flat-file — „lekka" alternatywa) — poważne podatności RCE w ostatnich latach; nadal wymaga serwera PHP wystawionego do internetu.
  • TinaCMS — edytuje Markdown, ale wymaga backendu: chmura Tina jest darmowa tylko do 2 użytkowników, a self-hosting to własny serwer Node + baza (Mongo/Postgres) + auth — wracamy do utrzymywania aplikacji.
  • Ryzyko open-core: funkcje potrafią z czasem przechodzić do płatnych planów (przykład wyżej). Gdy treść i jej historia leżą w gicie, nie ma funkcji, którą dostawca mógłby przenieść do płatnego planu.

Plusy i minusy obu podejść

Portal ma być utrzymywany przez co najmniej 6 lat, więc bilans trzeba robić w dwóch horyzontach. Poniżej ocena podejść jako klas rozwiązań, nie konkretnych produktów.

Krótkoterminowo (uruchomienie i pierwsze miesiące)

Statyczne + git CMS z bazą
Plusy mało ruchomych części od pierwszego dnia; edytor graficzny gotowy; historia i rollback od razu, w gicie bogatszy panel od ręki: role i uprawnienia, workflow redakcyjny, relacje między treściami, więcej gotowych integracji
Minusy uprawnienia proste (dziedziczone z gita — bez ról redakcyjnych); przeglądanie historii na razie w interfejsie gita, nie w edytorze więcej komponentów do postawienia, spięcia i zabezpieczenia od pierwszego dnia (aplikacja, baza, backupy)

W horyzoncie 6 lat

Statyczne + git CMS z bazą
Plusy strona publiczna bez aplikacji = brak presji łatek na ścieżce czytelnika; do utrzymania zostaje serwis gitowy (najlepiej ten, który zespół i tak ma); treść w otwartym formacie przetrwa każdą wymianę narzędzi jeśli z czasem będą potrzebne funkcje aplikacyjne (konta, personalizacja, treści silnie strukturalne), platforma już je ma
Minusy przy bardzo dużej skali (tysiące stron) buildy rosną i wymagają optymalizacji; zaawansowane funkcje redakcyjne zależą od tempa rozwoju narzędzi open-source kilka dużych migracji wersji w 6 lat (zmiany łamiące); baza wymaga backupów i testów odtwarzania; stała powierzchnia ataku; ryzyko przenoszenia funkcji do płatnych planów

„Czy Gitea to nie jest po prostu drugi CMS?"

Uczciwe pytanie: Gitea też ma logowanie, bazę i wymaga aktualizacji bezpieczeństwa, a dla edytorów musi być dostępna spoza VPN. Czy różnica nie sprowadza się więc do tego, że zamiast CMS-a utrzymujemy Giteę?

Częściowo tak — i dlatego nie twierdzimy, że utrzymanie jest zerowe. Różnica polega na trzech rzeczach:

  • Gitea stoi poza ścieżką czytelnika. Może mieć przerwę, aktualizację, a nawet zostać przejęta — portal dalej stoi i serwuje bezpieczne pliki. Najgorszy scenariusz włamania to wandalizm treści: widoczny, z pełną historią, odwracalny jednym revertem. W CMS-ie serwującym stronę ten sam incydent oznacza przejętą stronę publiczną.
  • Zespół już utrzymuje Giteę. Docelowo repozytorium treści może żyć na istniejącej instancji zespołu — wtedy krańcowy koszt utrzymania jest bliski zera, a logowanie załatwia jedna integracja z AAI.
  • Klasa oprogramowania. Gitea to pojedynczy program w Go z SQLite: aktualizacja to podmiana obrazu i restart, bez ekosystemu pluginów i bez drzewa zależności npm po stronie serwera. Platformy CMS to frameworki aplikacyjne z regularnymi migracjami głównych wersji.

Gdzie jeszcze może się przydać

Ten sam wzorzec — edytor graficzny nad repozytorium Markdown — nie jest ograniczony do portalu. Naturalni kandydaci u nas:

  • Projekt Mickiewicza — treści redagowane przez osoby nietechniczne, a publikowane jako strona statyczna.
  • Dokumentacja Episodes Platform — już dziś jest w Markdownie; podpięcie edytora dałoby wygodną edycję w przeglądarce zamiast edytora plików w Gitei, bez żadnych zmian w istniejącym repozytorium.

Koszt wdrożenia w takich miejscach jest niewielki: edytor to jeden statyczny plik HTML plus konfiguracja wskazująca repozytorium i strukturę treści.

Brak lock-inu

Każdy element jest wymienialny osobno, bo treść to czysty Markdown:

  • Sveltia ↔ Decap — ten sam format konfiguracji; podmiana = jedna linijka <script>.
  • Astro ↔ Hugo / Eleventy — Markdown zostaje bez zmian, wymieniamy tylko szablony.
  • Gitea ↔ dowolny hosting gitowy — GitHub, GitLab i inne.
  • Nawet rezygnacja z całego podejścia = eksport trywialny, bo treść od początku leży w otwartym formacie w naszym repozytorium.

Wniosek z tego demo: zaczynamy od najprostszego rozwiązania, które spełnia wymagania — graficzny edytor dla redaktorów i bezpieczna, bezobsługowa strona publiczna. Złożoność dodajemy dopiero wtedy, gdy pojawi się potrzeba, której to podejście nie obsłuży.