first commit and build
build-and-deploy / build (push) Successful in 19s

This commit is contained in:
2026-09-16 11:42:32 -04:00
commit baf674b1be
14 changed files with 285 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
# Hardware
Physical inventory.
| Item | Model | Serial | Purchased | Warranty | Notes |
|---|---|---|---|---|---|
| Gateway | UniFi UDR7 | _redact on public_ | | | |
| _add yours_ | | | | | |
+17
View File
@@ -0,0 +1,17 @@
# Frostlabs Homelab
Operational documentation and disaster-recovery runbooks.
!!! info "How this site works"
The source of truth is the Markdown in this repository on `git.frostlabs.me`.
On every push to `main`, Gitea Actions rebuilds and redeploys this site. The
rendered page you're reading is disposable — if it's ever lost, it rebuilds
from the repo. The repo itself lives in three independent places (Gitea VPS,
homelab, laptop), which is what makes this survive a total system failure.
## Start here
- [Network](network/index.md) — topology, VLAN/subnet plan, firewall policy
- [Runbooks](runbooks/index.md) — step-by-step recovery procedures
- [Services](services/index.md) — what runs where
- [Hardware](hardware/index.md) — physical inventory
+21
View File
@@ -0,0 +1,21 @@
# Firewall
Zone-based policy on the UDR7. Document the **intent** first, then the rules
that implement it — future-you (mid-outage) needs the reasoning, not just a
rule dump.
## Policy matrix
| From \ To | Management | Trusted | IoT | Guest | WAN |
|---|---|---|---|---|---|
| Management | — | allow | allow | allow | allow |
| Trusted | deny | — | allow | deny | allow |
| IoT | deny | deny | — | deny | allow* |
| Guest | deny | deny | deny | — | allow |
\* IoT to WAN often restricted to specific destinations. Document exceptions.
## Rationale
Explain each non-obvious allow/deny: why IoT can't reach Trusted, which
management exceptions exist, and any per-device carve-outs.
+8
View File
@@ -0,0 +1,8 @@
# Network
The homelab runs on a UniFi UDR7 with a segmented VLAN design and a
zone-based firewall policy. This section is the reference for that design.
- [Topology](topology.md) — physical + logical layout
- [VLANs & Subnets](vlans.md) — the segmentation plan
- [Firewall](firewall.md) — inter-zone policy and rationale
+27
View File
@@ -0,0 +1,27 @@
# Topology
!!! note "Template"
The diagram below is a scaffold. Replace the nodes/edges with your actual
layout. It renders automatically — Material draws ` ```mermaid ` blocks.
```mermaid
graph TD
WAN[Internet] --> UDR7[UniFi UDR7]
UDR7 --> SW[Aggregation Switch]
SW --> AP[Access Points]
SW --> VLAN_MGMT[VLAN 10 · Management]
SW --> VLAN_TRUST[VLAN 20 · Trusted]
SW --> VLAN_IOT[VLAN 30 · IoT]
SW --> VLAN_GUEST[VLAN 40 · Guest]
```
## Physical
| Device | Model | Location | Notes |
|---|---|---|---|
| Gateway | UniFi UDR7 | _rack_ | _replace with real detail_ |
| Switch | _model_ | _location_ | _uplinks / PoE_ |
## Logical
Describe uplinks, tagged/untagged ports, and where each VLAN is trunked.
+18
View File
@@ -0,0 +1,18 @@
# VLANs & Subnets
!!! warning "Fill in real values"
The rows below are an **example format**, not your live plan. Replace them
with your actual VLAN IDs, subnets, and gateways. On the private site this
is fine; keep the [public portfolio version](../index.md) sanitized.
| VLAN | Name | Subnet | Gateway | DHCP | Purpose |
|---|---|---|---|---|---|
| 10 | Management | 10.0.10.0/24 | 10.0.10.1 | reserved | Switches, APs, UDR7 UI |
| 20 | Trusted | 10.0.20.0/24 | 10.0.20.1 | yes | Workstations, phones |
| 30 | IoT | 10.0.30.0/24 | 10.0.30.1 | yes | Smart-home, Matter/Thread |
| 40 | Guest | 10.0.40.0/24 | 10.0.40.1 | yes | Isolated guest access |
## Notes
- Reserved (static) leases: document them per device.
- mDNS / service discovery across VLANs: note where it's allowed and how.
+45
View File
@@ -0,0 +1,45 @@
# Disaster Recovery: Git + Docs stack
Goal: restore `git.frostlabs.me` and the docs sites after losing the VPS.
## What state actually matters
| Thing | Where | Rebuildable? |
|---|---|---|
| Gitea data (repos, DB, config) | `/opt/gitea/gitea/` (SQLite + repos) | **No — back this up** |
| Runner registration | `/opt/gitea/runner/.runner` | No (but re-registerable in minutes) |
| Built sites | `/srv/www/` | Yes — rebuilt on next push |
| Tunnel / nginx / compose config | `/opt/gitea/*.yml`, `.env`, `nginx.conf` | Keep a copy off-box |
The docs repos themselves are safe as long as one clone survives (VPS, homelab,
laptop). This runbook is about restoring the **server**.
## Backup (do this on a schedule)
```bash
# Off-box snapshot of everything stateful on the VPS
rsync -aP /opt/gitea/ backup-target:/backups/gitea/
```
!!! tip
A `gitea dump` is the "proper" way, but for a single-user SQLite instance an
rsync of `/opt/gitea` while the stack is stopped is simplest and complete.
## Restore onto a fresh VPS
1. Provision the box, install Docker + compose.
2. Recreate `/opt/gitea/` and restore the backup into it.
3. Recreate `.env` with `TUNNEL_TOKEN` and (optionally) `RUNNER_TOKEN`.
4. `mkdir -p /srv/www/docs-public /srv/www/docs-private`
5. `docker compose up -d`
6. In Cloudflare Zero Trust, point the tunnel at the new box (token is the same
tunnel, so hostnames just reattach). Confirm `git.frostlabs.me` loads.
7. If the runner didn't reconnect, re-register it (Site Admin → Actions → Runners).
8. Push any repo (or hit **Run workflow**) to rebuild both sites into `/srv/www`.
## Verify
- [ ] `git.frostlabs.me` reachable, repos present
- [ ] `runbook.frostlabs.me` rebuilt and gated by CF Access
- [ ] `docs.frostlabs.me` rebuilt and public
- [ ] a test push triggers a green Actions run
+6
View File
@@ -0,0 +1,6 @@
# Runbooks
Step-by-step procedures for when something is on fire. Written to be followed
under stress — imperative steps, exact commands, no ambiguity.
- [Disaster Recovery](disaster-recovery.md) — rebuild the docs/Git stack from nothing
+12
View File
@@ -0,0 +1,12 @@
# Services
What runs where, and how to reach it.
| Service | Host | VLAN | URL / Port | Notes |
|---|---|---|---|---|
| Gitea | VPS (Linode) | — | git.frostlabs.me | via Cloudflare Tunnel |
| Docs (this site) | VPS (Linode) | — | runbook.frostlabs.me | nginx + CF Access |
| _add yours_ | | | | |
For each service, link to its own page with config location, backup method,
and restore steps.