Separate redundancy notes from infrastructure flows

This commit is contained in:
interlope committed 2026-11-01 19:55:34 +01:00
1 parent 1cb9c004d8
commit dd0a2e3f68
6 files changed
+41 -11

No files matched your search

+1 -1
View File
@@ -85,7 +85,7 @@ earlier state of the lab.
<p>This diagram separates visitor traffic from deployment, control and monitoring. Application groups are illustrative; no real service catalogue, hostnames or private addresses are included. Solid arrows show the main flow within each section, while dashed arrows identify secondary paths, checks or control operations.</p> <p>This diagram separates visitor traffic from deployment, control and monitoring. Application groups are illustrative; no real service catalogue, hostnames or private addresses are included. Solid arrows show the main flow within each section, while dashed arrows identify secondary paths, checks or control operations.</p>
<figure> <figure>
<a href="../img/infrastructure-overview.png"><img src="../img/infrastructure-overview.png" alt="Detailed anonymized architecture: Cloudflare proxy and DNS-only access, two HAProxy and Anubis edges, private service failover, Tailscale origins, Semaphore deployment, Headscale policy, certificates and Prometheus monitoring" loading="lazy" /></a> <a href="../img/infrastructure-overview.png"><img src="../img/infrastructure-overview.png" alt="Detailed anonymized architecture: Cloudflare proxy and DNS-only access, two HAProxy and Anubis edges, private service failover, Tailscale origins, Semaphore deployment, Headscale policy, certificates and Prometheus monitoring" loading="lazy" /></a>
<figcaption>Open the image at full size to follow the paths. Cloudflare checks the public entrance; each HAProxy checks its application paths. The shared origins remain a common dependency.</figcaption> <figcaption>Open the image at full size to follow the paths. The separate red panel explains failure handling and redundancy limits; it is not an infrastructure component or a traffic path. Cloudflare checks the public entrance; each HAProxy checks its application paths.</figcaption>
</figure> </figure>
<p>The <a href="../files/infrastructure-mermaid.txt">Mermaid source</a> describes this generic architecture. It is maintained documentation, not a production configuration export.</p> <p>The <a href="../files/infrastructure-mermaid.txt">Mermaid source</a> describes this generic architecture. It is maintained documentation, not a production configuration export.</p>
+13 -3
View File
@@ -96,8 +96,17 @@ flowchart TB
PROM -. "HTTPS /_edge/metrics" .-> HA PROM -. "HTTPS /_edge/metrics" .-> HA
PROM -. "HTTPS /_edge/metrics" .-> HB PROM -. "HTTPS /_edge/metrics" .-> HB
LIMITS["Failure boundaries<br/>Cloudflare bypasses an unavailable public edge<br/>HAProxy bypasses a failed per-service path when its peer is healthy<br/>a failed shared origin is still unavailable<br/>open video streams and WebSockets must reconnect"] subgraph BOUNDARIES["Failure handling and limits - explanatory notes"]
ORIGINS -.-> LIMITS direction LR
LIMIT_EDGE["Public edge unavailable<br/>Cloudflare selects a healthy edge for new connections"]
LIMIT_PATH["One service path unavailable<br/>HAProxy uses the peer when its path is healthy"]
LIMIT_ORIGIN["Shared origin unavailable<br/>Both edges lose that application<br/>edge redundancy does not replicate origins"]
LIMIT_STREAM["Open video streams and WebSockets<br/>Existing connections do not migrate<br/>clients must reconnect"]
LIMIT_EDGE ~~~ LIMIT_PATH ~~~ LIMIT_ORIGIN ~~~ LIMIT_STREAM
end
%% Invisible positioning only: this is not a data-flow connection.
ORIGINS ~~~ BOUNDARIES
classDef public fill:#233d58,stroke:#7ab5dc,color:#f2f6ff classDef public fill:#233d58,stroke:#7ab5dc,color:#f2f6ff
classDef edge fill:#284c44,stroke:#7bc8a7,color:#f2f6ff classDef edge fill:#284c44,stroke:#7bc8a7,color:#f2f6ff
@@ -110,5 +119,6 @@ flowchart TB
class VPS,ROUTER,FW,NPM,APPS origin class VPS,ROUTER,FW,NPM,APPS origin
class GIT,PLAN,DEPLOY,SECRETS,HS,CERT,CFAPI ops class GIT,PLAN,DEPLOY,SECRETS,HS,CERT,CFAPI ops
class PROM,GRAF,ALERT monitor class PROM,GRAF,ALERT monitor
class LIMITS note class LIMIT_EDGE,LIMIT_PATH,LIMIT_ORIGIN,LIMIT_STREAM note
style BOUNDARIES fill:#291f2a,stroke:#dd9ba7,color:#fff5f6
``` ```
@@ -91,8 +91,17 @@ flowchart TB
PROM -. "HTTPS /_edge/metrics" .-> HA PROM -. "HTTPS /_edge/metrics" .-> HA
PROM -. "HTTPS /_edge/metrics" .-> HB PROM -. "HTTPS /_edge/metrics" .-> HB
LIMITS["Failure boundaries<br/>Cloudflare bypasses an unavailable public edge<br/>HAProxy bypasses a failed per-service path when its peer is healthy<br/>a failed shared origin is still unavailable<br/>open video streams and WebSockets must reconnect"] subgraph BOUNDARIES["Failure handling and limits - explanatory notes"]
ORIGINS -.-> LIMITS direction LR
LIMIT_EDGE["Public edge unavailable<br/>Cloudflare selects a healthy edge for new connections"]
LIMIT_PATH["One service path unavailable<br/>HAProxy uses the peer when its path is healthy"]
LIMIT_ORIGIN["Shared origin unavailable<br/>Both edges lose that application<br/>edge redundancy does not replicate origins"]
LIMIT_STREAM["Open video streams and WebSockets<br/>Existing connections do not migrate<br/>clients must reconnect"]
LIMIT_EDGE ~~~ LIMIT_PATH ~~~ LIMIT_ORIGIN ~~~ LIMIT_STREAM
end
%% Invisible positioning only: this is not a data-flow connection.
ORIGINS ~~~ BOUNDARIES
classDef public fill:#233d58,stroke:#7ab5dc,color:#f2f6ff classDef public fill:#233d58,stroke:#7ab5dc,color:#f2f6ff
classDef edge fill:#284c44,stroke:#7bc8a7,color:#f2f6ff classDef edge fill:#284c44,stroke:#7bc8a7,color:#f2f6ff
@@ -105,4 +114,5 @@ flowchart TB
class VPS,ROUTER,FW,NPM,APPS origin class VPS,ROUTER,FW,NPM,APPS origin
class GIT,PLAN,DEPLOY,SECRETS,HS,CERT,CFAPI ops class GIT,PLAN,DEPLOY,SECRETS,HS,CERT,CFAPI ops
class PROM,GRAF,ALERT monitor class PROM,GRAF,ALERT monitor
class LIMITS note class LIMIT_EDGE,LIMIT_PATH,LIMIT_ORIGIN,LIMIT_STREAM note
style BOUNDARIES fill:#291f2a,stroke:#dd9ba7,color:#fff5f6
@@ -91,8 +91,17 @@ flowchart TB
PROM -. "HTTPS /_edge/metrics" .-> HA PROM -. "HTTPS /_edge/metrics" .-> HA
PROM -. "HTTPS /_edge/metrics" .-> HB PROM -. "HTTPS /_edge/metrics" .-> HB
LIMITS["Failure boundaries<br/>Cloudflare bypasses an unavailable public edge<br/>HAProxy bypasses a failed per-service path when its peer is healthy<br/>a failed shared origin is still unavailable<br/>open video streams and WebSockets must reconnect"] subgraph BOUNDARIES["Failure handling and limits - explanatory notes"]
ORIGINS -.-> LIMITS direction LR
LIMIT_EDGE["Public edge unavailable<br/>Cloudflare selects a healthy edge for new connections"]
LIMIT_PATH["One service path unavailable<br/>HAProxy uses the peer when its path is healthy"]
LIMIT_ORIGIN["Shared origin unavailable<br/>Both edges lose that application<br/>edge redundancy does not replicate origins"]
LIMIT_STREAM["Open video streams and WebSockets<br/>Existing connections do not migrate<br/>clients must reconnect"]
LIMIT_EDGE ~~~ LIMIT_PATH ~~~ LIMIT_ORIGIN ~~~ LIMIT_STREAM
end
%% Invisible positioning only: this is not a data-flow connection.
ORIGINS ~~~ BOUNDARIES
classDef public fill:#233d58,stroke:#7ab5dc,color:#f2f6ff classDef public fill:#233d58,stroke:#7ab5dc,color:#f2f6ff
classDef edge fill:#284c44,stroke:#7bc8a7,color:#f2f6ff classDef edge fill:#284c44,stroke:#7bc8a7,color:#f2f6ff
@@ -105,4 +114,5 @@ flowchart TB
class VPS,ROUTER,FW,NPM,APPS origin class VPS,ROUTER,FW,NPM,APPS origin
class GIT,PLAN,DEPLOY,SECRETS,HS,CERT,CFAPI ops class GIT,PLAN,DEPLOY,SECRETS,HS,CERT,CFAPI ops
class PROM,GRAF,ALERT monitor class PROM,GRAF,ALERT monitor
class LIMITS note class LIMIT_EDGE,LIMIT_PATH,LIMIT_ORIGIN,LIMIT_STREAM note
style BOUNDARIES fill:#291f2a,stroke:#dd9ba7,color:#fff5f6
Binary file not shown.

