--- title: "Jak działa to demo: portal statyczny + CMS oparty o git" description: "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." date: 2026-07-23 category: demo author: Cyfronet cover: /uploads/diagrams/cover-git-cms.svg lang: pl draft: 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](/uploads/diagrams/od-zapisu-do-publikacji.svg) 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](/uploads/diagrams/architektura-maszyna.svg) 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](/uploads/diagrams/architektura-cms-z-baza.svg) ## 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](/uploads/diagrams/powierzchnia-ataku.svg) - **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 `