# 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
```