diff --git a/docs/diagrams/docker-compose.dot b/docs/diagrams/docker-compose.dot index 9c78dfa..e0ddfb1 100644 --- a/docs/diagrams/docker-compose.dot +++ b/docs/diagrams/docker-compose.dot @@ -27,8 +27,6 @@ digraph Compose { "svc:portainer" [label="portainer", shape=box, style=filled, fillcolor="#dfefff"]; "svc:prometheus" [label="prometheus", shape=box, style=filled, fillcolor="#dfefff"]; "svc:searxng-webapp" [label="searxng-webapp", shape=box, style=filled, fillcolor="#dfefff"]; - "svc:shift-recorder-web" [label="shift-recorder-web", shape=box, style=filled, fillcolor="#dfefff"]; - "svc:stockfill" [label="stockfill", shape=box, style=filled, fillcolor="#dfefff"]; "svc:telegraf" [label="telegraf", shape=box, style=filled, fillcolor="#dfefff"]; "svc:traefik" [label="traefik", shape=box, style=filled, fillcolor="#dfefff"]; "net:gramps" [label="gramps", shape=ellipse, style=filled, fillcolor="#f4f4f4"]; @@ -72,8 +70,6 @@ digraph Compose { "svc:prometheus" -> "net:monitor"; "svc:prometheus" -> "net:traefik"; "svc:searxng-webapp" -> "net:traefik"; - "svc:shift-recorder-web" -> "net:traefik"; - "svc:stockfill" -> "net:traefik"; "svc:telegraf" -> "net:monitor"; "svc:traefik" -> "net:traefik"; } diff --git a/docs/diagrams/docker-compose.svg b/docs/diagrams/docker-compose.svg index 4ccb12c..8b0a068 100644 --- a/docs/diagrams/docker-compose.svg +++ b/docs/diagrams/docker-compose.svg @@ -1,463 +1,439 @@ - - - + + Compose - + svc:authelia - -authelia + +authelia - + net:traefik - -traefik + +traefik svc:authelia->net:traefik - - + + svc:crowdsec - -crowdsec + +crowdsec svc:crowdsec->net:traefik - - + + svc:docker-socket-proxy - -docker-socket-proxy + +docker-socket-proxy - + net:monitor - -monitor + +monitor svc:docker-socket-proxy->net:monitor - - + + svc:docker-socket-proxy->net:traefik - - + + svc:docker-update-exporter - -docker-update-exporter + +docker-update-exporter svc:docker-update-exporter->net:monitor - - + + svc:error-pages - -error-pages + +error-pages svc:error-pages->net:traefik - - + + svc:gitea - -gitea + +gitea svc:gitea->net:traefik - - + + svc:gitea-runner - -gitea-runner + +gitea-runner svc:gitea-runner->net:traefik - - + + svc:gotify - -gotify + +gotify svc:gotify->net:traefik - - + + svc:grafana - -grafana + +grafana svc:grafana->net:monitor - - + + svc:grafana->net:traefik - - + + svc:gramps-redis - -gramps-redis + +gramps-redis - + net:gramps - -gramps + +gramps svc:gramps-redis->net:gramps - - + + svc:grampsweb - -grampsweb + +grampsweb svc:grampsweb->net:gramps - - + + svc:grampsweb->net:traefik - - + + svc:grampsweb_celery - -grampsweb_celery + +grampsweb_celery svc:grampsweb_celery->net:gramps - - + + svc:influxdb - -influxdb + +influxdb svc:influxdb->net:monitor - - + + svc:influxdb->net:traefik - - + + svc:monitor-kuma - -monitor-kuma + +monitor-kuma svc:monitor-kuma->net:monitor - - + + svc:monitor-kuma->net:traefik - - + + svc:mtls-bridge - -mtls-bridge + +mtls-bridge svc:mtls-bridge->net:monitor - - + + svc:mtls-bridge->net:traefik - - + + svc:nextcloud-db - -nextcloud-db + +nextcloud-db - + net:nextcloud - -nextcloud + +nextcloud svc:nextcloud-db->net:nextcloud - - + + svc:nextcloud-redis - -nextcloud-redis + +nextcloud-redis svc:nextcloud-redis->net:nextcloud - - + + svc:nextcloud-webapp - -nextcloud-webapp + +nextcloud-webapp svc:nextcloud-webapp->net:nextcloud - - + + svc:nextcloud-webapp->net:traefik - - + + svc:node-exporter - -node-exporter + +node-exporter svc:node-exporter->net:monitor - - + + svc:node-red - -node-red + +node-red svc:node-red->net:monitor - - + + svc:node-red->net:traefik - - + + svc:passbolt-db - -passbolt-db + +passbolt-db - + net:passbolt - -passbolt + +passbolt svc:passbolt-db->net:passbolt - - + + svc:passbolt-webapp - -passbolt-webapp + +passbolt-webapp svc:passbolt-webapp->net:passbolt - - + + svc:passbolt-webapp->net:traefik - - + + svc:pihole-exporter - -pihole-exporter + +pihole-exporter svc:pihole-exporter->net:monitor - - + + svc:portainer - -portainer + +portainer svc:portainer->net:traefik - - + + svc:prometheus - -prometheus + +prometheus svc:prometheus->net:monitor - - + + svc:prometheus->net:traefik - - + + svc:searxng-webapp - -searxng-webapp + +searxng-webapp svc:searxng-webapp->net:traefik - - - - - -svc:shift-recorder-web - -shift-recorder-web - - - -svc:shift-recorder-web->net:traefik - - - - - -svc:stockfill - -stockfill - - - -svc:stockfill->net:traefik - - + + - + svc:telegraf - -telegraf + +telegraf - + svc:telegraf->net:monitor - - + + - + svc:traefik - -traefik + +traefik - + svc:traefik->net:traefik - - + + diff --git a/docs/diagrams/docker-traefik-dynu.dot b/docs/diagrams/docker-traefik-dynu.dot index cab77a3..542c536 100644 --- a/docs/diagrams/docker-traefik-dynu.dot +++ b/docs/diagrams/docker-traefik-dynu.dot @@ -1,98 +1,88 @@ digraph DockerTraefikDynu { - graph [rankdir=LR, compound=true, splines=ortho, nodesep=0.7, ranksep=1.2, fontname="Helvetica", concentrate=true]; - node [fontname="Helvetica", fontsize=10, style="rounded,filled"]; + graph [rankdir=LR, compound=true, splines=polyline, nodesep=0.9, ranksep=1.6, fontname="Helvetica", concentrate=true, newrank=true]; + node [fontname="Helvetica", fontsize=11, style="rounded,filled"]; edge [fontname="Helvetica", fontsize=9, color="#334155"]; - "svc:traefik" [label="Traefik -(entrypoint)", shape=box, fillcolor="#bfdbfe"]; + "dynu" [label="Dynu / Public DNS", shape=box, fillcolor="#fde68a"]; + "svc:traefik" [label="Traefik", shape=box, fillcolor="#bfdbfe"]; + "dynu" -> "svc:traefik" [penwidth=1.6]; "svc:authelia" [label="authelia [TLS]", shape=box, fillcolor="#dcfce7"]; "svc:traefik" -> "svc:authelia" [penwidth=1.4]; - "dns:service-1." [label="service-1.", shape=note, fillcolor="#fef3c7"]; - "dns:service-1." -> "svc:traefik"; + "dns:auth." [label="auth.", shape=note, fillcolor="#fef3c7"]; + "dns:auth." -> "dynu"; "svc:gitea" [label="gitea :3000 [TLS]", shape=box, fillcolor="#dcfce7"]; "svc:traefik" -> "svc:gitea" [penwidth=1.4]; - "dns:service-2." [label="service-2.", shape=note, fillcolor="#fef3c7"]; - "dns:service-2." -> "svc:traefik"; + "dns:gitea." [label="gitea.", shape=note, fillcolor="#fef3c7"]; + "dns:gitea." -> "dynu"; "svc:gotify" [label="gotify :80", shape=box, fillcolor="#dcfce7"]; "svc:traefik" -> "svc:gotify" [penwidth=1.4]; - "dns:service-3." [label="service-3.", shape=note, fillcolor="#fef3c7"]; - "dns:service-3." -> "svc:traefik"; + "dns:gotify." [label="gotify.", shape=note, fillcolor="#fef3c7"]; + "dns:gotify." -> "dynu"; "svc:grafana" [label="grafana :3000", shape=box, fillcolor="#dcfce7"]; "svc:traefik" -> "svc:grafana" [penwidth=1.4]; - "dns:service-4." [label="service-4.", shape=note, fillcolor="#fef3c7"]; - "dns:service-4." -> "svc:traefik"; + "dns:grafana." [label="grafana.", shape=note, fillcolor="#fef3c7"]; + "dns:grafana." -> "dynu"; "svc:grampsweb" [label="grampsweb", shape=box, fillcolor="#dcfce7"]; "svc:traefik" -> "svc:grampsweb" [penwidth=1.4]; - "dns:service-5." [label="service-5.", shape=note, fillcolor="#fef3c7"]; - "dns:service-5." -> "svc:traefik"; + "dns:familytree." [label="familytree.", shape=note, fillcolor="#fef3c7"]; + "dns:familytree." -> "dynu"; "svc:influxdb" [label="influxdb :8086 [authelia]", shape=box, fillcolor="#dcfce7"]; "svc:traefik" -> "svc:influxdb" [penwidth=1.4]; - "dns:service-6." [label="service-6.", shape=note, fillcolor="#fef3c7"]; - "dns:service-6." -> "svc:traefik"; + "dns:influxdb." [label="influxdb.", shape=note, fillcolor="#fef3c7"]; + "dns:influxdb." -> "dynu"; "svc:monitor-kuma" [label="monitor-kuma [TLS]", shape=box, fillcolor="#dcfce7"]; "svc:traefik" -> "svc:monitor-kuma" [penwidth=1.4]; - "dns:service-7." [label="service-7.", shape=note, fillcolor="#fef3c7"]; - "dns:service-7." -> "svc:traefik"; + "dns:monitor-kuma." [label="monitor-kuma.", shape=note, fillcolor="#fef3c7"]; + "dns:monitor-kuma." -> "dynu"; "svc:mtls-bridge" [label="mtls-bridge :8080 [mTLS]", shape=box, fillcolor="#dcfce7"]; "svc:traefik" -> "svc:mtls-bridge" [penwidth=1.4]; - "dns:service-8." [label="service-8.", shape=note, fillcolor="#fef3c7"]; - "dns:service-8." -> "svc:traefik"; + "dns:mtls-bridge." [label="mtls-bridge.", shape=note, fillcolor="#fef3c7"]; + "dns:mtls-bridge." -> "dynu"; "svc:nextcloud-webapp" [label="nextcloud-webapp", shape=box, fillcolor="#dcfce7"]; "svc:traefik" -> "svc:nextcloud-webapp" [penwidth=1.4]; - "dns:service-9." [label="service-9.", shape=note, fillcolor="#fef3c7"]; - "dns:service-9." -> "svc:traefik"; + "dns:nextcloud." [label="nextcloud.", shape=note, fillcolor="#fef3c7"]; + "dns:nextcloud." -> "dynu"; "svc:node-red" [label="node-red :1880 [authelia]", shape=box, fillcolor="#dcfce7"]; "svc:traefik" -> "svc:node-red" [penwidth=1.4]; - "dns:service-10." [label="service-10.", shape=note, fillcolor="#fef3c7"]; - "dns:service-10." -> "svc:traefik"; + "dns:node-red." [label="node-red.", shape=note, fillcolor="#fef3c7"]; + "dns:node-red." -> "dynu"; "svc:passbolt-webapp" [label="passbolt-webapp", shape=box, fillcolor="#dcfce7"]; "svc:traefik" -> "svc:passbolt-webapp" [penwidth=1.4]; - "dns:service-11." [label="service-11.", shape=note, fillcolor="#fef3c7"]; - "dns:service-11." -> "svc:traefik"; + "dns:passbolt." [label="passbolt.", shape=note, fillcolor="#fef3c7"]; + "dns:passbolt." -> "dynu"; "svc:portainer" [label="portainer :9000 [TLS]", shape=box, fillcolor="#dcfce7"]; "svc:traefik" -> "svc:portainer" [penwidth=1.4]; - "dns:service-12." [label="service-12.", shape=note, fillcolor="#fef3c7"]; - "dns:service-12." -> "svc:traefik"; + "dns:portainer." [label="portainer.", shape=note, fillcolor="#fef3c7"]; + "dns:portainer." -> "dynu"; "svc:prometheus" [label="prometheus :9090 [authelia]", shape=box, fillcolor="#dcfce7"]; "svc:traefik" -> "svc:prometheus" [penwidth=1.4]; - "dns:service-13." [label="service-13.", shape=note, fillcolor="#fef3c7"]; - "dns:service-13." -> "svc:traefik"; + "dns:prometheus." [label="prometheus.", shape=note, fillcolor="#fef3c7"]; + "dns:prometheus." -> "dynu"; "svc:searxng-webapp" [label="searxng-webapp", shape=box, fillcolor="#dcfce7"]; "svc:traefik" -> "svc:searxng-webapp" [penwidth=1.4]; - "dns:service-14." [label="service-14.", shape=note, fillcolor="#fef3c7"]; - "dns:service-14." -> "svc:traefik"; - "svc:shift-recorder-web" [label="shift-recorder-web -[TLS]", shape=box, fillcolor="#dcfce7"]; - "svc:traefik" -> "svc:shift-recorder-web" [penwidth=1.4]; - "dns:service-15." [label="service-15.", shape=note, fillcolor="#fef3c7"]; - "dns:service-15." -> "svc:traefik"; - "svc:stockfill" [label="stockfill -:80 -[TLS]", shape=box, fillcolor="#dcfce7"]; - "svc:traefik" -> "svc:stockfill" [penwidth=1.4]; - "dns:service-16." [label="service-16.", shape=note, fillcolor="#fef3c7"]; - "dns:service-16." -> "svc:traefik"; + "dns:searxng." [label="searxng.", shape=note, fillcolor="#fef3c7"]; + "dns:searxng." -> "dynu"; "svc:traefik" [label="traefik [authelia]", shape=box, fillcolor="#dcfce7"]; "svc:traefik" -> "svc:traefik" [penwidth=1.4]; - "dns:service-17." [label="service-17.", shape=note, fillcolor="#fef3c7"]; - "dns:service-17." -> "svc:traefik"; - { rank=same; "dns:service-1."; "dns:service-10."; "dns:service-11."; "dns:service-12."; "dns:service-13."; "dns:service-14."; "dns:service-15."; "dns:service-16."; "dns:service-17."; "dns:service-2."; "dns:service-3."; "dns:service-4."; "dns:service-5."; "dns:service-6."; "dns:service-7."; "dns:service-8."; "dns:service-9."; } + "dns:traefik." [label="traefik.", shape=note, fillcolor="#fef3c7"]; + "dns:traefik." -> "dynu"; + { rank=same; "dns:auth."; "dns:familytree."; "dns:gitea."; "dns:gotify."; "dns:grafana."; "dns:influxdb."; "dns:monitor-kuma."; "dns:mtls-bridge."; "dns:nextcloud."; "dns:node-red."; "dns:passbolt."; "dns:portainer."; "dns:prometheus."; "dns:searxng."; "dns:traefik."; } subgraph "cluster_networks" { label="Docker backend networks"; style="rounded,dashed"; color="#d1d5db"; "net:gramps" [label="gramps", shape=ellipse, fillcolor="#f8fafc"]; @@ -124,7 +114,5 @@ digraph DockerTraefikDynu { "svc:prometheus" -> "net:monitor" [style=dashed, color="#94a3b8", arrowsize=0.7]; "svc:prometheus" -> "net:traefik" [style=dashed, color="#94a3b8", arrowsize=0.7]; "svc:searxng-webapp" -> "net:traefik" [style=dashed, color="#94a3b8", arrowsize=0.7]; - "svc:shift-recorder-web" -> "net:traefik" [style=dashed, color="#94a3b8", arrowsize=0.7]; - "svc:stockfill" -> "net:traefik" [style=dashed, color="#94a3b8", arrowsize=0.7]; "svc:traefik" -> "net:traefik" [style=dashed, color="#94a3b8", arrowsize=0.7]; } diff --git a/docs/diagrams/docker-traefik-dynu.svg b/docs/diagrams/docker-traefik-dynu.svg index f38852a..35edf82 100644 --- a/docs/diagrams/docker-traefik-dynu.svg +++ b/docs/diagrams/docker-traefik-dynu.svg @@ -1,666 +1,611 @@ - - - + + DockerTraefikDynu - + cluster_networks - -Docker backend networks + +Docker backend networks + + + +dynu + +Dynu / Public DNS - + svc:traefik - -traefik -[authelia] + +traefik +[authelia] + + + +dynu->svc:traefik + + - + svc:traefik->svc:traefik - - + + - + svc:authelia - -authelia -[TLS] + +authelia +[TLS] - + svc:traefik->svc:authelia - - + + - + svc:gitea - -gitea -:3000 -[TLS] + +gitea +:3000 +[TLS] - + svc:traefik->svc:gitea - - + + - + svc:gotify - -gotify -:80 + +gotify +:80 - + svc:traefik->svc:gotify - - + + - + svc:grafana - -grafana -:3000 + +grafana +:3000 - + svc:traefik->svc:grafana - - + + - + svc:grampsweb - -grampsweb + +grampsweb - + svc:traefik->svc:grampsweb - - + + - + svc:influxdb - -influxdb -:8086 -[authelia] + +influxdb +:8086 +[authelia] - + svc:traefik->svc:influxdb - - + + - + svc:monitor-kuma - -monitor-kuma -[TLS] + +monitor-kuma +[TLS] - + svc:traefik->svc:monitor-kuma - - + + - + svc:mtls-bridge - -mtls-bridge -:8080 -[mTLS] + +mtls-bridge +:8080 +[mTLS] - + svc:traefik->svc:mtls-bridge - - + + - + svc:nextcloud-webapp - -nextcloud-webapp + +nextcloud-webapp - + svc:traefik->svc:nextcloud-webapp - - + + - + svc:node-red - -node-red -:1880 -[authelia] + +node-red +:1880 +[authelia] - + svc:traefik->svc:node-red - - + + - + svc:passbolt-webapp - -passbolt-webapp + +passbolt-webapp - + svc:traefik->svc:passbolt-webapp - - + + - + svc:portainer - -portainer -:9000 -[TLS] + +portainer +:9000 +[TLS] - + svc:traefik->svc:portainer - - + + - + svc:prometheus - -prometheus -:9090 -[authelia] + +prometheus +:9090 +[authelia] - + svc:traefik->svc:prometheus - - + + - + svc:searxng-webapp - -searxng-webapp + +searxng-webapp - + svc:traefik->svc:searxng-webapp - - - - - -svc:shift-recorder-web - -shift-recorder-web -[TLS] - - - -svc:traefik->svc:shift-recorder-web - - - - - -svc:stockfill - -stockfill -:80 -[TLS] - - - -svc:traefik->svc:stockfill - - + + - + net:traefik - -traefik + +traefik - + svc:traefik->net:traefik - - + + - + svc:authelia->net:traefik - - + + - - -dns:service-1.<internal-domain> - - - -service-1.<internal-domain> + + +dns:auth.<domain> + + + +auth.<domain> - - -dns:service-1.<internal-domain>->svc:traefik - - + + +dns:auth.<domain>->dynu + + - + svc:gitea->net:traefik - - + + - - -dns:service-2.<internal-domain> - - - -service-2.<internal-domain> + + +dns:gitea.<domain> + + + +gitea.<domain> - - -dns:service-2.<internal-domain>->svc:traefik - - + + +dns:gitea.<domain>->dynu + + - + svc:gotify->net:traefik - - + + - - -dns:service-3.<internal-domain> - - - -service-3.<internal-domain> + + +dns:gotify.<domain> + + + +gotify.<domain> - - -dns:service-3.<internal-domain>->svc:traefik - - + + +dns:gotify.<domain>->dynu + + - + net:monitor - -monitor + +monitor - + svc:grafana->net:monitor - - + + - + svc:grafana->net:traefik - - + + - - -dns:service-4.<internal-domain> - - - -service-4.<internal-domain> + + +dns:grafana.<domain> + + + +grafana.<domain> - - -dns:service-4.<internal-domain>->svc:traefik - - + + +dns:grafana.<domain>->dynu + + - + net:gramps - -gramps + +gramps - + svc:grampsweb->net:gramps - - + + - + svc:grampsweb->net:traefik - - + + - - -dns:service-5.<internal-domain> - - - -service-5.<internal-domain> + + +dns:familytree.<domain> + + + +familytree.<domain> - - -dns:service-5.<internal-domain>->svc:traefik - - + + +dns:familytree.<domain>->dynu + + - + svc:influxdb->net:monitor - - + + - + svc:influxdb->net:traefik - - + + - - -dns:service-6.<internal-domain> - - - -service-6.<internal-domain> + + +dns:influxdb.<domain> + + + +influxdb.<domain> - - -dns:service-6.<internal-domain>->svc:traefik - - + + +dns:influxdb.<domain>->dynu + + - + svc:monitor-kuma->net:monitor - - + + - + svc:monitor-kuma->net:traefik - - + + - - -dns:service-7.<internal-domain> - - - -service-7.<internal-domain> + + +dns:monitor-kuma.<domain> + + + +monitor-kuma.<domain> - - -dns:service-7.<internal-domain>->svc:traefik - - + + +dns:monitor-kuma.<domain>->dynu + + - + svc:mtls-bridge->net:monitor - - + + - + svc:mtls-bridge->net:traefik - - + + - - -dns:service-8.<internal-domain> - - - -service-8.<internal-domain> + + +dns:mtls-bridge.<domain> + + + +mtls-bridge.<domain> - - -dns:service-8.<internal-domain>->svc:traefik - - + + +dns:mtls-bridge.<domain>->dynu + + - + net:nextcloud - -nextcloud + +nextcloud - + svc:nextcloud-webapp->net:nextcloud - - + + - + svc:nextcloud-webapp->net:traefik - - + + - - -dns:service-9.<internal-domain> - - - -service-9.<internal-domain> + + +dns:nextcloud.<domain> + + + +nextcloud.<domain> - - -dns:service-9.<internal-domain>->svc:traefik - - + + +dns:nextcloud.<domain>->dynu + + - + svc:node-red->net:monitor - - + + - + svc:node-red->net:traefik - - + + - - -dns:service-10.<internal-domain> - - - -service-10.<internal-domain> + + +dns:node-red.<domain> + + + +node-red.<domain> - - -dns:service-10.<internal-domain>->svc:traefik - - + + +dns:node-red.<domain>->dynu + + - + net:passbolt - -passbolt + +passbolt - + svc:passbolt-webapp->net:passbolt - - + + - + svc:passbolt-webapp->net:traefik - - + + - - -dns:service-11.<internal-domain> - - - -service-11.<internal-domain> + + +dns:passbolt.<domain> + + + +passbolt.<domain> - - -dns:service-11.<internal-domain>->svc:traefik - - + + +dns:passbolt.<domain>->dynu + + - + svc:portainer->net:traefik - - + + - - -dns:service-12.<internal-domain> - - - -service-12.<internal-domain> + + +dns:portainer.<domain> + + + +portainer.<domain> - - -dns:service-12.<internal-domain>->svc:traefik - - + + +dns:portainer.<domain>->dynu + + - + svc:prometheus->net:monitor - - + + - + svc:prometheus->net:traefik - - + + - - -dns:service-13.<internal-domain> - - - -service-13.<internal-domain> + + +dns:prometheus.<domain> + + + +prometheus.<domain> - - -dns:service-13.<internal-domain>->svc:traefik - - + + +dns:prometheus.<domain>->dynu + + - + svc:searxng-webapp->net:traefik - - + + - - -dns:service-14.<internal-domain> - - - -service-14.<internal-domain> + + +dns:searxng.<domain> + + + +searxng.<domain> - - -dns:service-14.<internal-domain>->svc:traefik - - + + +dns:searxng.<domain>->dynu + + - - -svc:shift-recorder-web->net:traefik - - - - + -dns:service-15.<internal-domain> - - - -service-15.<internal-domain> +dns:traefik.<domain> + + + +traefik.<domain> - - -dns:service-15.<internal-domain>->svc:traefik - - - - - -svc:stockfill->net:traefik - - - - - -dns:service-16.<internal-domain> - - - -service-16.<internal-domain> - - - -dns:service-16.<internal-domain>->svc:traefik - - - - - -dns:service-17.<internal-domain> - - - -service-17.<internal-domain> - - - -dns:service-17.<internal-domain>->svc:traefik - - + + +dns:traefik.<domain>->dynu + + diff --git a/docs/diagrams/physical-topology.dot b/docs/diagrams/physical-topology.dot index 44864e9..c05614c 100644 --- a/docs/diagrams/physical-topology.dot +++ b/docs/diagrams/physical-topology.dot @@ -1,91 +1,4 @@ digraph PhysicalTopology { - graph [rankdir=LR, compound=true, splines=polyline, nodesep=0.7, ranksep=1.2, fontname="Helvetica", concentrate=true]; - node [fontname="Helvetica", fontsize=10, style="rounded,filled", fillcolor="#ffffff"]; - edge [fontname="Helvetica", fontsize=9, color="#64748b"]; - subgraph "cluster_docker" { - label="docker host"; - style="rounded,filled"; - color="#93c5fd"; - fillcolor="#eff6ff"; - subgraph "cluster_docker_apps" { - label="apps"; - style="rounded,dashed"; - color="#bfdbfe"; - fillcolor="#f8fbff"; - "svc:crowdsec" [label="crowdsec", shape=box, fillcolor="#dcfce7"]; - "svc:docker-update-exporter" [label="docker-update-exporter", shape=box, fillcolor="#dcfce7"]; - "svc:error-pages" [label="error-pages", shape=box, fillcolor="#dcfce7"]; - "svc:gitea" [label="gitea", shape=box, fillcolor="#dcfce7"]; - "svc:gotify" [label="gotify", shape=box, fillcolor="#dcfce7"]; - "svc:grampsweb" [label="grampsweb", shape=box, fillcolor="#dcfce7"]; - "svc:grampsweb_celery" [label="grampsweb_celery", shape=box, fillcolor="#dcfce7"]; - "svc:monitor-kuma" [label="monitor-kuma", shape=box, fillcolor="#dcfce7"]; - "svc:mtls-bridge" [label="mtls-bridge", shape=box, fillcolor="#dcfce7"]; - "svc:nextcloud-webapp" [label="nextcloud-webapp", shape=box, fillcolor="#dcfce7"]; - "svc:node-red" [label="node-red", shape=box, fillcolor="#dcfce7"]; - "svc:passbolt-webapp" [label="passbolt-webapp", shape=box, fillcolor="#dcfce7"]; - "svc:portainer" [label="portainer", shape=box, fillcolor="#dcfce7"]; - "svc:searxng-webapp" [label="searxng-webapp", shape=box, fillcolor="#dcfce7"]; - "svc:shift-recorder-web" [label="shift-recorder-web", shape=box, fillcolor="#dcfce7"]; - "svc:stockfill" [label="stockfill", shape=box, fillcolor="#dcfce7"]; - "svc:telegraf" [label="telegraf", shape=box, fillcolor="#dcfce7"]; - } - subgraph "cluster_docker_automation" { - label="automation"; - style="rounded,dashed"; - color="#bfdbfe"; - fillcolor="#f8fbff"; - "svc:gitea-runner" [label="gitea-runner", shape=box, fillcolor="#dcfce7"]; - } - subgraph "cluster_docker_edge_proxy_auth" { - label="edge/proxy/auth"; - style="rounded,dashed"; - color="#bfdbfe"; - fillcolor="#f8fbff"; - "svc:authelia" [label="authelia", shape=box, fillcolor="#dcfce7"]; - "svc:docker-socket-proxy" [label="docker-socket-proxy", shape=box, fillcolor="#dcfce7"]; - "svc:traefik" [label="traefik", shape=box, fillcolor="#dcfce7"]; - } - subgraph "cluster_docker_monitoring" { - label="monitoring"; - style="rounded,dashed"; - color="#bfdbfe"; - fillcolor="#f8fbff"; - "svc:grafana" [label="grafana", shape=box, fillcolor="#dcfce7"]; - "svc:node-exporter" [label="node-exporter", shape=box, fillcolor="#dcfce7"]; - "svc:prometheus" [label="prometheus", shape=box, fillcolor="#dcfce7"]; - } - subgraph "cluster_docker_storage_database_support" { - label="storage/database/support"; - style="rounded,dashed"; - color="#bfdbfe"; - fillcolor="#f8fbff"; - "svc:gramps-redis" [label="gramps-redis", shape=box, fillcolor="#dcfce7"]; - "svc:influxdb" [label="influxdb", shape=box, fillcolor="#dcfce7"]; - "svc:nextcloud-db" [label="nextcloud-db", shape=box, fillcolor="#dcfce7"]; - "svc:nextcloud-redis" [label="nextcloud-redis", shape=box, fillcolor="#dcfce7"]; - "svc:passbolt-db" [label="passbolt-db", shape=box, fillcolor="#dcfce7"]; - } - } - subgraph "cluster_raspberrypi" { - label="raspberrypi host"; - style="rounded,filled"; - color="#93c5fd"; - fillcolor="#eff6ff"; - subgraph "cluster_raspberrypi_apps" { - label="apps"; - style="rounded,dashed"; - color="#bfdbfe"; - fillcolor="#f8fbff"; - "svc:pihole-exporter" [label="pihole-exporter", shape=box, fillcolor="#dcfce7"]; - } - } - subgraph "cluster_legend" { - label="Legend"; style="rounded"; color="#d1d5db"; - "leg_host" [label="Host cluster", shape=box3d, fillcolor="#eff6ff"]; - "leg_cat" [label="Service category", shape=folder, fillcolor="#f8fbff"]; - "leg_svc" [label="Container/service", shape=box, fillcolor="#dcfce7"]; - "leg_host" -> "leg_cat" [style=dashed]; - "leg_cat" -> "leg_svc" [style=dashed]; - } + graph [rankdir=LR, fontname="Helvetica", nodesep=1.0, ranksep=1.5]; + "placeholder:inventory" [shape=note, style="filled", fillcolor="#fef3c7", label="Host inventory JSON not found.\nGenerate terraform inventory and rerun scripts/docs/generate-all.sh\n(--host-inventory )."]; } diff --git a/docs/diagrams/physical-topology.svg b/docs/diagrams/physical-topology.svg index f05c23a..5f20db3 100644 --- a/docs/diagrams/physical-topology.svg +++ b/docs/diagrams/physical-topology.svg @@ -1,271 +1,23 @@ - - - + + PhysicalTopology - - -cluster_docker - -docker host - - -cluster_docker_apps - -apps - - -cluster_docker_automation - -automation - - -cluster_docker_edge_proxy_auth - -edge/proxy/auth - - -cluster_docker_monitoring - -monitoring - - -cluster_docker_storage_database_support - -storage/database/support - - -cluster_raspberrypi - -raspberrypi host - - -cluster_raspberrypi_apps - -apps - - -cluster_legend - -Legend - - + + -svc:crowdsec - -crowdsec - - - -svc:docker-update-exporter - -docker-update-exporter - - - -svc:error-pages - -error-pages - - - -svc:gitea - -gitea - - - -svc:gotify - -gotify - - - -svc:grampsweb - -grampsweb - - - -svc:grampsweb_celery - -grampsweb_celery - - - -svc:monitor-kuma - -monitor-kuma - - - -svc:mtls-bridge - -mtls-bridge - - - -svc:nextcloud-webapp - -nextcloud-webapp - - - -svc:node-red - -node-red - - - -svc:passbolt-webapp - -passbolt-webapp - - - -svc:portainer - -portainer - - - -svc:searxng-webapp - -searxng-webapp - - - -svc:shift-recorder-web - -shift-recorder-web - - - -svc:stockfill - -stockfill - - - -svc:telegraf - -telegraf - - - -svc:gitea-runner - -gitea-runner - - - -svc:authelia - -authelia - - - -svc:docker-socket-proxy - -docker-socket-proxy - - - -svc:traefik - -traefik - - - -svc:grafana - -grafana - - - -svc:node-exporter - -node-exporter - - - -svc:prometheus - -prometheus - - - -svc:gramps-redis - -gramps-redis - - - -svc:influxdb - -influxdb - - - -svc:nextcloud-db - -nextcloud-db - - - -svc:nextcloud-redis - -nextcloud-redis - - - -svc:passbolt-db - -passbolt-db - - - -svc:pihole-exporter - -pihole-exporter - - - -leg_host - - - - -Host cluster - - - -leg_cat - -Service category - - - -leg_host->leg_cat - - - - - -leg_svc - -Container/service - - - -leg_cat->leg_svc - - +placeholder:inventory + + + +Host inventory JSON not found. +Generate terraform inventory and rerun scripts/docs/generate-all.sh +(--host-inventory <path>). diff --git a/docs/public/compose-inventory.md b/docs/public/compose-inventory.md index 4354f2c..ffffaac 100644 --- a/docs/public/compose-inventory.md +++ b/docs/public/compose-inventory.md @@ -1,12 +1,12 @@ # Docker Compose Inventory -Source fingerprint: `0fad36c3fed6` +Source fingerprint: `232be78ef441` ## Summary | Item | Count | |---|---:| -| Services | 30 | +| Services | 28 | | Networks | 5 | | Volumes | 0 | @@ -40,8 +40,6 @@ Source fingerprint: `0fad36c3fed6` | portainer | portainer | portainer/portainer-ce:latest | | monitoring, all, portainer | traefik | | unless-stopped | | prometheus | prometheus | prom/prometheus:latest | | monitoring, all, prometheus | monitor, traefik | | unless-stopped | | searxng-webapp | searxng-webapp | searxng/searxng | | apps, all, searxng | traefik | | always | -| shift-recorder-web | shift-recorder | | /home/nixos/docker/apps/shift-recorder | apps, all, shift-recorder | traefik | | unless-stopped | -| stockfill | stockfill | | /home/nixos/docker/apps/stockfill | apps, all, stockfill | traefik | | unless-stopped | | telegraf | telegraf | telegraf:latest | | monitoring, all, telegraf, prometheus | monitor | | unless-stopped | | traefik | traefik | traefik:3 | /home/nixos/docker/core | core, all, traefik | traefik | {'mode': 'ingress', 'target': 80, 'published': '80', 'protocol': 'tcp'}, {'mode': 'ingress', 'target': 443, 'published': '443', 'protocol': 'tcp'} | always | diff --git a/docs/public/diagrams.md b/docs/public/diagrams.md index 12b1336..187cb61 100644 --- a/docs/public/diagrams.md +++ b/docs/public/diagrams.md @@ -4,7 +4,9 @@ This view groups containers by inferred host and service role (edge/proxy/auth, monitoring, automation, apps, and supporting storage/services). -![Physical topology](physical-topology.svg) +
+ Physical topology +
## Docker, Traefik and Dynu routing @@ -12,4 +14,6 @@ This view shows sanitised public DNS names flowing to Traefik, then to exposed D _Diagrams are generated from Compose data and Traefik labels._ -![Docker Traefik Dynu](docker-traefik-dynu.svg) +
+ Docker Traefik Dynu +
diff --git a/docs/public/docker-compose.svg b/docs/public/docker-compose.svg index 4ccb12c..8b0a068 100644 --- a/docs/public/docker-compose.svg +++ b/docs/public/docker-compose.svg @@ -1,463 +1,439 @@ - - - + + Compose - + svc:authelia - -authelia + +authelia - + net:traefik - -traefik + +traefik svc:authelia->net:traefik - - + + svc:crowdsec - -crowdsec + +crowdsec svc:crowdsec->net:traefik - - + + svc:docker-socket-proxy - -docker-socket-proxy + +docker-socket-proxy - + net:monitor - -monitor + +monitor svc:docker-socket-proxy->net:monitor - - + + svc:docker-socket-proxy->net:traefik - - + + svc:docker-update-exporter - -docker-update-exporter + +docker-update-exporter svc:docker-update-exporter->net:monitor - - + + svc:error-pages - -error-pages + +error-pages svc:error-pages->net:traefik - - + + svc:gitea - -gitea + +gitea svc:gitea->net:traefik - - + + svc:gitea-runner - -gitea-runner + +gitea-runner svc:gitea-runner->net:traefik - - + + svc:gotify - -gotify + +gotify svc:gotify->net:traefik - - + + svc:grafana - -grafana + +grafana svc:grafana->net:monitor - - + + svc:grafana->net:traefik - - + + svc:gramps-redis - -gramps-redis + +gramps-redis - + net:gramps - -gramps + +gramps svc:gramps-redis->net:gramps - - + + svc:grampsweb - -grampsweb + +grampsweb svc:grampsweb->net:gramps - - + + svc:grampsweb->net:traefik - - + + svc:grampsweb_celery - -grampsweb_celery + +grampsweb_celery svc:grampsweb_celery->net:gramps - - + + svc:influxdb - -influxdb + +influxdb svc:influxdb->net:monitor - - + + svc:influxdb->net:traefik - - + + svc:monitor-kuma - -monitor-kuma + +monitor-kuma svc:monitor-kuma->net:monitor - - + + svc:monitor-kuma->net:traefik - - + + svc:mtls-bridge - -mtls-bridge + +mtls-bridge svc:mtls-bridge->net:monitor - - + + svc:mtls-bridge->net:traefik - - + + svc:nextcloud-db - -nextcloud-db + +nextcloud-db - + net:nextcloud - -nextcloud + +nextcloud svc:nextcloud-db->net:nextcloud - - + + svc:nextcloud-redis - -nextcloud-redis + +nextcloud-redis svc:nextcloud-redis->net:nextcloud - - + + svc:nextcloud-webapp - -nextcloud-webapp + +nextcloud-webapp svc:nextcloud-webapp->net:nextcloud - - + + svc:nextcloud-webapp->net:traefik - - + + svc:node-exporter - -node-exporter + +node-exporter svc:node-exporter->net:monitor - - + + svc:node-red - -node-red + +node-red svc:node-red->net:monitor - - + + svc:node-red->net:traefik - - + + svc:passbolt-db - -passbolt-db + +passbolt-db - + net:passbolt - -passbolt + +passbolt svc:passbolt-db->net:passbolt - - + + svc:passbolt-webapp - -passbolt-webapp + +passbolt-webapp svc:passbolt-webapp->net:passbolt - - + + svc:passbolt-webapp->net:traefik - - + + svc:pihole-exporter - -pihole-exporter + +pihole-exporter svc:pihole-exporter->net:monitor - - + + svc:portainer - -portainer + +portainer svc:portainer->net:traefik - - + + svc:prometheus - -prometheus + +prometheus svc:prometheus->net:monitor - - + + svc:prometheus->net:traefik - - + + svc:searxng-webapp - -searxng-webapp + +searxng-webapp svc:searxng-webapp->net:traefik - - - - - -svc:shift-recorder-web - -shift-recorder-web - - - -svc:shift-recorder-web->net:traefik - - - - - -svc:stockfill - -stockfill - - - -svc:stockfill->net:traefik - - + + - + svc:telegraf - -telegraf + +telegraf - + svc:telegraf->net:monitor - - + + - + svc:traefik - -traefik + +traefik - + svc:traefik->net:traefik - - + + diff --git a/docs/public/docker-traefik-dynu.svg b/docs/public/docker-traefik-dynu.svg index f38852a..35edf82 100644 --- a/docs/public/docker-traefik-dynu.svg +++ b/docs/public/docker-traefik-dynu.svg @@ -1,666 +1,611 @@ - - - + + DockerTraefikDynu - + cluster_networks - -Docker backend networks + +Docker backend networks + + + +dynu + +Dynu / Public DNS - + svc:traefik - -traefik -[authelia] + +traefik +[authelia] + + + +dynu->svc:traefik + + - + svc:traefik->svc:traefik - - + + - + svc:authelia - -authelia -[TLS] + +authelia +[TLS] - + svc:traefik->svc:authelia - - + + - + svc:gitea - -gitea -:3000 -[TLS] + +gitea +:3000 +[TLS] - + svc:traefik->svc:gitea - - + + - + svc:gotify - -gotify -:80 + +gotify +:80 - + svc:traefik->svc:gotify - - + + - + svc:grafana - -grafana -:3000 + +grafana +:3000 - + svc:traefik->svc:grafana - - + + - + svc:grampsweb - -grampsweb + +grampsweb - + svc:traefik->svc:grampsweb - - + + - + svc:influxdb - -influxdb -:8086 -[authelia] + +influxdb +:8086 +[authelia] - + svc:traefik->svc:influxdb - - + + - + svc:monitor-kuma - -monitor-kuma -[TLS] + +monitor-kuma +[TLS] - + svc:traefik->svc:monitor-kuma - - + + - + svc:mtls-bridge - -mtls-bridge -:8080 -[mTLS] + +mtls-bridge +:8080 +[mTLS] - + svc:traefik->svc:mtls-bridge - - + + - + svc:nextcloud-webapp - -nextcloud-webapp + +nextcloud-webapp - + svc:traefik->svc:nextcloud-webapp - - + + - + svc:node-red - -node-red -:1880 -[authelia] + +node-red +:1880 +[authelia] - + svc:traefik->svc:node-red - - + + - + svc:passbolt-webapp - -passbolt-webapp + +passbolt-webapp - + svc:traefik->svc:passbolt-webapp - - + + - + svc:portainer - -portainer -:9000 -[TLS] + +portainer +:9000 +[TLS] - + svc:traefik->svc:portainer - - + + - + svc:prometheus - -prometheus -:9090 -[authelia] + +prometheus +:9090 +[authelia] - + svc:traefik->svc:prometheus - - + + - + svc:searxng-webapp - -searxng-webapp + +searxng-webapp - + svc:traefik->svc:searxng-webapp - - - - - -svc:shift-recorder-web - -shift-recorder-web -[TLS] - - - -svc:traefik->svc:shift-recorder-web - - - - - -svc:stockfill - -stockfill -:80 -[TLS] - - - -svc:traefik->svc:stockfill - - + + - + net:traefik - -traefik + +traefik - + svc:traefik->net:traefik - - + + - + svc:authelia->net:traefik - - + + - - -dns:service-1.<internal-domain> - - - -service-1.<internal-domain> + + +dns:auth.<domain> + + + +auth.<domain> - - -dns:service-1.<internal-domain>->svc:traefik - - + + +dns:auth.<domain>->dynu + + - + svc:gitea->net:traefik - - + + - - -dns:service-2.<internal-domain> - - - -service-2.<internal-domain> + + +dns:gitea.<domain> + + + +gitea.<domain> - - -dns:service-2.<internal-domain>->svc:traefik - - + + +dns:gitea.<domain>->dynu + + - + svc:gotify->net:traefik - - + + - - -dns:service-3.<internal-domain> - - - -service-3.<internal-domain> + + +dns:gotify.<domain> + + + +gotify.<domain> - - -dns:service-3.<internal-domain>->svc:traefik - - + + +dns:gotify.<domain>->dynu + + - + net:monitor - -monitor + +monitor - + svc:grafana->net:monitor - - + + - + svc:grafana->net:traefik - - + + - - -dns:service-4.<internal-domain> - - - -service-4.<internal-domain> + + +dns:grafana.<domain> + + + +grafana.<domain> - - -dns:service-4.<internal-domain>->svc:traefik - - + + +dns:grafana.<domain>->dynu + + - + net:gramps - -gramps + +gramps - + svc:grampsweb->net:gramps - - + + - + svc:grampsweb->net:traefik - - + + - - -dns:service-5.<internal-domain> - - - -service-5.<internal-domain> + + +dns:familytree.<domain> + + + +familytree.<domain> - - -dns:service-5.<internal-domain>->svc:traefik - - + + +dns:familytree.<domain>->dynu + + - + svc:influxdb->net:monitor - - + + - + svc:influxdb->net:traefik - - + + - - -dns:service-6.<internal-domain> - - - -service-6.<internal-domain> + + +dns:influxdb.<domain> + + + +influxdb.<domain> - - -dns:service-6.<internal-domain>->svc:traefik - - + + +dns:influxdb.<domain>->dynu + + - + svc:monitor-kuma->net:monitor - - + + - + svc:monitor-kuma->net:traefik - - + + - - -dns:service-7.<internal-domain> - - - -service-7.<internal-domain> + + +dns:monitor-kuma.<domain> + + + +monitor-kuma.<domain> - - -dns:service-7.<internal-domain>->svc:traefik - - + + +dns:monitor-kuma.<domain>->dynu + + - + svc:mtls-bridge->net:monitor - - + + - + svc:mtls-bridge->net:traefik - - + + - - -dns:service-8.<internal-domain> - - - -service-8.<internal-domain> + + +dns:mtls-bridge.<domain> + + + +mtls-bridge.<domain> - - -dns:service-8.<internal-domain>->svc:traefik - - + + +dns:mtls-bridge.<domain>->dynu + + - + net:nextcloud - -nextcloud + +nextcloud - + svc:nextcloud-webapp->net:nextcloud - - + + - + svc:nextcloud-webapp->net:traefik - - + + - - -dns:service-9.<internal-domain> - - - -service-9.<internal-domain> + + +dns:nextcloud.<domain> + + + +nextcloud.<domain> - - -dns:service-9.<internal-domain>->svc:traefik - - + + +dns:nextcloud.<domain>->dynu + + - + svc:node-red->net:monitor - - + + - + svc:node-red->net:traefik - - + + - - -dns:service-10.<internal-domain> - - - -service-10.<internal-domain> + + +dns:node-red.<domain> + + + +node-red.<domain> - - -dns:service-10.<internal-domain>->svc:traefik - - + + +dns:node-red.<domain>->dynu + + - + net:passbolt - -passbolt + +passbolt - + svc:passbolt-webapp->net:passbolt - - + + - + svc:passbolt-webapp->net:traefik - - + + - - -dns:service-11.<internal-domain> - - - -service-11.<internal-domain> + + +dns:passbolt.<domain> + + + +passbolt.<domain> - - -dns:service-11.<internal-domain>->svc:traefik - - + + +dns:passbolt.<domain>->dynu + + - + svc:portainer->net:traefik - - + + - - -dns:service-12.<internal-domain> - - - -service-12.<internal-domain> + + +dns:portainer.<domain> + + + +portainer.<domain> - - -dns:service-12.<internal-domain>->svc:traefik - - + + +dns:portainer.<domain>->dynu + + - + svc:prometheus->net:monitor - - + + - + svc:prometheus->net:traefik - - + + - - -dns:service-13.<internal-domain> - - - -service-13.<internal-domain> + + +dns:prometheus.<domain> + + + +prometheus.<domain> - - -dns:service-13.<internal-domain>->svc:traefik - - + + +dns:prometheus.<domain>->dynu + + - + svc:searxng-webapp->net:traefik - - + + - - -dns:service-14.<internal-domain> - - - -service-14.<internal-domain> + + +dns:searxng.<domain> + + + +searxng.<domain> - - -dns:service-14.<internal-domain>->svc:traefik - - + + +dns:searxng.<domain>->dynu + + - - -svc:shift-recorder-web->net:traefik - - - - + -dns:service-15.<internal-domain> - - - -service-15.<internal-domain> +dns:traefik.<domain> + + + +traefik.<domain> - - -dns:service-15.<internal-domain>->svc:traefik - - - - - -svc:stockfill->net:traefik - - - - - -dns:service-16.<internal-domain> - - - -service-16.<internal-domain> - - - -dns:service-16.<internal-domain>->svc:traefik - - - - - -dns:service-17.<internal-domain> - - - -service-17.<internal-domain> - - - -dns:service-17.<internal-domain>->svc:traefik - - + + +dns:traefik.<domain>->dynu + + diff --git a/docs/public/physical-topology.svg b/docs/public/physical-topology.svg index f05c23a..5f20db3 100644 --- a/docs/public/physical-topology.svg +++ b/docs/public/physical-topology.svg @@ -1,271 +1,23 @@ - - - + + PhysicalTopology - - -cluster_docker - -docker host - - -cluster_docker_apps - -apps - - -cluster_docker_automation - -automation - - -cluster_docker_edge_proxy_auth - -edge/proxy/auth - - -cluster_docker_monitoring - -monitoring - - -cluster_docker_storage_database_support - -storage/database/support - - -cluster_raspberrypi - -raspberrypi host - - -cluster_raspberrypi_apps - -apps - - -cluster_legend - -Legend - - + + -svc:crowdsec - -crowdsec - - - -svc:docker-update-exporter - -docker-update-exporter - - - -svc:error-pages - -error-pages - - - -svc:gitea - -gitea - - - -svc:gotify - -gotify - - - -svc:grampsweb - -grampsweb - - - -svc:grampsweb_celery - -grampsweb_celery - - - -svc:monitor-kuma - -monitor-kuma - - - -svc:mtls-bridge - -mtls-bridge - - - -svc:nextcloud-webapp - -nextcloud-webapp - - - -svc:node-red - -node-red - - - -svc:passbolt-webapp - -passbolt-webapp - - - -svc:portainer - -portainer - - - -svc:searxng-webapp - -searxng-webapp - - - -svc:shift-recorder-web - -shift-recorder-web - - - -svc:stockfill - -stockfill - - - -svc:telegraf - -telegraf - - - -svc:gitea-runner - -gitea-runner - - - -svc:authelia - -authelia - - - -svc:docker-socket-proxy - -docker-socket-proxy - - - -svc:traefik - -traefik - - - -svc:grafana - -grafana - - - -svc:node-exporter - -node-exporter - - - -svc:prometheus - -prometheus - - - -svc:gramps-redis - -gramps-redis - - - -svc:influxdb - -influxdb - - - -svc:nextcloud-db - -nextcloud-db - - - -svc:nextcloud-redis - -nextcloud-redis - - - -svc:passbolt-db - -passbolt-db - - - -svc:pihole-exporter - -pihole-exporter - - - -leg_host - - - - -Host cluster - - - -leg_cat - -Service category - - - -leg_host->leg_cat - - - - - -leg_svc - -Container/service - - - -leg_cat->leg_svc - - +placeholder:inventory + + + +Host inventory JSON not found. +Generate terraform inventory and rerun scripts/docs/generate-all.sh +(--host-inventory <path>). diff --git a/docs/public/stylesheets/extra.css b/docs/public/stylesheets/extra.css new file mode 100644 index 0000000..046bd6a --- /dev/null +++ b/docs/public/stylesheets/extra.css @@ -0,0 +1,23 @@ +.md-content img, article img { + max-width: 100%; + width: auto; + height: auto; +} + +.diagram-wrap { + width: 100%; + overflow-x: auto; + margin: 1rem 0 2rem; +} + +.diagram-wrap img { + max-width: none; + width: 1400px; + height: auto; +} + +@media (max-width: 900px) { + .diagram-wrap img { + width: 1200px; + } +} diff --git a/docs/public/traefik-routes.md b/docs/public/traefik-routes.md index 18734a7..072374e 100644 --- a/docs/public/traefik-routes.md +++ b/docs/public/traefik-routes.md @@ -2,22 +2,20 @@ | Service | Router | Rule | Entrypoints | TLS | Middlewares | Target Port | |---|---|---|---|---|---|---| -| authelia | authelia | Host(``) | websecure | true | | | +| authelia | authelia | Host(`auth.`) | websecure | true | | | | error-pages | error-pages-router | HostRegexp(`{host:.+}`) | web | | error-pages-middleware | | -| gitea | gitea | Host(``) | websecure | true | | 3000 | -| gotify | gotify | Host(``) | websecure | | | 80 | -| grafana | grafana | Host(``) | websecure | | | 3000 | -| grampsweb | gramps | Host(``) | websecure | | | 5000 | -| influxdb | influxdb | Host(``) | websecure | | authelia | 8086 | -| monitor-kuma | monitor | Host(``) | websecure | true | | 3001 | -| mtls-bridge | mtls-bridge | Host(``) | websecure | | mtls-bridge-auth,mtls-bridge-cors | 8080 | -| mtls-bridge | mtls-bridge-preflight | Host(``) && Method(`OPTIONS`) | websecure | | mtls-bridge-cors | | -| nextcloud-webapp | nextcloud | Host(``) | websecure | | nextcloud-dav, nextcloud-webfinger | | -| node-red | node-red | Host(``) | websecure | | authelia | 1880 | -| passbolt-webapp | passbolt | Host(``) | websecure | | | | -| portainer | portainer | Host(``) | websecure | true | | 9000 | -| prometheus | prometheus | Host(``) | websecure | | authelia | 9090 | -| searxng-webapp | searxng | Host(``) | websecure | | | 8080 | -| shift-recorder-web | shifts | Host(``) | websecure | true | | 80 | -| stockfill | stockfill | Host(``) | websecure | true | | 80 | -| traefik | traefik | Host(``) | websecure | | authelia | | +| gitea | gitea | Host(`gitea.`) | websecure | true | | 3000 | +| gotify | gotify | Host(`gotify.`) | websecure | | | 80 | +| grafana | grafana | Host(`grafana.`) | websecure | | | 3000 | +| grampsweb | gramps | Host(`familytree.`) | websecure | | | 5000 | +| influxdb | influxdb | Host(`influxdb.`) | websecure | | authelia | 8086 | +| monitor-kuma | monitor | Host(`monitor-kuma.`) | websecure | true | | 3001 | +| mtls-bridge | mtls-bridge | Host(`mtls-bridge.`) | websecure | | mtls-bridge-auth,mtls-bridge-cors | 8080 | +| mtls-bridge | mtls-bridge-preflight | Host(`mtls-bridge.`) && Method(`OPTIONS`) | websecure | | mtls-bridge-cors | | +| nextcloud-webapp | nextcloud | Host(`nextcloud.`) | websecure | | nextcloud-dav, nextcloud-webfinger | | +| node-red | node-red | Host(`node-red.`) | websecure | | authelia | 1880 | +| passbolt-webapp | passbolt | Host(`passbolt.`) | websecure | | | | +| portainer | portainer | Host(`portainer.`) | websecure | true | | 9000 | +| prometheus | prometheus | Host(`prometheus.`) | websecure | | authelia | 9090 | +| searxng-webapp | searxng | Host(`searxng.`) | websecure | | | 8080 | +| traefik | traefik | Host(`traefik.`) | websecure | | authelia | | diff --git a/mkdocs-public.yml b/mkdocs-public.yml index a9b3363..7777c25 100644 --- a/mkdocs-public.yml +++ b/mkdocs-public.yml @@ -13,6 +13,8 @@ nav: theme: name: mkdocs +extra_css: + - stylesheets/extra.css validation: nav: diff --git a/scripts/docs/generate-all.sh b/scripts/docs/generate-all.sh index 798603b..01e5489 100755 --- a/scripts/docs/generate-all.sh +++ b/scripts/docs/generate-all.sh @@ -7,5 +7,16 @@ scripts/docs/render-compose-config.sh python3 scripts/docs/generate-compose-inventory.py docs/generated/docker-compose.resolved.yml docs/generated/compose-inventory.md python3 scripts/docs/generate-traefik-routes.py docs/generated/docker-compose.resolved.yml docs/generated/traefik-routes.md python3 scripts/docs/generate-docs-index.py docs/generated/index.md -python3 scripts/docs/generate-diagrams.py --compose docs/generated/docker-compose.resolved.yml --out-dir docs/diagrams +HOST_INVENTORY="" +for p in data/terraform/proxmox-inventory.json infrastructure/terraform/proxmox/generated/infrastructure_inventory.json; do + if [[ -f "$p" ]]; then + HOST_INVENTORY="$p" + break + fi +done +DNS_INVENTORY="infrastructure/terraform/dynu/generated/dynu_dns_records_inventory.json" +GEN_ARGS=(--compose docs/generated/docker-compose.resolved.yml --out-dir docs/diagrams --domain-display redacted-label) +[[ -n "$HOST_INVENTORY" ]] && GEN_ARGS+=(--host-inventory "$HOST_INVENTORY") +[[ -f "$DNS_INVENTORY" ]] && GEN_ARGS+=(--dns-inventory "$DNS_INVENTORY") +python3 scripts/docs/generate-diagrams.py "${GEN_ARGS[@]}" python3 scripts/docs/sanitize-public-docs.py docs/generated docs/diagrams docs/public diff --git a/scripts/docs/generate-diagrams.py b/scripts/docs/generate-diagrams.py index 08af270..a2b2547 100644 --- a/scripts/docs/generate-diagrams.py +++ b/scripts/docs/generate-diagrams.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 import argparse +import json import re import subprocess import shutil @@ -23,13 +24,17 @@ def load_compose(path: Path) -> dict: return yaml.safe_load(handle) or {} -def sanitize_domain(value: str, known: dict[str, str]) -> str: - if value in known: - return known[value] +PARENT_KEYS = ("node", "node_name", "host", "physical_host", "hypervisor_host", "proxmox_node") + + +def display_domain(value: str, mode: str) -> str: + if mode == "full": + return value + if mode == "placeholder": + return "" if INTERNAL_DOMAIN_RE.search(value) else value if INTERNAL_DOMAIN_RE.search(value): - mapped = f"service-{len(known)+1}." - known[value] = mapped - return mapped + label = re.sub(r"\.lan\.ddnsgeek\.com$", "", value) + return f"{label}." return value @@ -90,51 +95,110 @@ def categorize_service(service_name: str) -> str: return "apps" -def generate_physical_topology(compose: dict, out_dot: Path, out_svg: Path) -> None: - services = compose.get("services") or {} - hosts: dict[str, dict[str, list[str]]] = {} - for name, svc in services.items(): - host = infer_host(name, svc) - cat = categorize_service(name) - hosts.setdefault(host, {}).setdefault(cat, []).append(name) +def load_inventory(path: Path | None) -> dict: + if not path or not path.exists(): + return {} + payload = json.loads(path.read_text()) + return payload.get("value", payload) if isinstance(payload, dict) else {} + + +def to_records(data) -> list[dict]: + if not isinstance(data, dict): + return [] + out = [] + for key, value in data.items(): + if isinstance(value, dict): + rec = dict(value) + rec.setdefault("_key", str(key)) + rec.setdefault("name", rec.get("hostname") or rec.get("vm_name") or str(key)) + out.append(rec) + return out + + +def parent_name(item: dict) -> str: + for k in PARENT_KEYS: + v = item.get(k) + if v: + return str(v) + return "" + + +def generate_physical_topology(compose: dict, inventory: dict, out_dot: Path, out_svg: Path) -> None: + physical = to_records(inventory.get("physical_hosts", {})) + virtual = to_records(inventory.get("virtual_hosts", {})) + to_records(inventory.get("vms", {})) + if not physical and not virtual: + lines = [ + "digraph PhysicalTopology {", + " graph [rankdir=LR, fontname=\"Helvetica\", nodesep=1.0, ranksep=1.5];", + ' "placeholder:inventory" [shape=note, style="filled", fillcolor="#fef3c7", label="Host inventory JSON not found.\\nGenerate terraform inventory and rerun scripts/docs/generate-all.sh\\n(--host-inventory )."];', + ] + lines.append("}") + write_dot(out_dot, lines) + render_svg(out_dot, out_svg) + return lines = [ "digraph PhysicalTopology {", - " graph [rankdir=LR, compound=true, splines=polyline, nodesep=0.7, ranksep=1.2, fontname=\"Helvetica\", concentrate=true];", - " node [fontname=\"Helvetica\", fontsize=10, style=\"rounded,filled\", fillcolor=\"#ffffff\"];", - " edge [fontname=\"Helvetica\", fontsize=9, color=\"#64748b\"];", + " graph [rankdir=LR, compound=true, splines=polyline, nodesep=0.95, ranksep=1.7, ratio=compress, fontname=\"Helvetica\", fontsize=13, concentrate=true, newrank=true];", + " node [fontname=\"Helvetica\", fontsize=12, style=\"rounded,filled\", fillcolor=\"#ffffff\"];", + " edge [fontname=\"Helvetica\", fontsize=10, color=\"#64748b\"];", ] - - for host, cat_map in sorted(hosts.items()): + phys_names = {str(p.get("name")): p for p in physical} + children: dict[str, list[dict]] = {k: [] for k in phys_names} + orphans: list[dict] = [] + for vm in virtual: + parent = parent_name(vm) + if parent in children: + children[parent].append(vm) + else: + orphans.append(vm) + for host, record in sorted(phys_names.items()): + host_role = str(record.get("role", "") or "") + cluster_label = f"{host}\\n{host_role}" if host_role else host lines.extend([ f' subgraph "cluster_{host}" {{', - f' label="{host} host";', + f' label="{cluster_label}";', ' style="rounded,filled";', - ' color="#93c5fd";', + ' color="#60a5fa";', ' fillcolor="#eff6ff";', + f' "phys:{host}" [label="{host}", shape=box3d, fillcolor="#bfdbfe"];', ]) - for category, svcs in sorted(cat_map.items()): - cluster_id = f"cluster_{host}_{re.sub(r'[^a-zA-Z0-9]+', '_', category)}" + for vm in sorted(children.get(host, []), key=lambda x: str(x.get("name", "")).lower()): + vm_name = str(vm.get("name")) + vm_role = str(vm.get("role", "") or "virtual host") + cluster_id = f"cluster_{host}_{re.sub(r'[^a-zA-Z0-9]+', '_', vm_name)}" lines.extend([ f' subgraph "{cluster_id}" {{', - f' label="{category}";', + f' label="{vm_name}";', ' style="rounded,dashed";', ' color="#bfdbfe";', ' fillcolor="#f8fbff";', + f' "vm:{vm_name}" [label="{vm_name}\\n{vm_role}", shape=component, fillcolor="#dcfce7"];', ]) - for service in sorted(svcs): - lines.append(f' "svc:{service}" [label="{service}", shape=box, fillcolor="#dcfce7"];') + if "docker" in vm_role.lower() or "docker" in vm_name.lower(): + lines.append(f' "role:{vm_name}" [label="Docker host", shape=box, fillcolor="#fef3c7"];') + lines.append(f' "vm:{vm_name}" -> "role:{vm_name}" [style=dashed, label="runs"];') lines.append(' }') + lines.append(f' "phys:{host}" -> "vm:{vm_name}" [label="hosts"];') lines.append(' }') + if orphans: + lines.extend([ + ' subgraph "cluster_orphans" {', + ' label="Unmapped virtual hosts"; style="rounded,dashed"; color="#d1d5db";', + ]) + for vm in sorted(orphans, key=lambda x: str(x.get("name", "")).lower()): + vm_name = str(vm.get("name")) + lines.append(f' "vm:{vm_name}" [label="{vm_name}", shape=component, fillcolor="#fee2e2"];') + lines.append(" }") lines.extend([ ' subgraph "cluster_legend" {', ' label="Legend"; style="rounded"; color="#d1d5db";', - ' "leg_host" [label="Host cluster", shape=box3d, fillcolor="#eff6ff"];', - ' "leg_cat" [label="Service category", shape=folder, fillcolor="#f8fbff"];', - ' "leg_svc" [label="Container/service", shape=box, fillcolor="#dcfce7"];', - ' "leg_host" -> "leg_cat" [style=dashed];', - ' "leg_cat" -> "leg_svc" [style=dashed];', + ' "leg_host" [label="Physical host", shape=box3d, fillcolor="#eff6ff"];', + ' "leg_vm" [label="Virtual machine", shape=component, fillcolor="#dcfce7"];', + ' "leg_role" [label="Hosted role", shape=box, fillcolor="#fef3c7"];', + ' "leg_host" -> "leg_vm" [label="hosts"];', + ' "leg_vm" -> "leg_role" [style=dashed, label="runs"];', ' }', "}", ]) @@ -142,17 +206,17 @@ def generate_physical_topology(compose: dict, out_dot: Path, out_svg: Path) -> N render_svg(out_dot, out_svg) -def generate_docker_traefik_dynu(compose: dict, out_dot: Path, out_svg: Path) -> None: +def generate_docker_traefik_dynu(compose: dict, dns_inventory: dict, domain_mode: str, out_dot: Path, out_svg: Path) -> None: services = compose.get("services") or {} networks = compose.get("networks") or {} - known_domains: dict[str, str] = {} - lines = [ "digraph DockerTraefikDynu {", - " graph [rankdir=LR, compound=true, splines=ortho, nodesep=0.7, ranksep=1.2, fontname=\"Helvetica\", concentrate=true];", - " node [fontname=\"Helvetica\", fontsize=10, style=\"rounded,filled\"];", + " graph [rankdir=LR, compound=true, splines=polyline, nodesep=0.9, ranksep=1.6, fontname=\"Helvetica\", concentrate=true, newrank=true];", + " node [fontname=\"Helvetica\", fontsize=11, style=\"rounded,filled\"];", " edge [fontname=\"Helvetica\", fontsize=9, color=\"#334155\"];", - ' "svc:traefik" [label="Traefik\n(entrypoint)", shape=box, fillcolor="#bfdbfe"];', + ' "dynu" [label="Dynu / Public DNS", shape=box, fillcolor="#fde68a"];', + ' "svc:traefik" [label="Traefik", shape=box, fillcolor="#bfdbfe"];', + ' "dynu" -> "svc:traefik" [penwidth=1.6];', ] routes: dict[str, dict] = {} @@ -182,7 +246,7 @@ def generate_docker_traefik_dynu(compose: dict, out_dot: Path, out_svg: Path) -> badges.append("authelia") if "mtls" in mw_low: badges.append("mTLS") - hosts = [sanitize_domain(h, known_domains) for h in extract_hosts(rule)] + hosts = [display_domain(h, domain_mode) for h in extract_hosts(rule)] if not hosts: continue info = routes.setdefault(svc_name, {"hosts": set(), "port": port, "badges": set()}) @@ -202,7 +266,17 @@ def generate_docker_traefik_dynu(compose: dict, out_dot: Path, out_svg: Path) -> for host in sorted(info["hosts"]): dns_nodes.add(host) lines.append(f' "dns:{host}" [label="{host}", shape=note, fillcolor="#fef3c7"];') - lines.append(f' "dns:{host}" -> "svc:traefik";') + lines.append(f' "dns:{host}" -> "dynu";') + for record in (dns_inventory.get("records", []) if isinstance(dns_inventory, dict) else []): + host = record.get("hostname") or record.get("name") + if not host: + continue + host_disp = display_domain(str(host), domain_mode) + if host_disp in dns_nodes: + continue + dns_nodes.add(host_disp) + lines.append(f' "dns:{host_disp}" [label="{host_disp}", shape=note, fillcolor="#fef3c7"];') + lines.append(f' "dns:{host_disp}" -> "dynu" [style=dashed, color=\"#94a3b8\"];') lines.append(' { rank=same; ' + '; '.join([f'"dns:{d}"' for d in sorted(dns_nodes)]) + '; }' if dns_nodes else '') @@ -256,6 +330,9 @@ def main() -> None: parser.add_argument("legacy", nargs="*") parser.add_argument("--compose") parser.add_argument("--out-dir") + parser.add_argument("--host-inventory") + parser.add_argument("--dns-inventory") + parser.add_argument("--domain-display", choices=["full", "redacted-label", "placeholder"], default="redacted-label") args = parser.parse_args() require_dot() @@ -271,9 +348,11 @@ def main() -> None: out_dir.mkdir(parents=True, exist_ok=True) compose = load_compose(compose_path) + host_inventory = load_inventory(Path(args.host_inventory)) if args.host_inventory else {} + dns_inventory = load_inventory(Path(args.dns_inventory)) if args.dns_inventory else {} - generate_docker_traefik_dynu(compose, out_dir / "docker-traefik-dynu.dot", out_dir / "docker-traefik-dynu.svg") - generate_physical_topology(compose, out_dir / "physical-topology.dot", out_dir / "physical-topology.svg") + generate_docker_traefik_dynu(compose, dns_inventory, args.domain_display, out_dir / "docker-traefik-dynu.dot", out_dir / "docker-traefik-dynu.svg") + generate_physical_topology(compose, host_inventory, out_dir / "physical-topology.dot", out_dir / "physical-topology.svg") generate_compose_topology(compose, out_dir / "docker-compose.dot", out_dir / "docker-compose.svg") diff --git a/scripts/docs/sanitize-public-docs.py b/scripts/docs/sanitize-public-docs.py index 7544fbc..c97a1c8 100644 --- a/scripts/docs/sanitize-public-docs.py +++ b/scripts/docs/sanitize-public-docs.py @@ -10,7 +10,7 @@ out_dir.mkdir(parents=True, exist_ok=True) def sanitize_text(content: str) -> str: - content = re.sub(r'\b[a-zA-Z0-9.-]+\.lan\.ddnsgeek\.com\b', '', content) + content = re.sub(r'\b([a-zA-Z0-9-]+)\.lan\.ddnsgeek\.com\b', r'\1.', content) content = re.sub( r'\b(?:10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|172\.(?:1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3})\b', '', @@ -63,7 +63,9 @@ This documentation is generated from the infrastructure repository. Sensitive va This view groups containers by inferred host and service role (edge/proxy/auth, monitoring, automation, apps, and supporting storage/services). -![Physical topology](physical-topology.svg) +
+ Physical topology +
## Docker, Traefik and Dynu routing @@ -71,6 +73,8 @@ This view shows sanitised public DNS names flowing to Traefik, then to exposed D _Diagrams are generated from Compose data and Traefik labels._ -![Docker Traefik Dynu](docker-traefik-dynu.svg) +
+ Docker Traefik Dynu +
""" )