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 | /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
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
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.
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: README.md (runbook) i DEPLOY-LOG.md (pełna historia decyzji) |
Całość działa w podmanie na jednej maszynie: kontener Gitei, kontener nginx i jednorazowy kontener builda odpalany przez systemd timer.
Dlaczego strona statyczna
- 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.