Before

Width:  |  Height:  |  Size: 774 KiB

After

Width:  |  Height:  |  Size: 805 KiB

@@ -1 +1 @@
<svg id="architecture" width="3452.69580078125" xmlns="http://www.w3.org/2000/svg" class="flowchart" height="2687.199951171875" viewBox="0 0 3452.69580078125 2687.199951171875" role="graphics-document document" aria-roledescription="flowchart-v2"><style>#architecture{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#architecture .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#architecture .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#architecture .error-icon{fill:#a44141;}#architecture .error-text{fill:#ddd;stroke:#ddd;}#architecture .edge-thickness-normal{stroke-width:1px;}#architecture .edge-thickness-thick{stroke-width:3.5px;}#architecture .edge-pattern-solid{stroke-dasharray:0;}#architecture .edge-thickness-invisible{stroke-width:0;fill:none;}#architecture .edge-pattern-dashed{stroke-dasharray:3;}#architecture .edge-pattern-dotted{stroke-dasharray:2;}#architecture .marker{fill:lightgrey;stroke:lightgrey;}#architecture .marker.cross{stroke:lightgrey;}#architecture svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#architecture p{margin:0;}#architecture .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#architecture .cluster-label text{fill:#F9FFFE;}#architecture .cluster-label span{color:#F9FFFE;}#architecture .cluster-label span p{background-color:transparent;}#architecture .label text,#architecture span{fill:#ccc;color:#ccc;}#architecture .node rect,#architecture .node circle,#architecture .node ellipse,#architecture .node polygon,#architecture .node path{fill:#1f2020;stroke:#ccc;stroke-width:1px;}#architecture .rough-node .label text,#architecture .node .label text,#architecture .image-shape .label,#architecture .icon-shape .label{text-anchor:middle;}#architecture .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#architecture .rough-node .label,#architecture .node .label,#architecture .image-shape .label,#architecture .icon-shape .label{text-align:center;}#architecture .node.clickable{cursor:pointer;}#architecture .root .anchor path{fill:lightgrey!important;stroke-width:0;stroke:lightgrey;}#architecture .arrowheadPath{fill:lightgrey;}#architecture .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#architecture .flowchart-link{stroke:lightgrey;fill:none;}#architecture .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#architecture .edgeLabel p{background-color:hsl(0, 0%, 34.4117647059%);}#architecture .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#architecture .labelBkg{background-color:rgba(87.75, 87.75, 87.75, 0.5);}#architecture .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#architecture .cluster text{fill:#F9FFFE;}#architecture .cluster span{color:#F9FFFE;}#architecture div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#architecture .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#architecture rect.text{fill:none;stroke-width:0;}#architecture .icon-shape,#architecture .image-shape{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#architecture .icon-shape p,#architecture .image-shape p{background-color:hsl(0, 0%, 34.4117647059%);padding:2px;}#architecture .icon-shape rect,#architecture .image-shape rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#architecture .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#architecture .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#architecture :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#architecture .public rect{fill:#233d58!important;stroke:#7ab5dc!important;color:#f2f6ff!important;}#architecture .public polygon{fill:#233d58!important;stroke:#7ab5dc!important;color:#f2f6ff!important;}#architecture .public ellipse{fill:#233d58!important;stroke:#7ab5dc!important;color:#f2f6ff!important;}#architecture .public circle{fill:#233d58!important;stroke:#7ab5dc!important;color:#f2f6ff!important;}#architecture .public path{fill:#233d58!important;stroke:#7ab5dc!important;color:#f2f6ff!important;}#architecture .public tspan{fill:#f2f6ff!important;}#architecture .edge rect{fill:#284c44!important;stroke:#7bc8a7!important;color:#f2f6ff!important;}#architecture .edge polygon{fill:#284c44!important;stroke:#7bc8a7!important;color:#f2f6ff!important;}#architecture .edge ellipse{fill:#2Line truncated <svg id="architecture" width="3454.791748046875" xmlns="http://www.w3.org/2000/svg" class="flowchart" height="2613.199951171875" viewBox="0 0 3454.791748046875 2613.199951171875" role="graphics-document document" aria-roledescription="flowchart-v2"><style>#architecture{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#architecture .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#architecture .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#architecture .error-icon{fill:#a44141;}#architecture .error-text{fill:#ddd;stroke:#ddd;}#architecture .edge-thickness-normal{stroke-width:1px;}#architecture .edge-thickness-thick{stroke-width:3.5px;}#architecture .edge-pattern-solid{stroke-dasharray:0;}#architecture .edge-thickness-invisible{stroke-width:0;fill:none;}#architecture .edge-pattern-dashed{stroke-dasharray:3;}#architecture .edge-pattern-dotted{stroke-dasharray:2;}#architecture .marker{fill:lightgrey;stroke:lightgrey;}#architecture .marker.cross{stroke:lightgrey;}#architecture svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#architecture p{margin:0;}#architecture .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#architecture .cluster-label text{fill:#F9FFFE;}#architecture .cluster-label span{color:#F9FFFE;}#architecture .cluster-label span p{background-color:transparent;}#architecture .label text,#architecture span{fill:#ccc;color:#ccc;}#architecture .node rect,#architecture .node circle,#architecture .node ellipse,#architecture .node polygon,#architecture .node path{fill:#1f2020;stroke:#ccc;stroke-width:1px;}#architecture .rough-node .label text,#architecture .node .label text,#architecture .image-shape .label,#architecture .icon-shape .label{text-anchor:middle;}#architecture .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#architecture .rough-node .label,#architecture .node .label,#architecture .image-shape .label,#architecture .icon-shape .label{text-align:center;}#architecture .node.clickable{cursor:pointer;}#architecture .root .anchor path{fill:lightgrey!important;stroke-width:0;stroke:lightgrey;}#architecture .arrowheadPath{fill:lightgrey;}#architecture .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#architecture .flowchart-link{stroke:lightgrey;fill:none;}#architecture .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#architecture .edgeLabel p{background-color:hsl(0, 0%, 34.4117647059%);}#architecture .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#architecture .labelBkg{background-color:rgba(87.75, 87.75, 87.75, 0.5);}#architecture .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#architecture .cluster text{fill:#F9FFFE;}#architecture .cluster span{color:#F9FFFE;}#architecture div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#architecture .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#architecture rect.text{fill:none;stroke-width:0;}#architecture .icon-shape,#architecture .image-shape{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#architecture .icon-shape p,#architecture .image-shape p{background-color:hsl(0, 0%, 34.4117647059%);padding:2px;}#architecture .icon-shape rect,#architecture .image-shape rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#architecture .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#architecture .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#architecture :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#architecture .public rect{fill:#233d58!important;stroke:#7ab5dc!important;color:#f2f6ff!important;}#architecture .public polygon{fill:#233d58!important;stroke:#7ab5dc!important;color:#f2f6ff!important;}#architecture .public ellipse{fill:#233d58!important;stroke:#7ab5dc!important;color:#f2f6ff!important;}#architecture .public circle{fill:#233d58!important;stroke:#7ab5dc!important;color:#f2f6ff!important;}#architecture .public path{fill:#233d58!important;stroke:#7ab5dc!important;color:#f2f6ff!important;}#architecture .public tspan{fill:#f2f6ff!important;}#architecture .edge rect{fill:#284c44!important;stroke:#7bc8a7!important;color:#f2f6ff!important;}#architecture .edge polygon{fill:#284c44!important;stroke:#7bc8a7!important;color:#f2f6ff!important;}#architecture .edge ellipse{fill:Line truncated

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 89 KiB