demo article in English: stack overview and redesigned architecture diagrams
@@ -0,0 +1,101 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 800" role="img" aria-label="Architecture of a database-backed CMS: one always-on application serves both the editor's admin panel and the reader's pages, backed by a database that needs backups and a separate media volume">
|
||||
<defs>
|
||||
<marker id="arrB" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M0 0 L10 5 L0 10 z" fill="#00004a"/>
|
||||
</marker>
|
||||
<filter id="softB" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="0" dy="2" stdDeviation="5" flood-color="#00004a" flood-opacity="0.10"/>
|
||||
</filter>
|
||||
<style>
|
||||
.t { font-family: Inter, "Segoe UI", Arial, sans-serif; }
|
||||
.box { fill: #ffffff; stroke: #00004a; stroke-width: 1.5; }
|
||||
.sub { fill: #f5f5f5; stroke: #e2e5ee; stroke-width: 1; }
|
||||
.ttl { font-weight: 700; font-size: 19px; fill: #00004a; letter-spacing: .04em; }
|
||||
.act { font-weight: 700; font-size: 18px; fill: #00004a; }
|
||||
.cap { font-size: 15px; fill: #46536a; }
|
||||
.sml { font-size: 14px; fill: #46536a; }
|
||||
.lbl { font-size: 14px; fill: #46536a; paint-order: stroke; stroke: #f8f9fc; stroke-width: 5; }
|
||||
.chipbg { fill: #e9ebf3; }
|
||||
.chip { font-size: 12.5px; font-weight: 700; fill: #00004a; letter-spacing: .06em; }
|
||||
.flow { stroke: #00004a; stroke-width: 1.8; fill: none; marker-end: url(#arrB); }
|
||||
.name { font-size: 16px; font-weight: 700; fill: #101228; }
|
||||
.pill { fill: #f5f5f5; stroke: #e2e5ee; }
|
||||
.pilltxt { font-size: 14px; fill: #101228; }
|
||||
</style>
|
||||
</defs>
|
||||
|
||||
<!-- actor: editor -->
|
||||
<g filter="url(#softB)"><rect class="box" x="49" y="20" width="380" height="86" rx="16"/></g>
|
||||
<circle cx="80" cy="48" r="11" fill="none" stroke="#00004a" stroke-width="1.8"/>
|
||||
<path d="M64 78 q16 -18 32 0" fill="none" stroke="#00004a" stroke-width="1.8"/>
|
||||
<text class="t act" x="108" y="54">Editor</text>
|
||||
<text class="t sml" x="108" y="80">admin panel in the browser, signs in</text>
|
||||
|
||||
<!-- actor: reader -->
|
||||
<g filter="url(#softB)"><rect class="box" x="395" y="20" width="380" height="86" rx="16"/></g>
|
||||
<circle cx="426" cy="48" r="11" fill="none" stroke="#00004a" stroke-width="1.8"/>
|
||||
<path d="M410 78 q16 -18 32 0" fill="none" stroke="#00004a" stroke-width="1.8"/>
|
||||
<text class="t act" x="454" y="54">Reader</text>
|
||||
<text class="t sml" x="454" y="80">the public portal, assembled live</text>
|
||||
|
||||
<!-- machine boundary (same vertical skeleton as the static diagram) -->
|
||||
<rect x="30" y="158" width="740" height="560" rx="18" fill="#f8f9fc" stroke="#e2e5ee" stroke-width="1.5"/>
|
||||
<text class="t" x="400" y="194" text-anchor="middle" font-size="14" font-weight="700" fill="#00004a" letter-spacing=".18em">MACHINE · DATABASE-BACKED CMS</text>
|
||||
<text class="t sml" x="400" y="216" text-anchor="middle">WordPress, Strapi, Drupal and the like</text>
|
||||
|
||||
<path class="flow" d="M239 106 V232"/>
|
||||
<text class="t lbl" x="253" y="150">sign in to the panel</text>
|
||||
<path class="flow" d="M585 232 V110"/>
|
||||
<text class="t lbl" x="599" y="150">HTML built per request</text>
|
||||
|
||||
<!-- the application: always on, serves everybody -->
|
||||
<g filter="url(#softB)"><rect class="box" x="60" y="238" width="680" height="210" rx="16"/></g>
|
||||
<text class="t ttl" x="88" y="278">CMS APPLICATION</text>
|
||||
<rect class="chipbg" x="290" y="258" width="110" height="24" rx="12"/>
|
||||
<text class="t chip" x="345" y="275" text-anchor="middle">ALWAYS ON</text>
|
||||
<rect class="sub" x="84" y="298" width="204" height="130" rx="12"/>
|
||||
<text class="t name" x="104" y="330">admin panel</text>
|
||||
<text class="t cap" x="104" y="356">public address</text>
|
||||
<text class="t cap" x="104" y="378">and login, open</text>
|
||||
<text class="t cap" x="104" y="400">to the internet</text>
|
||||
<rect class="sub" x="298" y="298" width="204" height="130" rx="12"/>
|
||||
<text class="t name" x="318" y="330">page rendering</text>
|
||||
<text class="t cap" x="318" y="356">every visit is</text>
|
||||
<text class="t cap" x="318" y="378">work for the app</text>
|
||||
<text class="t cap" x="318" y="400">and the database</text>
|
||||
<rect class="sub" x="512" y="298" width="204" height="130" rx="12"/>
|
||||
<text class="t name" x="532" y="330">plugins</text>
|
||||
<text class="t cap" x="532" y="356">each with its own</text>
|
||||
<text class="t cap" x="532" y="378">update cycle and</text>
|
||||
<text class="t cap" x="532" y="400">its own bugs</text>
|
||||
|
||||
<path class="flow" d="M239 448 V504"/>
|
||||
<text class="t lbl" x="253" y="484">upload</text>
|
||||
<path class="flow" d="M585 448 V504"/>
|
||||
<text class="t lbl" x="599" y="484">SQL</text>
|
||||
|
||||
<!-- media volume -->
|
||||
<g filter="url(#softB)"><rect class="sub" x="60" y="508" width="310" height="170" rx="16"/></g>
|
||||
<text class="t ttl" x="88" y="546">media/</text>
|
||||
<rect class="chipbg" x="180" y="526" width="86" height="24" rx="12"/>
|
||||
<text class="t chip" x="223" y="543" text-anchor="middle">VOLUME</text>
|
||||
<text class="t cap" x="88" y="582">images and files</text>
|
||||
<text class="t cap" x="88" y="606">outside the database</text>
|
||||
<text class="t cap" x="88" y="630">backed up separately</text>
|
||||
|
||||
<!-- database -->
|
||||
<g filter="url(#softB)"><rect class="box" x="430" y="508" width="310" height="170" rx="16"/></g>
|
||||
<text class="t ttl" x="458" y="546">DATABASE</text>
|
||||
<rect class="chipbg" x="590" y="526" width="110" height="24" rx="12"/>
|
||||
<text class="t chip" x="645" y="543" text-anchor="middle">ALWAYS ON</text>
|
||||
<text class="t cap" x="458" y="582">content and accounts</text>
|
||||
<text class="t cap" x="458" y="606">backups and restore drills</text>
|
||||
<text class="t cap" x="458" y="630">schema migrations</text>
|
||||
<text class="t cap" x="458" y="654">on every upgrade</text>
|
||||
|
||||
<!-- summary pills -->
|
||||
<rect class="pill" x="60" y="740" width="330" height="46" rx="23"/>
|
||||
<text class="t pilltxt" x="225" y="768" text-anchor="middle">two processes run non stop, day and night</text>
|
||||
<rect class="pill" x="410" y="740" width="330" height="46" rx="23"/>
|
||||
<text class="t pilltxt" x="575" y="768" text-anchor="middle">security updates are a standing duty</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.0 KiB |
@@ -0,0 +1,105 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 1040" role="img" aria-label="Architecture on the demo machine: the editor writes through Sveltia into the Gitea content repository, a systemd timer runs a one-shot Astro build container that overlays content onto the code repository, the result lands in the releases volume and nginx serves readers static files only">
|
||||
<defs>
|
||||
<marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M0 0 L10 5 L0 10 z" fill="#00004a"/>
|
||||
</marker>
|
||||
<filter id="soft" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="0" dy="2" stdDeviation="5" flood-color="#00004a" flood-opacity="0.10"/>
|
||||
</filter>
|
||||
<style>
|
||||
.t { font-family: Inter, "Segoe UI", Arial, sans-serif; }
|
||||
.box { fill: #ffffff; stroke: #00004a; stroke-width: 1.5; }
|
||||
.sub { fill: #f5f5f5; stroke: #e2e5ee; stroke-width: 1; }
|
||||
.ttl { font-weight: 700; font-size: 19px; fill: #00004a; letter-spacing: .04em; }
|
||||
.act { font-weight: 700; font-size: 18px; fill: #00004a; }
|
||||
.cap { font-size: 15px; fill: #46536a; }
|
||||
.sml { font-size: 14px; fill: #46536a; }
|
||||
.lbl { font-size: 14px; fill: #46536a; paint-order: stroke; stroke: #f8f9fc; stroke-width: 5; }
|
||||
.chipbg { fill: #d2faf7; }
|
||||
.chip { font-size: 12.5px; font-weight: 700; fill: #00004a; letter-spacing: .06em; }
|
||||
.flow { stroke: #00004a; stroke-width: 1.8; fill: none; marker-end: url(#arr); }
|
||||
.mono { font-family: "SF Mono", Consolas, Menlo, monospace; font-size: 14px; fill: #101228; }
|
||||
.name { font-size: 16px; font-weight: 700; fill: #101228; }
|
||||
</style>
|
||||
</defs>
|
||||
|
||||
<!-- actor: editor -->
|
||||
<g filter="url(#soft)"><rect class="box" x="49" y="20" width="380" height="86" rx="16"/></g>
|
||||
<circle cx="80" cy="48" r="11" fill="none" stroke="#00004a" stroke-width="1.8"/>
|
||||
<path d="M64 78 q16 -18 32 0" fill="none" stroke="#00004a" stroke-width="1.8"/>
|
||||
<text class="t act" x="108" y="54">Editor</text>
|
||||
<text class="t sml" x="108" y="80">browser · <tspan font-weight="600">/admin/</tspan> (Sveltia), visual editing</text>
|
||||
|
||||
<!-- machine boundary -->
|
||||
<rect x="30" y="158" width="740" height="730" rx="18" fill="#f8f9fc" stroke="#e2e5ee" stroke-width="1.5"/>
|
||||
<text class="t" x="400" y="194" text-anchor="middle" font-size="14" font-weight="700" fill="#00004a" letter-spacing=".18em">DEMO MACHINE · PODMAN</text>
|
||||
<text class="t sml" x="400" y="216" text-anchor="middle">separate containers under systemd</text>
|
||||
|
||||
<path class="flow" d="M239 106 V232"/>
|
||||
<text class="t lbl" x="253" y="150">save through the API (OAuth)</text>
|
||||
|
||||
<!-- gitea: two repositories -->
|
||||
<g filter="url(#soft)"><rect class="box" x="60" y="238" width="680" height="190" rx="16"/></g>
|
||||
<text class="t ttl" x="88" y="278">GITEA</text>
|
||||
<rect class="chipbg" x="170" y="258" width="62" height="24" rx="12"/>
|
||||
<text class="t chip" x="201" y="275" text-anchor="middle">:3000</text>
|
||||
<rect class="sub" x="84" y="298" width="310" height="108" rx="12"/>
|
||||
<text class="t name" x="106" y="330">ctao/content</text>
|
||||
<text class="t cap" x="106" y="356">Markdown and images,</text>
|
||||
<text class="t cap" x="106" y="380">written by the CMS</text>
|
||||
<rect class="sub" x="414" y="298" width="302" height="108" rx="12"/>
|
||||
<text class="t name" x="436" y="330">ctao/portal</text>
|
||||
<text class="t cap" x="436" y="356">portal code,</text>
|
||||
<text class="t cap" x="436" y="380">maintained by the team</text>
|
||||
|
||||
<path class="flow" d="M400 428 V454"/>
|
||||
<text class="t lbl" x="414" y="447">git fetch, both repos</text>
|
||||
|
||||
<!-- build (ephemeral) -->
|
||||
<g filter="url(#soft)">
|
||||
<rect x="60" y="460" width="680" height="190" rx="16" fill="#ffffff" stroke="#00004a" stroke-width="1.5" stroke-dasharray="7 5"/>
|
||||
</g>
|
||||
<text class="t ttl" x="88" y="500">BUILD · ASTRO</text>
|
||||
<rect class="chipbg" x="250" y="480" width="190" height="24" rx="12"/>
|
||||
<text class="t chip" x="345" y="497" text-anchor="middle">ONE-SHOT CONTAINER</text>
|
||||
<text class="t cap" x="88" y="536">a systemd timer checks both repositories every 10 seconds</text>
|
||||
<text class="t cap" x="88" y="564">on a change: fetch both, overlay content onto code</text>
|
||||
<text class="t cap" x="88" y="592" font-weight="700" fill="#101228">Markdown becomes static HTML</text>
|
||||
<text class="t cap" x="88" y="620">the container exits when the build is done</text>
|
||||
|
||||
<path class="flow" d="M400 650 V676"/>
|
||||
<text class="t lbl" x="414" y="669">new version of the site</text>
|
||||
|
||||
<!-- releases volume -->
|
||||
<g filter="url(#soft)"><rect class="sub" x="60" y="682" width="310" height="176" rx="16"/></g>
|
||||
<text class="t ttl" x="88" y="720">releases/</text>
|
||||
<rect class="chipbg" x="196" y="700" width="86" height="24" rx="12"/>
|
||||
<text class="t chip" x="239" y="717" text-anchor="middle">VOLUME</text>
|
||||
<text class="t mono" x="88" y="754">9f2c1d-43e2bb/ previous</text>
|
||||
<text class="t mono" x="88" y="778">71b980-8c1a2f/ <tspan font-weight="700" fill="#00004a">← current</tspan></text>
|
||||
<text class="t cap" x="88" y="812">atomic swap,</text>
|
||||
<text class="t cap" x="88" y="836">zero downtime</text>
|
||||
|
||||
<!-- nginx -->
|
||||
<g filter="url(#soft)"><rect class="box" x="430" y="682" width="310" height="176" rx="16"/></g>
|
||||
<text class="t ttl" x="458" y="720">NGINX</text>
|
||||
<rect class="chipbg" x="540" y="700" width="62" height="24" rx="12"/>
|
||||
<text class="t chip" x="571" y="717" text-anchor="middle">:8080</text>
|
||||
<text class="t cap" x="458" y="754">serves <tspan font-weight="600">releases/current</tspan></text>
|
||||
<text class="t cap" x="458" y="782">static files only</text>
|
||||
<text class="t cap" x="458" y="810">no application, no database,</text>
|
||||
<text class="t cap" x="458" y="836">no PHP, no plugins</text>
|
||||
|
||||
<path class="flow" d="M372 770 H424"/>
|
||||
<text class="t lbl" x="398" y="756" text-anchor="middle">current/</text>
|
||||
|
||||
<path class="flow" d="M585 860 V930"/>
|
||||
<text class="t lbl" x="599" y="900">static HTML</text>
|
||||
|
||||
<!-- actor: reader -->
|
||||
<g filter="url(#soft)"><rect class="box" x="395" y="940" width="380" height="86" rx="16"/></g>
|
||||
<circle cx="426" cy="968" r="11" fill="none" stroke="#00004a" stroke-width="1.8"/>
|
||||
<path d="M410 998 q16 -18 32 0" fill="none" stroke="#00004a" stroke-width="1.8"/>
|
||||
<text class="t act" x="454" y="974">Reader</text>
|
||||
<text class="t sml" x="454" y="1000">the public portal, plain and fast HTML</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.3 KiB |
@@ -1,110 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 640" role="img" aria-label="Architektura klasycznego CMS z bazą danych: aplikacja CMS z publicznym panelem admina działa non stop, obok baza danych i wolumen mediów; czytelnik dostaje strony renderowane na żądanie">
|
||||
<defs>
|
||||
<marker id="arrB" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M0 0 L10 5 L0 10 z" fill="#00004a"/>
|
||||
</marker>
|
||||
<filter id="softB" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="0" dy="2" stdDeviation="5" flood-color="#00004a" flood-opacity="0.10"/>
|
||||
</filter>
|
||||
<style>
|
||||
.t { font-family: Inter, "Segoe UI", Arial, sans-serif; }
|
||||
.box { fill: #ffffff; stroke: #00004a; stroke-width: 1.5; }
|
||||
.sub { fill: #f5f5f5; stroke: #e2e5ee; stroke-width: 1; }
|
||||
.ttl { font-weight: 700; font-size: 15.5px; fill: #00004a; letter-spacing: .04em; }
|
||||
.cap { font-size: 12.5px; fill: #46536a; }
|
||||
.lbl { font-size: 12px; fill: #46536a; paint-order: stroke; stroke: #ffffff; stroke-width: 4; }
|
||||
.chipbg { fill: #e9ebf3; }
|
||||
.chip { font-size: 11.5px; font-weight: 700; fill: #00004a; letter-spacing: .06em; }
|
||||
.flow { stroke: #00004a; stroke-width: 1.8; fill: none; marker-end: url(#arrB); }
|
||||
.pill { fill: #f5f5f5; stroke: #e2e5ee; }
|
||||
.pilltxt { font-size: 12.5px; fill: #101228; }
|
||||
</style>
|
||||
</defs>
|
||||
|
||||
<!-- machine boundary (mirrors the static-demo diagram 1:1) -->
|
||||
<rect x="340" y="40" width="830" height="570" rx="18" fill="#f8f9fc" stroke="#e2e5ee" stroke-width="1.5"/>
|
||||
<text class="t" x="366" y="76" font-size="13" font-weight="700" fill="#00004a" letter-spacing=".18em">MASZYNA · CMS Z BAZĄ DANYCH</text>
|
||||
<text class="t cap" x="366" y="96">np. WordPress, Strapi, Drupal — wspólny schemat tej klasy rozwiązań</text>
|
||||
|
||||
<!-- actor: redaktor -->
|
||||
<g filter="url(#softB)">
|
||||
<rect class="box" x="52" y="120" width="220" height="120" rx="16"/>
|
||||
</g>
|
||||
<circle cx="88" cy="156" r="11" fill="none" stroke="#00004a" stroke-width="1.8"/>
|
||||
<path d="M72 186 q16 -18 32 0" fill="none" stroke="#00004a" stroke-width="1.8"/>
|
||||
<text class="t ttl" x="116" y="162">Redaktor</text>
|
||||
<text class="t cap" x="70" y="212">panel admina w przeglądarce</text>
|
||||
<text class="t cap" x="70" y="228">logowanie do aplikacji</text>
|
||||
|
||||
<!-- actor: czytelnik -->
|
||||
<g filter="url(#softB)">
|
||||
<rect class="box" x="52" y="400" width="220" height="120" rx="16"/>
|
||||
</g>
|
||||
<circle cx="88" cy="436" r="11" fill="none" stroke="#00004a" stroke-width="1.8"/>
|
||||
<path d="M72 466 q16 -18 32 0" fill="none" stroke="#00004a" stroke-width="1.8"/>
|
||||
<text class="t ttl" x="116" y="442">Czytelnik</text>
|
||||
<text class="t cap" x="70" y="492">publiczna strona portalu</text>
|
||||
<text class="t cap" x="70" y="508">HTML składany na żądanie</text>
|
||||
|
||||
<!-- CMS application (tall box, always running) -->
|
||||
<g filter="url(#softB)">
|
||||
<rect class="box" x="400" y="120" width="320" height="400" rx="16"/>
|
||||
</g>
|
||||
<text class="t ttl" x="424" y="152">APLIKACJA CMS</text>
|
||||
<rect class="chipbg" x="590" y="136" width="106" height="22" rx="11"/>
|
||||
<text class="t chip" x="643" y="151" text-anchor="middle">NON STOP</text>
|
||||
<rect class="sub" x="420" y="176" width="280" height="88" rx="12"/>
|
||||
<text class="t" x="436" y="202" font-size="13.5" font-weight="700" fill="#101228">panel admina</text>
|
||||
<text class="t cap" x="436" y="224">publiczny adres + logowanie</text>
|
||||
<text class="t cap" x="436" y="242">z internetu</text>
|
||||
<rect class="sub" x="420" y="278" width="280" height="88" rx="12"/>
|
||||
<text class="t" x="436" y="304" font-size="13.5" font-weight="700" fill="#101228">renderowanie stron</text>
|
||||
<text class="t cap" x="436" y="326">każde wejście czytelnika =</text>
|
||||
<text class="t cap" x="436" y="344">praca aplikacji i bazy</text>
|
||||
<rect class="sub" x="420" y="380" width="280" height="88" rx="12"/>
|
||||
<text class="t" x="436" y="406" font-size="13.5" font-weight="700" fill="#101228">pluginy / rozszerzenia</text>
|
||||
<text class="t cap" x="436" y="428">własny cykl aktualizacji</text>
|
||||
<text class="t cap" x="436" y="446">i podatności</text>
|
||||
|
||||
<!-- database -->
|
||||
<g filter="url(#softB)">
|
||||
<rect class="box" x="790" y="120" width="340" height="185" rx="16"/>
|
||||
</g>
|
||||
<text class="t ttl" x="814" y="152">BAZA DANYCH</text>
|
||||
<rect class="chipbg" x="972" y="136" width="106" height="22" rx="11"/>
|
||||
<text class="t chip" x="1025" y="151" text-anchor="middle">NON STOP</text>
|
||||
<text class="t cap" x="814" y="188">treść + konta użytkowników</text>
|
||||
<text class="t cap" x="814" y="212">wymaga backupów i testów odtwarzania</text>
|
||||
<text class="t cap" x="814" y="236">migracje schematu przy aktualizacjach</text>
|
||||
<text class="t cap" x="814" y="266">historia zmian: zależnie od produktu,</text>
|
||||
<text class="t cap" x="814" y="284">bywa funkcją płatną</text>
|
||||
|
||||
<!-- media volume -->
|
||||
<g filter="url(#softB)">
|
||||
<rect class="sub" x="790" y="400" width="340" height="120" rx="16"/>
|
||||
</g>
|
||||
<text class="t ttl" x="814" y="432">media/</text>
|
||||
<rect class="chipbg" x="896" y="416" width="82" height="22" rx="11"/>
|
||||
<text class="t chip" x="937" y="431" text-anchor="middle">WOLUMEN</text>
|
||||
<text class="t cap" x="814" y="462">obrazy i pliki poza bazą</text>
|
||||
<text class="t cap" x="814" y="480">osobny backup</text>
|
||||
|
||||
<!-- flows -->
|
||||
<path class="flow" d="M272 180 H396"/>
|
||||
<text class="t lbl" x="334" y="170" text-anchor="middle">logowanie do panelu</text>
|
||||
|
||||
<path class="flow" d="M400 460 H276"/>
|
||||
<text class="t lbl" x="338" y="450" text-anchor="middle">HTML na żądanie</text>
|
||||
|
||||
<path class="flow" d="M720 212 H786"/>
|
||||
<text class="t lbl" x="753" y="202" text-anchor="middle">SQL</text>
|
||||
|
||||
<path class="flow" d="M720 440 H786"/>
|
||||
<text class="t lbl" x="753" y="430" text-anchor="middle">upload</text>
|
||||
|
||||
<!-- summary pills -->
|
||||
<rect class="pill" x="380" y="552" width="360" height="36" rx="18"/>
|
||||
<text class="t pilltxt" x="560" y="575" text-anchor="middle">2 procesy działają bez przerwy, także nocą</text>
|
||||
<rect class="pill" x="770" y="552" width="360" height="36" rx="18"/>
|
||||
<text class="t pilltxt" x="950" y="575" text-anchor="middle">aktualizacje bezpieczeństwa = stały obowiązek</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 6.1 KiB |
@@ -1,111 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 640" role="img" aria-label="Architektura demo na maszynie: redaktor i czytelnik łączą się z kontenerami podmana — Gitea, build Astro, wolumen releases i nginx">
|
||||
<defs>
|
||||
<marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M0 0 L10 5 L0 10 z" fill="#00004a"/>
|
||||
</marker>
|
||||
<filter id="soft" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="0" dy="2" stdDeviation="5" flood-color="#00004a" flood-opacity="0.10"/>
|
||||
</filter>
|
||||
<style>
|
||||
.t { font-family: Inter, "Segoe UI", Arial, sans-serif; }
|
||||
.box { fill: #ffffff; stroke: #00004a; stroke-width: 1.5; }
|
||||
.sub { fill: #f5f5f5; stroke: #e2e5ee; stroke-width: 1; }
|
||||
.ttl { font-weight: 700; font-size: 15.5px; fill: #00004a; letter-spacing: .04em; }
|
||||
.cap { font-size: 12.5px; fill: #46536a; }
|
||||
.lbl { font-size: 12px; fill: #46536a; paint-order: stroke; stroke: #ffffff; stroke-width: 4; }
|
||||
.chipbg { fill: #d2faf7; }
|
||||
.chip { font-size: 11.5px; font-weight: 700; fill: #00004a; letter-spacing: .06em; }
|
||||
.flow { stroke: #00004a; stroke-width: 1.8; fill: none; marker-end: url(#arr); }
|
||||
.mono { font-family: "SF Mono", Consolas, Menlo, monospace; font-size: 12.5px; fill: #101228; }
|
||||
</style>
|
||||
</defs>
|
||||
|
||||
<!-- machine boundary -->
|
||||
<rect x="340" y="40" width="830" height="570" rx="18" fill="#f8f9fc" stroke="#e2e5ee" stroke-width="1.5"/>
|
||||
<text class="t" x="366" y="76" font-size="13" font-weight="700" fill="#00004a" letter-spacing=".18em">MASZYNA DEMO · PODMAN</text>
|
||||
<text class="t cap" x="366" y="96">osobne kontenery pod systemd · wszystko w jednym katalogu użytkownika</text>
|
||||
|
||||
<!-- actor: redaktor -->
|
||||
<g filter="url(#soft)">
|
||||
<rect class="box" x="52" y="120" width="220" height="120" rx="16"/>
|
||||
</g>
|
||||
<circle cx="88" cy="156" r="11" fill="none" stroke="#00004a" stroke-width="1.8"/>
|
||||
<path d="M72 186 q16 -18 32 0" fill="none" stroke="#00004a" stroke-width="1.8"/>
|
||||
<text class="t ttl" x="116" y="162">Redaktor</text>
|
||||
<text class="t cap" x="70" y="212">przeglądarka · <tspan font-weight="600">/admin/</tspan> (Sveltia)</text>
|
||||
<text class="t cap" x="70" y="228">edycja WYSIWYG, podgląd 1:1</text>
|
||||
|
||||
<!-- actor: czytelnik -->
|
||||
<g filter="url(#soft)">
|
||||
<rect class="box" x="52" y="400" width="220" height="120" rx="16"/>
|
||||
</g>
|
||||
<circle cx="88" cy="436" r="11" fill="none" stroke="#00004a" stroke-width="1.8"/>
|
||||
<path d="M72 466 q16 -18 32 0" fill="none" stroke="#00004a" stroke-width="1.8"/>
|
||||
<text class="t ttl" x="116" y="442">Czytelnik</text>
|
||||
<text class="t cap" x="70" y="492">publiczna strona portalu</text>
|
||||
<text class="t cap" x="70" y="508">czysty, szybki HTML</text>
|
||||
|
||||
<!-- gitea -->
|
||||
<g filter="url(#soft)">
|
||||
<rect class="box" x="400" y="120" width="320" height="185" rx="16"/>
|
||||
</g>
|
||||
<text class="t ttl" x="424" y="152">GITEA</text>
|
||||
<rect class="chipbg" x="490" y="136" width="52" height="22" rx="11"/>
|
||||
<text class="t chip" x="516" y="151" text-anchor="middle">:3000</text>
|
||||
<rect class="sub" x="420" y="172" width="280" height="112" rx="12"/>
|
||||
<text class="t" x="436" y="198" font-size="13.5" font-weight="700" fill="#101228">repo ctao/portal</text>
|
||||
<text class="t cap" x="436" y="220">treść: Markdown + obrazy (WebP)</text>
|
||||
<text class="t cap" x="436" y="238">każda zmiana = commit</text>
|
||||
<text class="t cap" x="436" y="256">pełna historia + rollback za darmo</text>
|
||||
|
||||
<!-- build (ephemeral) -->
|
||||
<g filter="url(#soft)">
|
||||
<rect x="790" y="120" width="340" height="185" rx="16" fill="#ffffff" stroke="#00004a" stroke-width="1.5" stroke-dasharray="7 5"/>
|
||||
</g>
|
||||
<text class="t ttl" x="814" y="152">BUILD · ASTRO</text>
|
||||
<rect class="chipbg" x="948" y="136" width="164" height="22" rx="11"/>
|
||||
<text class="t chip" x="1030" y="151" text-anchor="middle">KONTENER JEDNORAZOWY</text>
|
||||
<text class="t cap" x="814" y="188">timer systemd (co ~10 s) sprawdza,</text>
|
||||
<text class="t cap" x="814" y="206">czy w repo jest nowy commit</text>
|
||||
<text class="t cap" x="814" y="234">jeśli tak: git fetch → checkout →</text>
|
||||
<text class="t cap" x="814" y="252"><tspan font-weight="700" fill="#101228">Markdown → statyczny HTML</tspan></text>
|
||||
<text class="t cap" x="814" y="280">po buildzie kontener znika</text>
|
||||
|
||||
<!-- releases volume -->
|
||||
<g filter="url(#soft)">
|
||||
<rect class="sub" x="790" y="400" width="340" height="150" rx="16"/>
|
||||
</g>
|
||||
<text class="t ttl" x="814" y="432">releases/</text>
|
||||
<rect class="chipbg" x="908" y="416" width="82" height="22" rx="11"/>
|
||||
<text class="t chip" x="949" y="431" text-anchor="middle">WOLUMEN</text>
|
||||
<text class="t mono" x="814" y="466">9f2c1d/ poprzednia wersja</text>
|
||||
<text class="t mono" x="814" y="488">71b980/ <tspan font-weight="700" fill="#00004a">← current (symlink)</tspan></text>
|
||||
<text class="t cap" x="814" y="518">podmiana atomowa — zero przestoju</text>
|
||||
|
||||
<!-- nginx -->
|
||||
<g filter="url(#soft)">
|
||||
<rect class="box" x="400" y="400" width="320" height="150" rx="16"/>
|
||||
</g>
|
||||
<text class="t ttl" x="424" y="432">NGINX</text>
|
||||
<rect class="chipbg" x="500" y="416" width="52" height="22" rx="11"/>
|
||||
<text class="t chip" x="526" y="431" text-anchor="middle">:8080</text>
|
||||
<text class="t cap" x="424" y="466">serwuje <tspan font-weight="600">releases/current</tspan></text>
|
||||
<text class="t cap" x="424" y="484">wyłącznie statyczne pliki</text>
|
||||
<text class="t cap" x="424" y="502">brak aplikacji · brak bazy · brak PHP</text>
|
||||
|
||||
<!-- flows -->
|
||||
<path class="flow" d="M272 180 H396"/>
|
||||
<text class="t lbl" x="334" y="170" text-anchor="middle">zapis przez API (OAuth)</text>
|
||||
|
||||
<path class="flow" d="M790 212 H724"/>
|
||||
<text class="t lbl" x="757" y="202" text-anchor="middle">git fetch</text>
|
||||
|
||||
<path class="flow" d="M960 305 V396"/>
|
||||
<text class="t lbl" x="968" y="354" text-anchor="start">nowa wersja strony</text>
|
||||
|
||||
<path class="flow" d="M790 475 H724"/>
|
||||
<text class="t lbl" x="757" y="465" text-anchor="middle">current/</text>
|
||||
|
||||
<path class="flow" d="M400 475 H276"/>
|
||||
<text class="t lbl" x="338" y="465" text-anchor="middle">statyczny HTML</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 6.1 KiB |
@@ -0,0 +1,48 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 540" role="img" aria-label="Attack surface compared: a database-backed CMS exposes an application, a login panel, a database and plugins, while this solution exposes static HTML files only and keeps editing behind a git sign-in">
|
||||
<defs>
|
||||
<filter id="soft3" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="0" dy="2" stdDeviation="5" flood-color="#00004a" flood-opacity="0.10"/>
|
||||
</filter>
|
||||
<marker id="arr3" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M0 0 L10 5 L0 10 z" fill="#00004a"/>
|
||||
</marker>
|
||||
<style>
|
||||
.t { font-family: Inter, "Segoe UI", Arial, sans-serif; }
|
||||
.hd { font-weight: 800; font-size: 16px; fill: #00004a; letter-spacing: .14em; }
|
||||
.cap { font-size: 14.5px; fill: #46536a; }
|
||||
.item { font-size: 15.5px; fill: #101228; }
|
||||
.side { font-size: 15px; fill: #101228; }
|
||||
.bad { fill: #fdf0f0; stroke: #e8c5c5; stroke-width: 1.5; }
|
||||
.good { fill: #ffffff; stroke: #00004a; stroke-width: 1.5; }
|
||||
.flow { stroke: #00004a; stroke-width: 1.8; fill: none; marker-end: url(#arr3); }
|
||||
</style>
|
||||
</defs>
|
||||
|
||||
<!-- top: classic CMS -->
|
||||
<text class="t hd" x="40" y="48">DATABASE-BACKED CMS</text>
|
||||
<text class="t side" x="40" y="173">internet</text>
|
||||
<path class="flow" d="M120 168 H176"/>
|
||||
<g filter="url(#soft3)"><rect class="bad" x="180" y="68" width="580" height="200" rx="16"/></g>
|
||||
<text class="t item" x="208" y="106">▪ CMS application (PHP / Node), public</text>
|
||||
<text class="t item" x="208" y="140">▪ login panel, public</text>
|
||||
<text class="t item" x="208" y="174">▪ database holding the content</text>
|
||||
<text class="t item" x="208" y="208">▪ plugins and dependencies</text>
|
||||
<text class="t" x="208" y="242" font-size="14.5" font-weight="700" fill="#8f3b3b">all of it runs non stop and needs patching</text>
|
||||
|
||||
<!-- divider -->
|
||||
<line x1="40" y1="300" x2="760" y2="300" stroke="#e2e5ee" stroke-width="1.5"/>
|
||||
|
||||
<!-- bottom: this solution -->
|
||||
<text class="t hd" x="40" y="334">THIS SOLUTION</text>
|
||||
<text class="t side" x="40" y="389">internet</text>
|
||||
<path class="flow" d="M120 384 H176"/>
|
||||
<g filter="url(#soft3)"><rect class="good" x="180" y="346" width="580" height="76" rx="16"/></g>
|
||||
<text class="t item" x="208" y="378">▪ HTML files served by nginx</text>
|
||||
<text class="t cap" x="208" y="404">no application, no database, no login panel</text>
|
||||
|
||||
<text class="t side" x="40" y="483">editing</text>
|
||||
<path class="flow" d="M120 478 H176"/>
|
||||
<g filter="url(#soft3)"><rect class="good" x="180" y="440" width="580" height="76" rx="16"/></g>
|
||||
<text class="t item" x="208" y="472">▪ git (Gitea), signed-in users only</text>
|
||||
<text class="t cap" x="208" y="498">off the reader's path, so an outage is invisible</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
@@ -1,4 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1600 900" role="img" aria-label="Grafika: graf commitów w gicie przechodzący w statyczną stronę WWW">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1600 900" role="img" aria-label="Illustration: a graph of git commits flowing into a static web page">
|
||||
<defs>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0" stop-color="#00004a"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
@@ -1,76 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 430" role="img" aria-label="Pięć kroków od zapisu w edytorze do publikacji: zapis, commit, detekcja, build, publikacja">
|
||||
<defs>
|
||||
<marker id="arr2" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M0 0 L10 5 L0 10 z" fill="#00004a"/>
|
||||
</marker>
|
||||
<filter id="soft2" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="0" dy="2" stdDeviation="5" flood-color="#00004a" flood-opacity="0.10"/>
|
||||
</filter>
|
||||
<style>
|
||||
.t { font-family: Inter, "Segoe UI", Arial, sans-serif; }
|
||||
.card { fill: #ffffff; stroke: #00004a; stroke-width: 1.5; }
|
||||
.ttl { font-weight: 700; font-size: 15px; fill: #00004a; }
|
||||
.cap { font-size: 12.3px; fill: #46536a; }
|
||||
.num { font-weight: 800; font-size: 15px; fill: #00004a; }
|
||||
.pill { fill: #f5f5f5; stroke: #e2e5ee; }
|
||||
.pilltxt { font-size: 12.5px; fill: #101228; }
|
||||
.flow { stroke: #00004a; stroke-width: 1.8; fill: none; marker-end: url(#arr2); }
|
||||
</style>
|
||||
</defs>
|
||||
|
||||
<!-- cards -->
|
||||
<g filter="url(#soft2)"><rect class="card" x="55" y="100" width="200" height="175" rx="16"/></g>
|
||||
<g filter="url(#soft2)"><rect class="card" x="285" y="100" width="200" height="175" rx="16"/></g>
|
||||
<g filter="url(#soft2)"><rect class="card" x="515" y="100" width="200" height="175" rx="16"/></g>
|
||||
<g filter="url(#soft2)"><rect class="card" x="745" y="100" width="200" height="175" rx="16"/></g>
|
||||
<g filter="url(#soft2)"><rect class="card" x="975" y="100" width="200" height="175" rx="16"/></g>
|
||||
|
||||
<!-- connectors -->
|
||||
<path class="flow" d="M255 187 H281"/>
|
||||
<path class="flow" d="M485 187 H511"/>
|
||||
<path class="flow" d="M715 187 H741"/>
|
||||
<path class="flow" d="M945 187 H971"/>
|
||||
|
||||
<!-- step numbers -->
|
||||
<circle cx="155" cy="100" r="17" fill="#00e4d8"/><text class="t num" x="155" y="106" text-anchor="middle">1</text>
|
||||
<circle cx="385" cy="100" r="17" fill="#00e4d8"/><text class="t num" x="385" y="106" text-anchor="middle">2</text>
|
||||
<circle cx="615" cy="100" r="17" fill="#00e4d8"/><text class="t num" x="615" y="106" text-anchor="middle">3</text>
|
||||
<circle cx="845" cy="100" r="17" fill="#00e4d8"/><text class="t num" x="845" y="106" text-anchor="middle">4</text>
|
||||
<circle cx="1075" cy="100" r="17" fill="#00e4d8"/><text class="t num" x="1075" y="106" text-anchor="middle">5</text>
|
||||
|
||||
<!-- card 1 -->
|
||||
<text class="t ttl" x="155" y="152" text-anchor="middle">Zapis w edytorze</text>
|
||||
<text class="t cap" x="155" y="182" text-anchor="middle">Sveltia · WYSIWYG</text>
|
||||
<text class="t cap" x="155" y="200" text-anchor="middle">podgląd artykułu 1:1</text>
|
||||
<text class="t cap" x="155" y="218" text-anchor="middle">obrazy → WebP przy uploadzie</text>
|
||||
|
||||
<!-- card 2 -->
|
||||
<text class="t ttl" x="385" y="152" text-anchor="middle">Commit w repo</text>
|
||||
<text class="t cap" x="385" y="182" text-anchor="middle">Gitea · logowanie OAuth</text>
|
||||
<text class="t cap" x="385" y="200" text-anchor="middle">zapis przez API = commit</text>
|
||||
<text class="t cap" x="385" y="218" text-anchor="middle">historia każdej zmiany</text>
|
||||
|
||||
<!-- card 3 -->
|
||||
<text class="t ttl" x="615" y="152" text-anchor="middle">Detekcja zmiany</text>
|
||||
<text class="t cap" x="615" y="182" text-anchor="middle">timer systemd</text>
|
||||
<text class="t cap" x="615" y="200" text-anchor="middle">sprawdza repo co ~10 s</text>
|
||||
<text class="t cap" x="615" y="218" text-anchor="middle">brak zmian = brak pracy</text>
|
||||
|
||||
<!-- card 4 -->
|
||||
<text class="t ttl" x="845" y="152" text-anchor="middle">Build strony</text>
|
||||
<text class="t cap" x="845" y="182" text-anchor="middle">jednorazowy kontener</text>
|
||||
<text class="t cap" x="845" y="200" text-anchor="middle">Astro: Markdown →</text>
|
||||
<text class="t cap" x="845" y="218" text-anchor="middle">statyczny HTML</text>
|
||||
|
||||
<!-- card 5 -->
|
||||
<text class="t ttl" x="1075" y="152" text-anchor="middle">Publikacja</text>
|
||||
<text class="t cap" x="1075" y="182" text-anchor="middle">atomowa podmiana symlinka</text>
|
||||
<text class="t cap" x="1075" y="200" text-anchor="middle">nginx od razu serwuje</text>
|
||||
<text class="t cap" x="1075" y="218" text-anchor="middle">nową wersję</text>
|
||||
|
||||
<!-- reassurance pills -->
|
||||
<rect class="pill" x="240" y="330" width="330" height="40" rx="20"/>
|
||||
<text class="t pilltxt" x="405" y="355" text-anchor="middle">awaria builda? strona działa dalej na starej wersji</text>
|
||||
<rect class="pill" x="630" y="330" width="330" height="40" rx="20"/>
|
||||
<text class="t pilltxt" x="795" y="355" text-anchor="middle">rollback = git revert — jedna komenda</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.5 KiB |
@@ -1,48 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 360" role="img" aria-label="Porównanie powierzchni ataku: CMS z bazą wystawia publicznie aplikację, bazę i pluginy; rozwiązanie statyczne wystawia tylko pliki HTML, a edycja idzie przez git">
|
||||
<defs>
|
||||
<filter id="soft3" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="0" dy="2" stdDeviation="5" flood-color="#00004a" flood-opacity="0.10"/>
|
||||
</filter>
|
||||
<marker id="arr3" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M0 0 L10 5 L0 10 z" fill="#00004a"/>
|
||||
</marker>
|
||||
<style>
|
||||
.t { font-family: Inter, "Segoe UI", Arial, sans-serif; }
|
||||
.hd { font-weight: 800; font-size: 14px; fill: #00004a; letter-spacing: .14em; }
|
||||
.cap { font-size: 12.5px; fill: #46536a; }
|
||||
.item{ font-size: 13px; fill: #101228; }
|
||||
.bad { fill: #fdf0f0; stroke: #e8c5c5; stroke-width: 1.5; }
|
||||
.good{ fill: #ffffff; stroke: #00004a; stroke-width: 1.5; }
|
||||
.flow{ stroke: #00004a; stroke-width: 1.8; fill: none; marker-end: url(#arr3); }
|
||||
.lbl { font-size: 12px; fill: #46536a; paint-order: stroke; stroke: #ffffff; stroke-width: 4; }
|
||||
</style>
|
||||
</defs>
|
||||
|
||||
<!-- left: classic CMS -->
|
||||
<text class="t hd" x="300" y="52" text-anchor="middle">CMS Z BAZĄ DANYCH</text>
|
||||
<text class="t item" x="60" y="150">internet</text>
|
||||
<path class="flow" d="M130 145 H186"/>
|
||||
<g filter="url(#soft3)"><rect class="bad" x="190" y="80" width="360" height="200" rx="16"/></g>
|
||||
<text class="t item" x="218" y="126">▪ aplikacja CMS (PHP / Node) — publiczna</text>
|
||||
<text class="t item" x="218" y="158">▪ panel logowania — publiczny</text>
|
||||
<text class="t item" x="218" y="190">▪ baza danych z treścią</text>
|
||||
<text class="t item" x="218" y="222">▪ pluginy i zależności</text>
|
||||
<text class="t cap" x="218" y="256" font-weight="700" fill="#8f3b3b">wszystko działa non stop i wymaga patchowania</text>
|
||||
|
||||
<!-- divider -->
|
||||
<line x1="600" y1="60" x2="600" y2="320" stroke="#e2e5ee" stroke-width="1.5"/>
|
||||
|
||||
<!-- right: static -->
|
||||
<text class="t hd" x="900" y="52" text-anchor="middle">TO ROZWIĄZANIE</text>
|
||||
<text class="t item" x="646" y="130">internet</text>
|
||||
<path class="flow" d="M716 125 H772"/>
|
||||
<g filter="url(#soft3)"><rect class="good" x="776" y="88" width="360" height="76" rx="16"/></g>
|
||||
<text class="t item" x="804" y="120">▪ pliki HTML — i nic więcej</text>
|
||||
<text class="t cap" x="804" y="146">nie ma czego zhakować ani patchować</text>
|
||||
|
||||
<text class="t item" x="646" y="252">edycja</text>
|
||||
<path class="flow" d="M716 247 H772"/>
|
||||
<g filter="url(#soft3)"><rect class="good" x="776" y="210" width="360" height="76" rx="16"/></g>
|
||||
<text class="t item" x="804" y="242">▪ git (Gitea) — tylko zalogowani</text>
|
||||
<text class="t cap" x="804" y="268">poza ścieżką czytelnika — awaria nie kładzie strony</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1,54 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 620 600" role="img" aria-label="Five steps from a save in the editor to a published page: save, commit, change detected, site build, published">
|
||||
<defs>
|
||||
<filter id="soft2" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="0" dy="2" stdDeviation="5" flood-color="#00004a" flood-opacity="0.10"/>
|
||||
</filter>
|
||||
<style>
|
||||
.t { font-family: Inter, "Segoe UI", Arial, sans-serif; }
|
||||
.ttl { font-weight: 700; font-size: 18px; fill: #00004a; }
|
||||
.cap { font-size: 15px; fill: #46536a; }
|
||||
.num { font-weight: 800; font-size: 16px; fill: #00004a; }
|
||||
.pill { fill: #f5f5f5; stroke: #e2e5ee; }
|
||||
.pilltxt { font-size: 14px; fill: #101228; }
|
||||
</style>
|
||||
</defs>
|
||||
|
||||
<!-- rail -->
|
||||
<line x1="60" y1="70" x2="60" y2="470" stroke="#c7cde9" stroke-width="2"/>
|
||||
|
||||
<!-- step 1 -->
|
||||
<circle cx="60" cy="70" r="20" fill="#00e4d8"/>
|
||||
<text class="t num" x="60" y="76" text-anchor="middle">1</text>
|
||||
<text class="t ttl" x="100" y="66">Save in the editor</text>
|
||||
<text class="t cap" x="100" y="92">Sveltia, visual editing with a preview that matches the page</text>
|
||||
|
||||
<!-- step 2 -->
|
||||
<circle cx="60" cy="170" r="20" fill="#00e4d8"/>
|
||||
<text class="t num" x="60" y="176" text-anchor="middle">2</text>
|
||||
<text class="t ttl" x="100" y="166">Commit in the repository</text>
|
||||
<text class="t cap" x="100" y="192">Gitea signs the editor in; each save becomes one commit</text>
|
||||
|
||||
<!-- step 3 -->
|
||||
<circle cx="60" cy="270" r="20" fill="#00e4d8"/>
|
||||
<text class="t num" x="60" y="276" text-anchor="middle">3</text>
|
||||
<text class="t ttl" x="100" y="266">Change detected</text>
|
||||
<text class="t cap" x="100" y="292">a systemd timer checks both repositories every 10 seconds</text>
|
||||
|
||||
<!-- step 4 -->
|
||||
<circle cx="60" cy="370" r="20" fill="#00e4d8"/>
|
||||
<text class="t num" x="60" y="376" text-anchor="middle">4</text>
|
||||
<text class="t ttl" x="100" y="366">Site build</text>
|
||||
<text class="t cap" x="100" y="392">a one-shot container runs Astro: Markdown becomes static HTML</text>
|
||||
|
||||
<!-- step 5 -->
|
||||
<circle cx="60" cy="470" r="20" fill="#00e4d8"/>
|
||||
<text class="t num" x="60" y="476" text-anchor="middle">5</text>
|
||||
<text class="t ttl" x="100" y="466">Published</text>
|
||||
<text class="t cap" x="100" y="492">an atomic symlink swap; nginx serves the new version at once</text>
|
||||
|
||||
<!-- reassurance -->
|
||||
<rect class="pill" x="40" y="524" width="310" height="46" rx="23"/>
|
||||
<text class="t pilltxt" x="195" y="552" text-anchor="middle">a failed build leaves the old version up</text>
|
||||
<rect class="pill" x="370" y="524" width="220" height="46" rx="23"/>
|
||||
<text class="t pilltxt" x="480" y="552" text-anchor="middle">rollback is one git revert</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
@@ -0,0 +1,70 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 700" role="img" aria-label="The three parts of the stack: Sveltia CMS as the editor, git and Gitea as the database, Astro as the build-time generator; when a reader opens a page only nginx and the generated files are involved">
|
||||
<defs>
|
||||
<marker id="arr0" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M0 0 L10 5 L0 10 z" fill="#00004a"/>
|
||||
</marker>
|
||||
<filter id="soft0" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="0" dy="2" stdDeviation="5" flood-color="#00004a" flood-opacity="0.10"/>
|
||||
</filter>
|
||||
<style>
|
||||
.t { font-family: Inter, "Segoe UI", Arial, sans-serif; }
|
||||
.card { fill: #ffffff; stroke: #00004a; stroke-width: 1.5; }
|
||||
.ttl { font-weight: 700; font-size: 19px; fill: #00004a; letter-spacing: .04em; }
|
||||
.cap { font-size: 15.5px; fill: #46536a; }
|
||||
.chipbg { fill: #d2faf7; }
|
||||
.chip { font-size: 12.5px; font-weight: 700; fill: #00004a; letter-spacing: .06em; }
|
||||
.gain { font-size: 15.5px; font-weight: 700; fill: #101228; }
|
||||
.flow { stroke: #00004a; stroke-width: 1.8; fill: none; marker-end: url(#arr0); }
|
||||
.lbl { font-size: 14px; fill: #46536a; }
|
||||
.band { fill: #f5f5f5; stroke: #e2e5ee; }
|
||||
.bandtxt { font-size: 14px; fill: #101228; }
|
||||
</style>
|
||||
</defs>
|
||||
|
||||
<!-- row 1: the editor -->
|
||||
<g filter="url(#soft0)"><rect class="card" x="20" y="20" width="760" height="160" rx="16"/></g>
|
||||
<text class="t ttl" x="48" y="68">SVELTIA CMS</text>
|
||||
<rect class="chipbg" x="48" y="84" width="78" height="26" rx="13"/>
|
||||
<text class="t chip" x="87" y="102" text-anchor="middle">EDITOR</text>
|
||||
<text class="t gain" x="48" y="142">every save is</text>
|
||||
<text class="t gain" x="48" y="164">a commit</text>
|
||||
<line x1="284" y1="46" x2="284" y2="154" stroke="#e2e5ee" stroke-width="1"/>
|
||||
<circle cx="312" cy="64" r="3" fill="#00e4d8"/><text class="t cap" x="330" y="69">visual editing in the browser at /admin/</text>
|
||||
<circle cx="312" cy="98" r="3" fill="#00e4d8"/><text class="t cap" x="330" y="103">one JavaScript file, no server to run</text>
|
||||
<circle cx="312" cy="132" r="3" fill="#00e4d8"/><text class="t cap" x="330" y="137">signs in to Gitea over OAuth</text>
|
||||
|
||||
<path class="flow" d="M400 180 V220"/>
|
||||
<text class="t lbl" x="414" y="205">commit</text>
|
||||
|
||||
<!-- row 2: the storage -->
|
||||
<g filter="url(#soft0)"><rect class="card" x="20" y="224" width="760" height="160" rx="16"/></g>
|
||||
<text class="t ttl" x="48" y="272">GIT · GITEA</text>
|
||||
<rect class="chipbg" x="48" y="288" width="86" height="26" rx="13"/>
|
||||
<text class="t chip" x="91" y="306" text-anchor="middle">STORAGE</text>
|
||||
<text class="t gain" x="48" y="346">the repository</text>
|
||||
<text class="t gain" x="48" y="368">is the database</text>
|
||||
<line x1="284" y1="250" x2="284" y2="358" stroke="#e2e5ee" stroke-width="1"/>
|
||||
<circle cx="312" cy="268" r="3" fill="#00e4d8"/><text class="t cap" x="330" y="273">articles as Markdown files</text>
|
||||
<circle cx="312" cy="302" r="3" fill="#00e4d8"/><text class="t cap" x="330" y="307">images stored next to them</text>
|
||||
<circle cx="312" cy="336" r="3" fill="#00e4d8"/><text class="t cap" x="330" y="341">history, diff and revert built in</text>
|
||||
|
||||
<path class="flow" d="M400 384 V424"/>
|
||||
<text class="t lbl" x="414" y="409">build</text>
|
||||
|
||||
<!-- row 3: the generator -->
|
||||
<g filter="url(#soft0)"><rect class="card" x="20" y="428" width="760" height="160" rx="16"/></g>
|
||||
<text class="t ttl" x="48" y="476">ASTRO</text>
|
||||
<rect class="chipbg" x="48" y="492" width="110" height="26" rx="13"/>
|
||||
<text class="t chip" x="103" y="510" text-anchor="middle">BUILD ONLY</text>
|
||||
<text class="t gain" x="48" y="550">nothing of it runs</text>
|
||||
<text class="t gain" x="48" y="572">in production</text>
|
||||
<line x1="284" y1="454" x2="284" y2="562" stroke="#e2e5ee" stroke-width="1"/>
|
||||
<circle cx="312" cy="472" r="3" fill="#00e4d8"/><text class="t cap" x="330" y="477">Markdown becomes static HTML</text>
|
||||
<circle cx="312" cy="506" r="3" fill="#00e4d8"/><text class="t cap" x="330" y="511">article fields checked at build time</text>
|
||||
<circle cx="312" cy="540" r="3" fill="#00e4d8"/><text class="t cap" x="330" y="545">React islands where they are needed</text>
|
||||
|
||||
<!-- what the reader actually touches -->
|
||||
<rect class="band" x="20" y="616" width="760" height="64" rx="32"/>
|
||||
<text class="t bandtxt" x="400" y="645" text-anchor="middle">When a reader opens a page, only nginx and the generated files are involved.</text>
|
||||
<text class="t bandtxt" x="400" y="667" text-anchor="middle">No application, no database, no admin login.</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.6 KiB |