This commit is contained in:
2026-07-27 19:56:44 +01:00
parent 211959cf2d
commit 31d653ddb5
9 changed files with 124 additions and 1 deletions
+1
View File
@@ -26,6 +26,7 @@ locals {
{ zone = "luke-else.co.uk", name = "status", value = module.prod.ipv4 },
{ zone = "luke-else.co.uk", name = "bitwarden", value = module.prod.ipv4 },
{ zone = "luke-else.co.uk", name = "rd", value = module.prod.ipv4 },
{ zone = "luke-else.co.uk", name = "home", value = module.prod.ipv4 },
{ zone = "luke-else.co.uk", name = "git", value = module.dev.ipv4 },
{ zone = "luke-else.co.uk", name = "traefik.cicd", value = module.dev.ipv4 },
{ zone = "luke-else.co.uk", name = "vpn", value = module.vpn.ipv4 },
+3 -1
View File
@@ -85,7 +85,7 @@ architecture-beta
│ └── playbooks/ # bootstrap.yml, deploy.yml, spinup.yml, spindown.yml, site.yml
├── services/ # Docker Compose stacks, grouped by which server they run on
│ ├── dev/ # Gitea + CI runners + Traefik + backup/restore
│ ├── prod/ # Websites, Bitwarden, RustDesk, status page + Traefik + backup/restore
│ ├── prod/ # Websites, Bitwarden, RustDesk, status page, home dashboard + Traefik + backup/restore
│ └── vpn/ # WireGuard (wg-easy) + Traefik + backup/restore
├── .devcontainer/ # git submodule: shared devcontainer for this repo (OpenTofu tooling)
└── assets/
@@ -101,6 +101,7 @@ Each of `services/dev`, `services/prod`, `services/vpn` follows the same convent
- **DNS is provisioned, not just documented.** `module.dns` creates a Hetzner zone and every A/MX/TXT/CNAME record in `infra/main.tf` — see [Managing DNS](#managing-dns).
- **Hosts are discovered dynamically** from the Hetzner API by role label, not a static inventory file — nothing in Ansible reads Terraform state.
- **Gitea Actions runners are disposable.** Their `/data` is a local cache; runner identity re-registers with Gitea on every `spinup.sh`, so they're excluded from backup.
- **The `home` dashboard only gets Docker container widgets for `prod`.** It links to every service on all three hosts, but container-level widgets (CPU/memory) are wired up only for containers on `prod` itself (`services/prod/home/config/docker.yaml`) — reaching into `dev`'s or `vpn`'s Docker socket would mean opening a path across hosts, which cuts against `vpn`'s deliberate isolation above. The Traefik widgets for `dev`/`vpn` are the one exception: they hit those hosts' public, unauthenticated dashboard URLs (same as any browser could), not their Docker sockets, so they need no network changes.
## Prerequisites
@@ -224,6 +225,7 @@ All three hosts run [Watchtower](https://containrrr.dev/watchtower/), polling ev
| Status page (Uptime Kuma) | `status-docker-compose.yml` | `status.luke-else.co.uk` |
| Bitwarden (Vaultwarden) | `bitwarden-docker-compose.yml` | `bitwarden.luke-else.co.uk` |
| RustDesk relay (hbbs/hbbr) | `rd-docker-compose.yml` | `rd.luke-else.co.uk`, ports `21115-21119` |
| Home dashboard (Homepage) | `home-docker-compose.yml` | `home.luke-else.co.uk` |
| Watchtower | `watchtower-docker-compose.yml` | — |
| Backup/restore | `backup-docker-compose.yml` | — |
+26
View File
@@ -0,0 +1,26 @@
services:
home:
image: ghcr.io/gethomepage/homepage:latest
container_name: home
volumes:
- ./home/config:/app/config
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- proxy
labels:
## Expose home Through Trefik ##
- "traefik.enable=true" # <== Enable traefik to proxy this container
- "traefik.http.middlewares.redirect-web-secure.redirectscheme.scheme=https"
- "traefik.http.routers.home-insecure.middlewares=redirect-web-secure"
- "traefik.http.routers.home-insecure.rule=Host(`home.luke-else.co.uk`)"
- "traefik.http.routers.home-insecure.entrypoints=web"
- "traefik.http.routers.home.rule=Host(`home.luke-else.co.uk`)"
- "traefik.http.routers.home.entrypoints=websecure"
- "traefik.http.routers.home.tls.certresolver=myresolver"
restart: unless-stopped
networks:
proxy:
external: true
+6
View File
@@ -0,0 +1,6 @@
# Docker host home reads live container status from - only ever the local
# socket for prod. dev/vpn are separate hosts with their own Docker daemons
# and are deliberately not reachable from here (see architecture diagram in
# the README), so their services are plain links, not live widgets.
my-docker:
socket: /var/run/docker.sock
+63
View File
@@ -0,0 +1,63 @@
- Websites:
- luke-else.co.uk:
href: https://luke-else.co.uk
description: Personal site (prod)
icon: mdi-web
container: luke-else
- Services:
- Status page:
href: https://status.luke-else.co.uk
description: Uptime Kuma
icon: mdi-list-status
container: status
widget:
type: uptimekuma
url: https://status.luke-else.co.uk
slug: dashboard
- Bitwarden:
href: https://bitwarden.luke-else.co.uk
description: Vaultwarden
icon: mdi-key-variant
container: bitwarden
- RustDesk:
href: https://rd.luke-else.co.uk
description: RustDesk relay (hbbs/hbbr)
icon: mdi-remote-desktop
container: rustdesk-hbbs
- Gitea:
href: https://git.luke-else.co.uk
description: Git hosting + CI (dev)
icon: mdi-git
- WireGuard:
href: https://vpn.luke-else.co.uk
description: wg-easy (vpn)
icon: mdi-vpn
- Infrastructure:
- Traefik (prod):
href: https://traefik.luke-else.co.uk
description: Reverse proxy - prod
icon: mdi-lan-connect
container: traefik
widget:
type: traefik
url: http://traefik.luke-else.co.uk
- Traefik (dev):
href: https://traefik.cicd.luke-else.co.uk
description: Reverse proxy - dev
icon: mdi-lan-connect
widget:
type: traefik
url: https://traefik.cicd.luke-else.co.uk
- Traefik (vpn):
href: https://traefik.vpn.luke-else.co.uk
description: Reverse proxy - vpn
icon: mdi-lan-connect
widget:
type: traefik
url: https://traefik.vpn.luke-else.co.uk
- Hetzner Cloud Console:
href: https://console.hetzner.cloud/
description: Servers, networks, firewalls (OpenTofu-managed)
icon: mdi-cloud-outline
+14
View File
@@ -0,0 +1,14 @@
title: Home
theme: dark
color: slate
headerStyle: boxed
layout:
Websites:
style: row
columns: 3
Services:
style: row
columns: 3
Infrastructure:
style: row
columns: 3
+9
View File
@@ -0,0 +1,9 @@
# Info bar widgets - stats for *this* host (prod), where home actually runs.
- resources:
label: prod
cpu: true
memory: true
disk: /
- search:
provider: duckduckgo
target: _blank
+1
View File
@@ -6,6 +6,7 @@ docker compose -f web-docker-compose.yml down
docker compose -f status-docker-compose.yml down
docker compose -f bitwarden-docker-compose.yml down
docker compose -f rd-docker-compose.yml down
docker compose -f home-docker-compose.yml down
docker compose -f watchtower-docker-compose.yml down
docker compose -f traefik-docker-compose.yml down
docker compose -f backup-docker-compose.yml down
+1
View File
@@ -21,6 +21,7 @@ docker compose -f status-docker-compose.yml pull && docker compose -f status-doc
docker compose -f web-docker-compose.yml pull && docker compose -f web-docker-compose.yml up -d
docker compose -f bitwarden-docker-compose.yml pull && docker compose -f bitwarden-docker-compose.yml up -d
docker compose -f rd-docker-compose.yml pull && docker compose -f rd-docker-compose.yml up -d
docker compose -f home-docker-compose.yml pull && docker compose -f home-docker-compose.yml up -d
docker compose -f backup-docker-compose.yml pull backup
docker compose -f backup-docker-compose.yml up -d backup