# ๐Ÿ—๏ธ Service Architecture ## Overview This document shows how the 176+ Docker services interact, their dependencies, and the data flows between them. --- ## ๐ŸŽฌ Media Stack Architecture (Mermaid) ```mermaid graph TB subgraph Internet["โ˜๏ธ Internet Sources"] USENET["Usenet
Providers"] TORRENT["Torrent
Trackers"] INDEXERS["Indexers
(NZB/Torrent)"] end subgraph Acquisition["๐Ÿ“ฅ Content Acquisition (Atlantis)"] PROWLARR["Prowlarr
Indexer Manager"] SONARR["Sonarr
TV Shows"] RADARR["Radarr
Movies"] LIDARR["Lidarr
Music"] READARR["Readarr
Books"] BAZARR["Bazarr
Subtitles"] SAB["SABnzbd
Usenet Client"] QBIT["qBittorrent
Torrent Client"] end subgraph Storage["๐Ÿ’พ Storage (Atlantis NAS)"] MEDIA_TV["/volume1/media/tv"] MEDIA_MOV["/volume1/media/movies"] MEDIA_MUS["/volume1/media/music"] MEDIA_BOOK["/volume1/media/books"] end subgraph Streaming["๐Ÿ“บ Media Streaming"] PLEX["Plex
Media Server"] JELLYFIN["Jellyfin
Media Server"] NAVIDROME["Navidrome
Music Server"] TAUTULLI["Tautulli
Plex Analytics"] end subgraph Clients["๐Ÿ“ฑ Client Devices"] TV["Smart TVs"] PHONE["Phones/Tablets"] WEB["Web Browsers"] APPS["Desktop Apps"] end %% Acquisition flow INDEXERS --> PROWLARR PROWLARR --> SONARR & RADARR & LIDARR & READARR SONARR --> SAB & QBIT RADARR --> SAB & QBIT LIDARR --> SAB & QBIT READARR --> SAB & QBIT USENET --> SAB TORRENT --> QBIT %% Storage flow SAB --> MEDIA_TV & MEDIA_MOV & MEDIA_MUS & MEDIA_BOOK QBIT --> MEDIA_TV & MEDIA_MOV & MEDIA_MUS & MEDIA_BOOK BAZARR --> MEDIA_TV & MEDIA_MOV %% Streaming flow MEDIA_TV & MEDIA_MOV --> PLEX & JELLYFIN MEDIA_MUS --> NAVIDROME PLEX --> TAUTULLI %% Client access PLEX & JELLYFIN & NAVIDROME --> TV & PHONE & WEB & APPS classDef acquisition fill:#e74c3c,stroke:#333,stroke-width:2px,color:#fff classDef storage fill:#3498db,stroke:#333,stroke-width:2px,color:#fff classDef streaming fill:#2ecc71,stroke:#333,stroke-width:2px,color:#fff classDef client fill:#9b59b6,stroke:#333,stroke-width:2px,color:#fff class PROWLARR,SONARR,RADARR,LIDARR,READARR,BAZARR,SAB,QBIT acquisition class MEDIA_TV,MEDIA_MOV,MEDIA_MUS,MEDIA_BOOK storage class PLEX,JELLYFIN,NAVIDROME,TAUTULLI streaming class TV,PHONE,WEB,APPS client ``` --- ## ๐Ÿ“Š Monitoring Stack Architecture ```mermaid graph TB subgraph Targets["๐ŸŽฏ Monitored Targets"] subgraph Synology["Synology NAS"] ATL_SNMP["Atlantis
SNMP"] CAL_SNMP["Calypso
SNMP"] SET_SNMP["Setillo
SNMP"] end subgraph Hosts["Linux Hosts"] NODE1["Homelab VM
node_exporter"] NODE2["Guava
node_exporter"] NODE3["Anubis
node_exporter"] end subgraph Containers["Containers"] CADV["cAdvisor
Container Metrics"] end subgraph Network["Network"] BLACK["Blackbox Exporter
HTTP/ICMP Probes"] end end subgraph Collection["๐Ÿ“ฅ Metric Collection (Homelab VM)"] PROM["Prometheus
Time Series DB"] SNMP_EXP["SNMP Exporter"] end subgraph Visualization["๐Ÿ“ˆ Visualization"] GRAFANA["Grafana
Dashboards"] end subgraph Alerting["๐Ÿšจ Alerting"] ALERTMGR["Alertmanager"] NTFY["ntfy
Push Notifications"] UPTIME["Uptime Kuma
Status Page"] end %% Collection ATL_SNMP & CAL_SNMP & SET_SNMP --> SNMP_EXP SNMP_EXP --> PROM NODE1 & NODE2 & NODE3 --> PROM CADV --> PROM BLACK --> PROM %% Visualization PROM --> GRAFANA PROM --> ALERTMGR ALERTMGR --> NTFY %% Uptime Kuma separate BLACK -.-> UPTIME classDef target fill:#e67e22,stroke:#333,stroke-width:2px,color:#fff classDef collection fill:#3498db,stroke:#333,stroke-width:2px,color:#fff classDef viz fill:#2ecc71,stroke:#333,stroke-width:2px,color:#fff classDef alert fill:#e74c3c,stroke:#333,stroke-width:2px,color:#fff class ATL_SNMP,CAL_SNMP,SET_SNMP,NODE1,NODE2,NODE3,CADV,BLACK target class PROM,SNMP_EXP collection class GRAFANA viz class ALERTMGR,NTFY,UPTIME alert ``` --- ## ๐Ÿ” Authentication & Security Stack ### Complete Authentication Architecture ```mermaid graph TB subgraph External["๐ŸŒ External Access"] USERS["๐Ÿ‘ค Users"] CLOUDFLARE["โ˜๏ธ Cloudflare
DNS/WAF/DDoS"] end subgraph Gateway["๐Ÿšช Gateway Layer (Atlantis)"] NPM["๐Ÿ”€ Nginx Proxy Manager
:81/:443
Reverse Proxy + SSL"] CFT["๐Ÿš‡ Cloudflare Tunnel
Zero Trust Access"] end subgraph AuthLayer["๐Ÿ” Authentication Layer (Calypso)"] AUTH_SRV["๐Ÿ” Authentik Server
:9000"] AUTH_PROXY["๐Ÿ›ก๏ธ Authentik Outpost
:9444
Forward Auth Proxy"] AUTH_WRK["โš™๏ธ Authentik Worker"] AUTH_DB["๐Ÿ˜ PostgreSQL"] AUTH_RED["๐Ÿ”ด Redis"] end subgraph VPN["๐Ÿ”’ VPN Layer"] WIREGUARD["๐Ÿ”’ Wireguard
Atlantis :51820"] TAILSCALE["๐Ÿ”ท Tailscale
100.x.x.x"] HEADSCALE["๐ŸŒ Headscale
Calypso :8080"] end subgraph DNS["๐ŸŒ DNS & Ad Blocking"] PIHOLE["๐Ÿ•ณ๏ธ Pi-hole
Atlantis :53"] ADGUARD1["๐Ÿ›ก๏ธ AdGuard
Calypso :53"] ADGUARD2["๐Ÿ›ก๏ธ AdGuard
Setillo :53"] end subgraph SecVault["๐Ÿ”‘ Secrets Management"] VAULT["๐Ÿ”‘ Vaultwarden
vault.vish.gg"] end subgraph ProtectedServices["๐Ÿ›ก๏ธ Protected Services"] GRAFANA["๐Ÿ“Š Grafana"] PAPERLESS["๐Ÿ“„ Paperless"] IMMICH["๐Ÿ“ธ Immich"] FIREFLY["๐Ÿ”ฅ Firefly III"] ACTUAL["๐Ÿ’ฐ Actual Budget"] GITEA["๐Ÿ”ง Gitea"] end subgraph PublicServices["๐ŸŒ Public/Self-Auth Services"] PLEX["๐Ÿ“บ Plex"] SEAFILE["โ˜๏ธ Seafile"] OST["๐Ÿš€ OpenSpeedTest"] NTFY["๐Ÿ“ฃ ntfy"] end %% External flow USERS --> CLOUDFLARE CLOUDFLARE --> NPM CLOUDFLARE --> CFT USERS --> TAILSCALE %% NPM to Auth NPM -->|"Forward Auth
Header Check"| AUTH_PROXY AUTH_PROXY -->|"Validate Session"| AUTH_SRV %% Auth internal AUTH_SRV --> AUTH_DB AUTH_SRV --> AUTH_RED AUTH_WRK --> AUTH_DB AUTH_WRK --> AUTH_RED %% Protected services via NPM + Auth NPM -->|"โœ“ Authenticated"| ProtectedServices %% Public services direct NPM --> PublicServices %% VPN access TAILSCALE --> HEADSCALE WIREGUARD --> ProtectedServices TAILSCALE --> ProtectedServices %% DNS ADGUARD1 -.-> ProtectedServices PIHOLE -.-> PublicServices classDef external fill:#e74c3c,stroke:#333,stroke-width:2px,color:#fff classDef gateway fill:#f39c12,stroke:#333,stroke-width:2px,color:#fff classDef auth fill:#9b59b6,stroke:#333,stroke-width:2px,color:#fff classDef dns fill:#1abc9c,stroke:#333,stroke-width:2px,color:#fff classDef protected fill:#3498db,stroke:#333,stroke-width:2px,color:#fff classDef public fill:#27ae60,stroke:#333,stroke-width:2px,color:#fff class USERS,CLOUDFLARE external class NPM,CFT gateway class AUTH_SRV,AUTH_PROXY,AUTH_WRK,AUTH_DB,AUTH_RED,VAULT auth class PIHOLE,ADGUARD1,ADGUARD2 dns class GRAFANA,PAPERLESS,IMMICH,FIREFLY,ACTUAL,GITEA protected class PLEX,SEAFILE,OST,NTFY public ``` --- ### Authentik SSO Flow (Detailed) ```mermaid sequenceDiagram autonumber participant U as ๐Ÿ‘ค User participant CF as โ˜๏ธ Cloudflare participant NPM as ๐Ÿ”€ NPM (Atlantis) participant OUT as ๐Ÿ›ก๏ธ Outpost (Calypso) participant AUTH as ๐Ÿ” Authentik (Calypso) participant APP as ๐Ÿ“ฑ Application U->>CF: Request app.vish.gg CF->>NPM: Forward (HTTPS) NPM->>OUT: Forward Auth Request
(/outpost.goauthentik.io/auth/nginx) alt No Valid Session OUT->>AUTH: Check Session AUTH-->>OUT: No Session OUT-->>NPM: 401 Unauthorized NPM-->>U: Redirect to sso.vish.gg/flows/default-authentication/ U->>AUTH: Login Page U->>AUTH: Submit Credentials + 2FA AUTH->>AUTH: Validate AUTH-->>U: Set Cookie + Redirect to app U->>NPM: Retry with Session Cookie NPM->>OUT: Forward Auth (with cookie) end OUT->>AUTH: Validate Session AUTH-->>OUT: Valid โœ“ OUT-->>NPM: 200 OK + Headers
(X-authentik-username, X-authentik-email) NPM->>APP: Proxy Request (with auth headers) APP-->>U: Response ``` --- ### NPM Proxy Host Configuration ```mermaid graph TB subgraph NPM["๐Ÿ”€ Nginx Proxy Manager (Atlantis :81)"] subgraph ProxyHosts["Proxy Hosts"] PH1["sso.vish.gg โ†’ Calypso:9000"] PH2["git.vish.gg โ†’ Calypso:3000"] PH3["docs.vish.gg โ†’ Atlantis:8088"] PH4["photos.vish.gg โ†’ Calypso:2283"] PH5["gf.vish.gg โ†’ Atlantis:3000"] PH6["actual.vish.gg โ†’ Calypso:5006"] PH7["ff.vish.gg โ†’ Calypso:8888"] PH8["plex.vish.gg โ†’ Atlantis:32400"] PH9["sf.vish.gg โ†’ Calypso:8092"] PH10["ntfy.vish.gg โ†’ Homelab:7080"] PH11["rackula.vish.gg โ†’ Calypso:4999"] end subgraph SSL["SSL Certificates"] WILD["*.vish.gg
Cloudflare DNS Challenge"] end subgraph AccessControl["Access Control"] AUTH_LOC["Authentik Forward Auth
Location: /outpost.goauthentik.io"] end end subgraph Services["Backend Services"] direction LR S1["Authentik"] S2["Gitea"] S3["Paperless"] S4["Immich"] S5["Grafana"] S6["Actual"] S7["Firefly"] S8["Plex"] S9["Seafile"] S10["ntfy"] S11["Rackula"] end PH1 --> S1 PH2 --> S2 PH3 --> S3 PH4 --> S4 PH5 --> S5 PH6 --> S6 PH7 --> S7 PH8 --> S8 PH9 --> S9 PH10 --> S10 PH11 --> S11 ``` --- ### Services Protected by Authentik | Domain | Service | Host | Auth Type | Notes | |--------|---------|------|-----------|-------| | `sso.vish.gg` | Authentik | Calypso | - | Identity Provider | | `git.vish.gg` | Gitea | Calypso | OAuth2/OIDC | Source Control | | `gf.vish.gg` | Grafana | Atlantis | OAuth2/OIDC | Monitoring | | `docs.vish.gg` | Paperless-NGX | Atlantis | Forward Auth | Documents | | `photos.vish.gg` | Immich | Calypso | Forward Auth | Photos | | `actual.vish.gg` | Actual Budget | Calypso | Forward Auth | Finance | | `ff.vish.gg` | Firefly III | Calypso | Forward Auth | Finance | | `rackula.vish.gg` | Rackula | Calypso | Forward Auth | Rack Diagram | ### Services NOT Protected (Public/Self-Auth) | Domain | Service | Host | Reason | |--------|---------|------|--------| | `plex.vish.gg` | Plex | Atlantis | Has Plex Auth | | `sf.vish.gg` | Seafile | Calypso | Has built-in auth + share links | | `ntfy.vish.gg` | ntfy | Homelab | Has built-in auth + public topics | | `ost.vish.gg` | OpenSpeedTest | Calypso | Public utility | --- ### Authentik Forward Auth Setup (NPM) To protect a service with Authentik Forward Auth in NPM: 1. **Create Provider in Authentik**: - Type: Proxy Provider - External Host: `https://app.vish.gg` - Mode: Forward auth (single application) 2. **Create Application in Authentik**: - Link to the provider - Set policies for access control 3. **Create Outpost in Authentik**: - Type: Proxy - Include the application 4. **Configure NPM Proxy Host**: ```nginx # Custom Nginx Configuration (Advanced tab) # Authentik Forward Auth location /outpost.goauthentik.io { proxy_pass http://calypso.vish.local:9444/outpost.goauthentik.io; proxy_set_header Host $host; proxy_set_header X-Original-URL $scheme://$http_host$request_uri; add_header Set-Cookie $auth_cookie; auth_request_set $auth_cookie $upstream_http_set_cookie; proxy_pass_request_body off; proxy_set_header Content-Length ""; } location / { auth_request /outpost.goauthentik.io/auth/nginx; error_page 401 = @goauthentik_proxy_signin; auth_request_set $auth_cookie $upstream_http_set_cookie; add_header Set-Cookie $auth_cookie; # Forward auth headers to application auth_request_set $authentik_username $upstream_http_x_authentik_username; auth_request_set $authentik_email $upstream_http_x_authentik_email; proxy_set_header X-authentik-username $authentik_username; proxy_set_header X-authentik-email $authentik_email; proxy_pass http://backend; } location @goauthentik_proxy_signin { internal; add_header Set-Cookie $auth_cookie; return 302 /outpost.goauthentik.io/start?rd=$request_uri; } ``` --- ## ๐Ÿ“ ASCII Service Distribution by Host ``` โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•— โ•‘ SERVICE DISTRIBUTION BY HOST โ•‘ โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ ๐Ÿ›๏ธ ATLANTIS (55 Services) - Primary Hub โ”‚ โ”‚ โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ”‚ โ”‚ โ”‚ โ”‚ ๐Ÿ“บ Media ๐Ÿ“Š Monitoring ๐Ÿ” Security ๐Ÿ› ๏ธ Infrastructure โ”‚ โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”‚ โ€ข Plex โ€ข Grafana โ€ข Vaultwarden โ€ข Portainer โ”‚ โ”‚ โ€ข Jellyfin โ€ข Prometheus โ€ข Wireguard โ€ข Nginx Proxy Mgr โ”‚ โ”‚ โ€ข Immich โ€ข Uptime Kuma โ€ข Pi-hole โ€ข DokuWiki โ”‚ โ”‚ โ€ข Tautulli โ€ข SNMP Exporter โ€ข Dozzle โ”‚ โ”‚ โ€ข Arr Suite (7) โ€ข Blackbox Exp โ€ข Watchtower โ”‚ โ”‚ โ€ข Navidrome โ”‚ โ”‚ โ”‚ โ”‚ ๐Ÿ’ฌ Communication ๐Ÿ“ Productivity ๐ŸŽฎ Other โ”‚ โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”‚ โ€ข Matrix Synapse โ€ข Paperless-NGX โ€ข IT-Tools โ”‚ โ”‚ โ€ข Mastodon โ€ข Firefly III โ€ข Stirling PDF โ”‚ โ”‚ โ€ข Joplin Server โ€ข Documenso โ€ข YouTube DL โ”‚ โ”‚ โ€ข Netbox โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ ๐Ÿข CALYPSO (17 Services) - Development & Backup โ”‚ โ”‚ โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ”‚ โ”‚ โ”‚ โ”‚ ๐Ÿ’ป Development ๐Ÿ’ฐ Finance ๐Ÿ“ฆ Infrastructure ๐Ÿ“ธ Media โ”‚ โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”‚ โ€ข Gitea โ€ข Firefly III โ€ข APT-Cacher-NG โ€ข Immich (backup) โ”‚ โ”‚ โ€ข Reactive Resume โ€ข Actual Budget โ€ข Prometheus โ€ข Seafile โ”‚ โ”‚ โ€ข Rustdesk โ€ข Wireguard โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ ๐Ÿ’ป HOMELAB VM (36 Services) - Experimentation โ”‚ โ”‚ โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ”‚ โ”‚ โ”‚ โ”‚ ๐Ÿ”— URL Services ๐ŸŽฎ Gaming ๐Ÿ“Š Monitoring ๐Ÿ”ง Utilities โ”‚ โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”‚ โ€ข Shlink โ€ข Satisfactory โ€ข Prometheus Hub โ€ข Archivebox โ”‚ โ”‚ โ€ข ntfy โ€ข Minecraft โ€ข node_exporter โ€ข WebCheck โ”‚ โ”‚ โ€ข Hoarder โ€ข L4D2 โ€ข Redlib โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ ๐ŸŒ CONCORD NUC (9 Services) - Edge/IoT โ”‚ โ”‚ โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ”‚ โ”‚ โ”‚ โ”‚ ๐Ÿ  Home Automation ๐Ÿ“บ Media ๐ŸŽต Music ๐Ÿ”ง Network โ”‚ โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”‚ โ€ข Home Assistant โ€ข Plex โ€ข YourSpotify โ€ข AdGuard Home โ”‚ โ”‚ โ€ข Matter Server โ€ข Invidious โ€ข Piped โ€ข Wireguard โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ ๐Ÿค– ANUBIS (8 Services) - AI/HPC (Mac Mini Ubuntu) โ”‚ โ”‚ โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ”‚ โ”‚ โ”‚ โ”‚ ๐Ÿง  AI/ML ๐Ÿ“ธ Photo ๐Ÿ”ง Development โ”‚ โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”‚ โ€ข Ollama โ€ข PhotoPrism โ€ข Draw.io โ”‚ โ”‚ โ€ข ChatGPT UI โ€ข Archivebox โ€ข Element Web โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ ๐ŸŒต SETILLO (4 Services) - Tucson Remote โ”‚ โ”‚ โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ”‚ โ”‚ โ”‚ โ”‚ ๐Ÿ“Š Monitoring ๐ŸŒ DNS โ”‚ โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”‚ โ€ข Prometheus โ€ข AdGuard Home โ”‚ โ”‚ โ€ข SNMP Exporter โ€ข Syncthing โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•— โ•‘ SERVICE COUNT SUMMARY โ•‘ โ•‘ โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•‘ โ•‘ Atlantis: 55 services โ”‚ Calypso: 17 services โ•‘ โ•‘ Homelab VM: 36 services โ”‚ Chicago VM: 8 services โ•‘ โ•‘ Bulgaria VM: 12 services โ”‚ Concord NUC: 9 services โ•‘ โ•‘ Anubis: 8 services โ”‚ Guava: 6 services โ•‘ โ•‘ Setillo: 4 services โ”‚ RPi nodes: 2 services โ•‘ โ•‘ Contabo: 1 service โ”‚ โ•‘ โ•‘ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•‘ โ•‘ TOTAL: 176+ services across 13 hosts โ•‘ โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• ``` --- ## ๐Ÿ”— Related Diagrams - [Network Topology](network-topology.md) - How hosts connect - [Storage Topology](storage-topology.md) - Where data lives - [Tailscale Mesh](tailscale-mesh.md) - Cross-location access --- ## ๐Ÿ’ฌ Communication Stack Architecture ```mermaid graph TB subgraph Internet["โ˜๏ธ Internet / Federation"] FEDI["Fediverse
(ActivityPub)"] MATRIX_FED["Matrix
Federation"] WEBRTC["WebRTC
Voice/Video"] end subgraph Cloudflare["๐Ÿ›ก๏ธ Cloudflare"] CF_PROXY["Cloudflare
Proxy/WAF"] CF_TUNNEL["Cloudflare
Tunnel"] end subgraph MatrixUbuntuVM["๐Ÿง Matrix-Ubuntu VM (Atlantis)"] subgraph Mastodon["๐Ÿ˜ Mastodon Stack"] MASTO_WEB["Mastodon Web
:3000"] MASTO_STREAM["Mastodon Streaming
:4000"] MASTO_SIDEKIQ["Sidekiq
Background Jobs"] end subgraph Matrix["๐Ÿ” Matrix Stack"] SYNAPSE["Synapse
:8008 / :8018"] ELEMENT["Element Web
Client"] COTURN["Coturn
TURN Server
:3478"] end subgraph Mattermost["๐Ÿ’ฌ Mattermost"] MM_APP["Mattermost
:8065"] end subgraph SharedDB["๐Ÿ—„๏ธ Shared Services"] POSTGRES["PostgreSQL
:5432"] REDIS["Redis
:6379"] end NGINX_VM["Nginx
Reverse Proxy"] end subgraph Atlantis["๐Ÿ›๏ธ Atlantis NAS"] subgraph JitsiStack["๐Ÿ“น Jitsi Meet"] JITSI_WEB["Jitsi Web"] JITSI_JVB["Jitsi Video Bridge"] JITSI_PROSODY["Prosody XMPP"] end subgraph Vaultwarden["๐Ÿ”‘ Vaultwarden"] VW["Vaultwarden
Password Manager"] end subgraph Joplin["๐Ÿ“ Joplin"] JOPLIN_SRV["Joplin Server"] end end subgraph Clients["๐Ÿ“ฑ Clients"] BROWSER["Web Browsers"] MOBILE["Mobile Apps"] DESKTOP["Desktop Apps"] end %% External connections FEDI <--> CF_PROXY MATRIX_FED <--> CF_PROXY WEBRTC <--> COTURN %% Cloudflare to services CF_PROXY --> NGINX_VM CF_TUNNEL --> NGINX_VM %% Nginx routing NGINX_VM --> MASTO_WEB & MASTO_STREAM NGINX_VM --> SYNAPSE & ELEMENT NGINX_VM --> MM_APP %% Database connections MASTO_WEB & MASTO_SIDEKIQ --> POSTGRES & REDIS SYNAPSE --> POSTGRES MM_APP --> POSTGRES %% Client access BROWSER & MOBILE & DESKTOP --> CF_PROXY BROWSER & MOBILE & DESKTOP --> JITSI_WEB BROWSER & MOBILE & DESKTOP --> VW BROWSER & MOBILE & DESKTOP --> JOPLIN_SRV classDef mastodon fill:#6364FF,stroke:#333,stroke-width:2px,color:#fff classDef matrix fill:#0DBD8B,stroke:#333,stroke-width:2px,color:#fff classDef mattermost fill:#0058CC,stroke:#333,stroke-width:2px,color:#fff classDef infra fill:#e67e22,stroke:#333,stroke-width:2px,color:#fff class MASTO_WEB,MASTO_STREAM,MASTO_SIDEKIQ mastodon class SYNAPSE,ELEMENT,COTURN matrix class MM_APP mattermost class POSTGRES,REDIS,NGINX_VM infra ``` ### Communication Services Summary | Service | Domain | Protocol | Purpose | |---------|--------|----------|---------| | **Mastodon** | mastodon.vish.gg | ActivityPub | Fediverse microblogging | | **Matrix (Primary)** | mx.vish.gg | Matrix | Federated chat | | **Matrix (Legacy)** | matrix.thevish.io | Matrix | Legacy homeserver | | **Mattermost** | mm.crista.love | Proprietary | Team collaboration | | **Jitsi Meet** | meet.vish.gg | WebRTC | Video conferencing | | **Joplin** | joplin.vish.gg | Joplin Sync | Note synchronization | | **Vaultwarden** | vault.vish.gg | Bitwarden | Password management | ### Deployment Scripts | Script | Location | Description | |--------|----------|-------------| | Mastodon Install | [mastodon-production/](../mastodon-production/) | Bare metal & Docker deployment | | Matrix Install | [matrix-element/](../matrix-element/) | Synapse + Element + TURN | | Mattermost Install | [mattermost-production/](../mattermost-production/) | Docker deployment | | VM Config | [matrix-ubuntu-vm/](../matrix-ubuntu-vm/) | Complete VM configuration | --- ## ๐Ÿ”„ CI/CD Pipeline Architecture ### Git Repository Mirroring The homelab repository uses Gitea Actions for automated CI/CD, including sanitized public mirroring. ```mermaid graph LR subgraph Development["๐Ÿ’ป Development"] DEV["Developer
Pushes Code"] end subgraph Gitea["๐Ÿ”ง Gitea (Calypso)"] PRIVATE["๐Ÿ”’ Private Repo
homelab"] PUBLIC["๐ŸŒ Public Repo
homelab-optimized"] RUNNER["๐Ÿƒ Gitea Runner
(Calypso)"] end subgraph Workflow["โš™๏ธ CI/CD Workflow"] CHECKOUT["๐Ÿ“ฅ Checkout Code"] SANITIZE["๐Ÿงน Sanitize
Remove Secrets"] PUSH["๐Ÿ“ค Force Push
Fresh History"] end subgraph Deployment["๐Ÿš€ Deployment"] ANSIBLE["๐Ÿ“‹ Ansible
164 Services"] PORTAINER["๐Ÿณ Portainer
5 Endpoints"] end DEV -->|"git push"| PRIVATE PRIVATE -->|"Triggers"| RUNNER RUNNER --> CHECKOUT CHECKOUT --> SANITIZE SANITIZE --> PUSH PUSH --> PUBLIC PRIVATE --> ANSIBLE ANSIBLE --> PORTAINER ``` ### Sanitization Process The sanitization script removes sensitive data before public mirroring: | Removed | Pattern | Example | |---------|---------|---------| | Passwords | `password:`, `PASS=` | `password: "REDACTED_PASSWORD" | | API Keys | `api_key:`, `API_KEY=` | `api_key: REDACTED_API_KEY` | | Tokens | `token:`, `TOKEN=` | `token: REDACTED_TOKEN` | | Secrets | `secret:`, `SECRET=` | `secret: REDACTED_SECRET` | | Private Keys | `-----BEGIN.*KEY-----` | File removed | | SSH Keys | `id_rsa`, `id_ed25519` | File removed | | Personal Emails | `*@gmail.com`, `*@*.com` | `REDACTED_EMAIL@example.com` | | JWT Secrets | `JWT_SECRET=` | `JWT_SECRET=REDACTED` | ### Gitea Runner Setup ```mermaid graph TB subgraph Calypso["๐ŸŒŠ Calypso (DS920+)"] GITEA["๐Ÿ”ง Gitea Server
:3000"] RUNNER["๐Ÿƒ Gitea Runner
act_runner:latest"] DOCKER["๐Ÿณ Docker Socket"] end GITEA -->|"Workflow Dispatch"| RUNNER RUNNER -->|"docker.sock"| DOCKER DOCKER -->|"Spawn Containers"| RUNNER ``` **Runner Configuration:** - Image: `gitea/act_runner:latest` - Labels: `ubuntu-latest`, `ubuntu-22.04`, `python` - Location: Portainer stack on Calypso - Trigger: Push to main branch ### Ansible Automation ```mermaid graph TB subgraph Control["๐Ÿ“‹ Ansible Control"] SITE["site.yml
Master Playbook"] INV["inventory.yml
13 Hosts"] ROLES["Roles
docker_stack, directory_setup"] end subgraph Hosts["๐Ÿ–ฅ๏ธ Target Hosts"] SYN["Synology
Atlantis, Calypso, Setillo"] VMS["VMs
Homelab, Chicago, Bulgaria"] PHYS["Physical
Guava, NUC, Anubis"] EDGE["Edge
RPi5"] end SITE --> INV INV --> SYN INV --> VMS INV --> PHYS INV --> EDGE ``` **Ansible Commands:** ```bash # Deploy everything ansible-playbook site.yml # Deploy to specific host ansible-playbook site.yml --limit atlantis # Deploy by category ansible-playbook site.yml --tags synology # Check status ansible-playbook playbooks/common/status.yml ``` --- ## ๐Ÿ”— Related Diagrams - [Network Topology](network-topology.md) - How hosts connect - [Storage Topology](storage-topology.md) - Where data lives - [Tailscale Mesh](tailscale-mesh.md) - Cross-location access