# Home lab ```mermaid %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#333333', 'edgeLabelBackground':'#f0f0f0', 'tertiaryColor': '#e67e22'}}}%% graph LR %% Styles classDef internet fill:#f9f9f9,stroke:#999,color:#333,font-size:12px; classDef arcodange fill:#e6e6e6,stroke:#555,color:#333,font-size:12px; classDef cluster fill:#d4d4d4,stroke:#777,color:#333,font-size:12px; %% Internet subgraph "Internet / Le monde" direction TB DuckDNS["🌐 DuckDNS
(duckdns.org)"]:::internet GoogleCloud["☁️ Google Cloud
(cloud.google.com)"]:::internet Cloudflare["πŸ›‘οΈ Cloudflare
(cloudflare.com)"]:::internet OVHcloud["πŸ–₯️ OVHcloud
(ovhcloud.com)"]:::internet Zoho["πŸ“§ Zoho
(zoho.eu)"]:::internet CrowdSec["πŸ”’ CrowdSec
(crowdsec.net)"]:::internet end %% Bureaux Arcodange subgraph "Bureaux Arcodange" direction TB Livebox["πŸ“‘ Livebox
(gateway)"]:::arcodange MacBook["πŸ’» MacBook Pro M4"]:::arcodange subgraph "Cluster Raspberry Pi" direction LR Pi1["🐧 pi1"]:::cluster Pi2["🐧 pi2"]:::cluster Pi3["🐧 pi3"]:::cluster end end ``` ## Network ```mermaid %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#333333', 'edgeLabelBackground':'#f0f0f0', 'tertiaryColor': '#e67e22'}}}%% graph LR %% Styles classDef internet fill:#f9f9f9,stroke:#999,color:#333,font-size:12px; classDef arcodange fill:#e6e6e6,stroke:#555,color:#333,font-size:12px; classDef k3sServer fill:#ff9999,stroke:#cc0000,color:#333,font-size:12px; classDef k3sAgent fill:#99ff99,stroke:#00cc00,color:#333,font-size:12px; classDef traefik fill:#9999ff,stroke:#0000cc,color:#333,font-size:12px; classDef dns fill:#ffff99,stroke:#cccc00,color:#333,font-size:12px; classDef cloudflared fill:#ccccff,stroke:#6666cc,color:#333,font-size:12px; %% Internet subgraph "Internet / Le monde" direction TB DuckDNS["🌐 DuckDNS
(duckdns.org)"]:::internet subgraph "Cloudflare" CloudflareService["πŸ›‘οΈ Cloudflare
(cloudflare.com)"]:::internet DNSNote@{ shape: text, label: "redirige *.arcodange.fr
β†’ Cloudflared Tunnel" } end end %% Bureaux Arcodange subgraph "Bureaux Arcodange" direction TB Livebox["πŸ“‘ Livebox
(passerelle)"]:::arcodange MacBook["πŸ’» MacBook Pro M4"]:::arcodange %% Cluster Raspberry Pi subgraph "Cluster Raspberry Pi" direction LR %% Noeud pi1 subgraph "pi1" Pi1["🐧 pi1"]:::k3sServer subgraph "K3s (Server)" Traefik["πŸš€ Traefik"]:::traefik Cloudflared["☁️ Cloudflared Tunnel"]:::cloudflared end PiHole1["🧹 Pi-hole"]:::dns NS1@{ shape: text, label: "nameserver : pi3" } DNSArcodange@{ shape: text, label: ".arcodange.lab
β†’ Traefik", color:#cccc00 } end %% Noeud pi2 subgraph "pi2" Pi2["🐧 pi2"]:::k3sAgent end %% Noeud pi3 subgraph "pi3" Pi3["🐧 pi3"]:::k3sAgent PiHole3["🧹 Pi-hole"]:::dns NS3@{ shape: text, label: "nameserver : pi1" } end end end %% Connexions %% Pi-hole β†’ Livebox (DNS) PiHole1 -.->|DNS| Livebox PiHole3 -.->|DNS| Livebox %% Cloudflare β†’ Cloudflared Tunnel β†’ Traefik CloudflareService -.-> Cloudflared Cloudflared --> Traefik %% Livebox β†’ Traefik (HTTPS) Livebox -->|redirige HTTPS| Traefik ``` ## with Gitea ```mermaid %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#333333', 'edgeLabelBackground':'#f0f0f0', 'tertiaryColor': '#e67e22'}}}%% graph LR %% Styles classDef internet fill:#f9f9f9,stroke:#999,color:#333,font-size:12px; classDef arcodange fill:#e6e6e6,stroke:#555,color:#333,font-size:12px; classDef k3sServer fill:#ff9999,stroke:#cc0000,color:#333,font-size:12px; classDef k3sAgent fill:#99ff99,stroke:#00cc00,color:#333,font-size:12px; classDef traefik fill:#9999ff,stroke:#0000cc,color:#333,font-size:12px; classDef dns fill:#ffff99,stroke:#cccc00,color:#333,font-size:12px; classDef cloudflared fill:#ccccff,stroke:#6666cc,color:#333,font-size:12px; classDef gitea fill:#ffcc99,stroke:#cc9966,color:#333,font-size:12px; classDef cms fill:#99ffcc,stroke:#66cc99,color:#333,font-size:12px; classDef domainFR fill:#99ccff,stroke:#0066cc,color:#333,font-size:12px; classDef domainLAB fill:#ccff99,stroke:#66cc66,color:#333,font-size:12px; %% Internet subgraph "Internet / Le monde" direction TB DuckDNS["🌐 DuckDNS
(duckdns.org)"]:::internet subgraph "Cloudflare" CloudflareService["πŸ›‘οΈ Cloudflare
(cloudflare.com)"]:::internet DNSNote@{ shape: text, label: "redirige *.arcodange.fr
β†’ Cloudflared Tunnel" } end end %% Bureaux Arcodange subgraph "Bureaux Arcodange" direction TB Livebox["πŸ“‘ Livebox
(passerelle)"]:::arcodange MacBook["πŸ’» MacBook Pro M4"]:::arcodange %% Cluster Raspberry Pi subgraph "Cluster Raspberry Pi" direction LR %% Noeud pi1 subgraph "pi1" Pi1["🐧 pi1"]:::k3sServer subgraph "K3s (Server)" Traefik["πŸš€ Traefik"]:::traefik Cloudflared["☁️ Cloudflared Tunnel"]:::cloudflared end PiHole1["🧹 Pi-hole"]:::dns GiteaRunner1["πŸƒ Gitea Act Runner"]:::gitea NS1@{ shape: text, label: "nameserver : pi3" } DNSArcodange@{ shape: text, label: ".arcodange.lab
β†’ Traefik", color:#cccc00 } end %% Noeud pi2 subgraph "pi2" Pi2["🐧 pi2"]:::k3sAgent Gitea["🦊 Gitea"]:::gitea subgraph "K3s (Agent)" CMS["πŸ“ CMS"]:::cms end end %% Noeud pi3 subgraph "pi3" Pi3["🐧 pi3"]:::k3sAgent PiHole3["🧹 Pi-hole"]:::dns GiteaRunner3["πŸƒ Gitea Act Runner"]:::gitea NS3@{ shape: text, label: "nameserver : pi1" } end end end %% Connexions Pi-hole β†’ Livebox (DNS) PiHole1 -.->|DNS| Livebox PiHole3 -.->|DNS| Livebox %% Cloudflare β†’ Cloudflared Tunnel β†’ Traefik CloudflareService -.-> Cloudflared Cloudflared --> Traefik %% Livebox β†’ Traefik (HTTPS) Livebox -->|redirige HTTPS| Traefik %% Gitea Act Runner β†’ Gitea GiteaRunner1 -.->|communication| Gitea GiteaRunner3 -.->|communication| Gitea %% Domains β†’ CMS via Traefik Traefik -->|cms-rec.arcodange.fr| CMS:::domainFR Traefik -->|www.arcodange.lab| CMS:::domainLAB ``` ### with security ```mermaid %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#333333', 'edgeLabelBackground':'#f0f0f0', 'tertiaryColor': '#05e2ff1c'}}}%% graph LR %% Styles classDef internet fill:#f9f9f9,stroke:#999,color:#333,font-size:12px; classDef arcodange fill:#e6e6e6,stroke:#555,color:#333,font-size:12px; classDef k3sServer fill:#ff9999,stroke:#cc0000,color:#333,font-size:12px; classDef k3sAgent fill:#99ff99,stroke:#00cc00,color:#333,font-size:12px; classDef traefik fill:#9999ff,stroke:#0000cc,color:#333,font-size:12px; classDef dns fill:#ffff99,stroke:#cccc00,color:#333,font-size:12px; classDef cloudflared fill:#ccccff,stroke:#6666cc,color:#333,font-size:12px; classDef gitea fill:#ffcc99,stroke:#cc9966,color:#333,font-size:12px; classDef cms fill:#99ffcc,stroke:#66cc99,color:#333,font-size:12px; classDef domainFR fill:#99ccff,stroke:#0066cc,color:#333,font-size:12px; classDef domainLAB fill:#ccff99,stroke:#66cc66,color:#333,font-size:12px; classDef crowdsec fill:#ff99cc,stroke:#cc6699,color:#333,font-size:12px; classDef security fill:#ffcccc,stroke:#cc9999,color:#333,font-size:12px; %% Internet subgraph "Internet / Le monde" direction TB subgraph "Cloudflare" CloudflareService["πŸ›‘οΈ Cloudflare
(cloudflare.com)"]:::internet DNSNote@{ shape: text, label: "redirige *.arcodange.fr
β†’ Cloudflared Tunnel" } end end %% Bureaux Arcodange subgraph "Bureaux Arcodange" direction TB Livebox["πŸ“‘ Livebox
(passerelle)"]:::arcodange DNSArcodange@{ shape: text, label: ".arcodange.lab
β†’ Traefik" } %% Cluster Raspberry Pi subgraph "Cluster Raspberry Pi" direction LR %% Noeud pi1 subgraph "pi1" Pi1["🐧 pi1"]:::k3sServer subgraph "K3s (Server)" Traefik["πŸš€ Traefik"]:::traefik Cloudflared["☁️ Cloudflared Tunnel"]:::cloudflared end PiHole1["🧹 Pi-hole"]:::dns GiteaRunner1["πŸƒ Gitea Act Runner"]:::gitea NS1@{ shape: text, label: "nameserver : pi3" } end %% Noeud pi2 subgraph "pi2" Pi2["🐧 pi2"]:::k3sAgent Gitea["🦊 Gitea"]:::gitea subgraph "K3s (Agent)" CMS["πŸ“ CMS"]:::cms end end %% Noeud pi3 subgraph "pi3" Pi3["🐧 pi3"]:::k3sAgent PiHole3["🧹 Pi-hole"]:::dns GiteaRunner3["πŸƒ Gitea Act Runner"]:::gitea subgraph "K3s (Agent)" CrowdSec["πŸ”’ CrowdSec"]:::crowdsec end NS3@{ shape: text, label: "nameserver : pi1" } end end %% SΓ©curitΓ© combinΓ©e subgraph "SΓ©curitΓ©" Turnstile["πŸ›‘οΈ Cloudflared Turnstile
(CAPTCHA)"]:::security BannedIPs["🚫 CrowdSec
(IP bannies)"]:::security end end %% Connexions Pi-hole β†’ Livebox (DNS) PiHole1 -.->|DNS| Livebox PiHole3 -.->|DNS| Livebox %% Internet β†’ Livebox CloudflareService --> Livebox %% Gitea Act Runner β†’ Gitea GiteaRunner1 -.->|communication| Gitea GiteaRunner3 -.->|communication| Gitea %% Cloudflare β†’ Cloudflared Tunnel β†’ SΓ©curitΓ© β†’ Traefik CloudflareService -.-> Cloudflared Cloudflared --> Turnstile Turnstile --> BannedIPs BannedIPs --> Traefik %% Livebox β†’ SΓ©curitΓ© β†’ Traefik Livebox --> Turnstile %% Domaines β†’ Gitea/CMS via Traefik Traefik -->|gitea.arcodange.fr| Gitea:::domainFR Traefik -->|gitea.arcodange.lab| Gitea:::domainLAB Traefik -->|cms-rec.arcodange.fr| CMS:::domainFR Traefik -->|www.arcodange.lab| CMS:::domainLAB ``` ## CI/CD Architecture ```mermaid %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#333333', 'edgeLabelBackground':'#f0f0f0', 'tertiaryColor': '#e67e22'}}}%% graph TD %% Styles classDef gitea fill:#ffcc99,stroke:#cc9966,color:#333; classDef argocd fill:#99ffcc,stroke:#66cc99,color:#333; classDef vault fill:#ccccff,stroke:#6666cc,color:#333; classDef k3s fill:#ff9999,stroke:#cc0000,color:#333; classDef runner fill:#ffff99,stroke:#cccc00,color:#333; %% Components Gitea["Gitea (pi2)"]:::gitea ArgoCD["ArgoCD (k3s)"]:::argocd Vault["Vault (k3s/tools)"]:::vault Runner1["Gitea Act Runner (pi1)"]:::runner Runner2["Gitea Act Runner (pi3)"]:::runner VaultOperator["Vault Secrets Operator (k3s/tools)"]:::vault k3s["k3s Cluster"]:::k3s WebApp["WebApp (k3s)"]:::k3s %% Workflow Gitea -->|OIDC Auth| Vault Gitea -->|Trigger CI| Runner1 Gitea -->|Trigger CI| Runner2 Runner1 -->|Deploy to| k3s Runner2 -->|Deploy to| k3s ArgoCD -->|GitOps Sync| Gitea ArgoCD -->|Deploy Apps| k3s VaultOperator -->|Inject Secrets| WebApp Vault -->|Secrets| VaultOperator WebApp -->|Uses| VaultOperator %% Annotations linkStyle 0,1,2,3,4,5,6,7 stroke:#999,stroke-width:1px; %% Notes note1["Custom runner image includes
.lab CA cert"] Runner1 --> note1 Runner2 --> note1 %% OIDC Workflow note2["OIDC Flow:
1. Runner executes vault_oauth__sh_b64
2. Obtains ID token from Gitea
3. Authenticates with Vault"] Runner1 --> note2 Runner2 --> note2 ```