Add levkin.ca site, document git-ci-01 runner tuning
All checks were successful
CI / skip-ci-check (pull_request) Successful in 6s
CI / ansible-validation (pull_request) Successful in 46s
CI / lint-and-test (pull_request) Successful in 51s
CI / secret-scanning (pull_request) Successful in 6s
CI / dependency-scan (pull_request) Successful in 15s
CI / license-check (pull_request) Successful in 13s
CI / sast-scan (pull_request) Successful in 24s
CI / vault-check (pull_request) Successful in 11s
CI / container-scan (pull_request) Successful in 6s
CI / sonar-analysis (pull_request) Successful in 5s
CI / playbook-test (pull_request) Successful in 25s
CI / workflow-summary (pull_request) Successful in 4s
All checks were successful
CI / skip-ci-check (pull_request) Successful in 6s
CI / ansible-validation (pull_request) Successful in 46s
CI / lint-and-test (pull_request) Successful in 51s
CI / secret-scanning (pull_request) Successful in 6s
CI / dependency-scan (pull_request) Successful in 15s
CI / license-check (pull_request) Successful in 13s
CI / sast-scan (pull_request) Successful in 24s
CI / vault-check (pull_request) Successful in 11s
CI / container-scan (pull_request) Successful in 6s
CI / sonar-analysis (pull_request) Successful in 5s
CI / playbook-test (pull_request) Successful in 25s
CI / workflow-summary (pull_request) Successful in 4s
Inventory and Caddy playbook for levkin LXC 220; Makefile target caddy-levkin. Document git-ci-01 disk (64G), capacity 2, prune cron, and pve201 RAM limits in host_vars and homelab guides. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
35d17ed527
commit
f0ff00a8dc
4
Makefile
4
Makefile
@ -284,6 +284,10 @@ caddy-auth: require-ansible ## Ensure auth.levkin.ca reverse proxy on Caddy VM
|
|||||||
@echo "$(YELLOW)Updating Caddy for Authentik...$(RESET)"
|
@echo "$(YELLOW)Updating Caddy for Authentik...$(RESET)"
|
||||||
$(ANSIBLE_PLAYBOOK) playbooks/caddy-auth-authentik.yml $(ANSIBLE_ARGS)
|
$(ANSIBLE_PLAYBOOK) playbooks/caddy-auth-authentik.yml $(ANSIBLE_ARGS)
|
||||||
|
|
||||||
|
caddy-levkin: require-ansible ## Ensure levkin.ca reverse proxy on Caddy VM
|
||||||
|
@echo "$(YELLOW)Updating Caddy for levkin.ca...$(RESET)"
|
||||||
|
$(ANSIBLE_PLAYBOOK) playbooks/caddy-levkin-site.yml $(ANSIBLE_ARGS)
|
||||||
|
|
||||||
workstations: ## Run workstation baseline (usage: make workstations [GROUP=dev] [HOST=dev01])
|
workstations: ## Run workstation baseline (usage: make workstations [GROUP=dev] [HOST=dev01])
|
||||||
@echo "$(YELLOW)Applying workstation baseline...$(RESET)"
|
@echo "$(YELLOW)Applying workstation baseline...$(RESET)"
|
||||||
@EXTRA=""; \
|
@EXTRA=""; \
|
||||||
|
|||||||
@ -10,7 +10,8 @@ Quick checklist after monitoring / sites / git pass.
|
|||||||
| Kuma + Dockge + Umami | LXC 218 @ `10.0.10.22`; Dockge stack **monitoring** active |
|
| Kuma + Dockge + Umami | LXC 218 @ `10.0.10.22`; Dockge stack **monitoring** active |
|
||||||
| Old Kuma pve201 LXC 305 | Stopped, `onboot` off |
|
| Old Kuma pve201 LXC 305 | Stopped, `onboot` off |
|
||||||
| `stats.levkin.ca` | Caddy → Umami `:3000` |
|
| `stats.levkin.ca` | Caddy → Umami `:3000` |
|
||||||
| Tracking scripts | caseware + auto + portfolio (`iliadobkin.com`) |
|
| Tracking scripts | levkin.ca + caseware + auto + portfolio (`iliadobkin.com`) |
|
||||||
|
| **levkin.ca** | LXC **220** @ `10.0.10.60`; Caddy → nginx; `/` = spec, `/folders/` = stack |
|
||||||
| Portfolio `iliadobkin.com` | Migrated pve201 LXC **306** → pve10 LXC **219** @ `10.0.10.106`; Caddy → nginx `:80` |
|
| Portfolio `iliadobkin.com` | Migrated pve201 LXC **306** → pve10 LXC **219** @ `10.0.10.106`; Caddy → nginx `:80` |
|
||||||
| Kuma SMTP | Working (user confirmed) |
|
| Kuma SMTP | Working (user confirmed) |
|
||||||
| Git remote | `git@git.levkin.ca:ilia/...` (SSH → `10.0.10.169` via `~/.ssh/config` on site LXCs) |
|
| Git remote | `git@git.levkin.ca:ilia/...` (SSH → `10.0.10.169` via `~/.ssh/config` on site LXCs) |
|
||||||
@ -25,6 +26,8 @@ Quick checklist after monitoring / sites / git pass.
|
|||||||
### You (UI / hardware / DNS)
|
### You (UI / hardware / DNS)
|
||||||
|
|
||||||
- [x] **Kuma SMTP** — working
|
- [x] **Kuma SMTP** — working
|
||||||
|
- [ ] **DNS `levkin.ca` + `www`** — A records → home IP (`142.180.237.136`); apex currently parked at AWS, not homelab
|
||||||
|
- [ ] **Gitea deploy key (levkin LXC 220)** — add `deploy-levkin-levkin.ca` pubkey in repo settings (SSH pull); HTTPS clone works meanwhile
|
||||||
- [ ] **UniFi DHCP reservations** — [unifi-static-dhcp.md](unifi-static-dhcp.md) @ https://192.168.2.1/
|
- [ ] **UniFi DHCP reservations** — [unifi-static-dhcp.md](unifi-static-dhcp.md) @ https://192.168.2.1/
|
||||||
- [ ] **Cal.com → Authentik OIDC** — first SSO (~1–2 h) — [levkin-selfhost-plan-2.md](levkin-selfhost-plan-2.md)
|
- [ ] **Cal.com → Authentik OIDC** — first SSO (~1–2 h) — [levkin-selfhost-plan-2.md](levkin-selfhost-plan-2.md)
|
||||||
- [ ] **Nextcloud VM 201 retire** — remove Kuma monitor, Caddy `nextcloud.levkin.ca`, stop VM
|
- [ ] **Nextcloud VM 201 retire** — remove Kuma monitor, Caddy `nextcloud.levkin.ca`, stop VM
|
||||||
@ -43,6 +46,7 @@ Quick checklist after monitoring / sites / git pass.
|
|||||||
|
|
||||||
| VMID | Name | IP | Git remote |
|
| VMID | Name | IP | Git remote |
|
||||||
|------|------|-----|------------|
|
|------|------|-----|------------|
|
||||||
|
| 220 | levkin | 10.0.10.60 | `git@git.levkin.ca:ilia/levkin.ca.git` |
|
||||||
| 215 | caseware | 10.0.10.105 | `git@git.levkin.ca:ilia/caseware.git` |
|
| 215 | caseware | 10.0.10.105 | `git@git.levkin.ca:ilia/caseware.git` |
|
||||||
| 216 | auto | 10.0.10.59 | `git@git.levkin.ca:ilia/auto.git` |
|
| 216 | auto | 10.0.10.59 | `git@git.levkin.ca:ilia/auto.git` |
|
||||||
| 219 | portfolio | 10.0.10.106 | `git@git.levkin.ca:ilia/sdetProfile.git` |
|
| 219 | portfolio | 10.0.10.106 | `git@git.levkin.ca:ilia/sdetProfile.git` |
|
||||||
|
|||||||
@ -41,6 +41,7 @@ Update this file whenever a guest is created, migrated, or re-IP’d. See [levki
|
|||||||
| 215 | caseware | **marketing site** | `10.0.10.105/24` | `10.0.10.105/24` | ✅ **Static** | `BC:24:11:72:04:53` | Static HTML `/var/www/caseware` → `caseware.levkin.ca` |
|
| 215 | caseware | **marketing site** | `10.0.10.105/24` | `10.0.10.105/24` | ✅ **Static** | `BC:24:11:72:04:53` | Static HTML `/var/www/caseware` → `caseware.levkin.ca` |
|
||||||
| 216 | auto | **marketing site** | `10.0.10.59/24` | `10.0.10.59/24` | ✅ **Static** | `BC:24:11:43:F0:86` | Static HTML `/var/www/auto` → `auto.levkin.ca` |
|
| 216 | auto | **marketing site** | `10.0.10.59/24` | `10.0.10.59/24` | ✅ **Static** | `BC:24:11:43:F0:86` | Static HTML `/var/www/auto` → `auto.levkin.ca` |
|
||||||
| 219 | portfolio | **marketing site** | `10.0.10.106/24` | `10.0.10.106/24` | ✅ **Static** | `BC:24:11:DF:94:32` | Static HTML `/var/www/portfolio` → `iliadobkin.com` (migrated from pve201 LXC 306) |
|
| 219 | portfolio | **marketing site** | `10.0.10.106/24` | `10.0.10.106/24` | ✅ **Static** | `BC:24:11:DF:94:32` | Static HTML `/var/www/portfolio` → `iliadobkin.com` (migrated from pve201 LXC 306) |
|
||||||
|
| 220 | levkin | **marketing site** | `10.0.10.60/24` | `10.0.10.60/24` | ✅ **Static** | `BC:24:11:C6:B2:E4` | Vite `www/` → `levkin.ca` (spec), `levkin.ca/folders` (stack) — [site-lxc-git.md](site-lxc-git.md) |
|
||||||
| 217 | identity | identity | `10.0.10.21/24` | `10.0.10.21/24` | ✅ **Static** | `BC:24:11:3C:85:45` | Authentik + Postgres + Redis; `auth.levkin.ca` via Caddy |
|
| 217 | identity | identity | `10.0.10.21/24` | `10.0.10.21/24` | ✅ **Static** | `BC:24:11:3C:85:45` | Authentik + Postgres + Redis; `auth.levkin.ca` via Caddy |
|
||||||
| 218 | monitoring | monitoring | `10.0.10.22/24` | `10.0.10.22/24` | ✅ **Static** | `BC:24:11:54:43:13` | Uptime Kuma `:3001`, Dockge `:5001`, Umami `:3000` — see [monitoring-stack.md](monitoring-stack.md) |
|
| 218 | monitoring | monitoring | `10.0.10.22/24` | `10.0.10.22/24` | ✅ **Static** | `BC:24:11:54:43:13` | Uptime Kuma `:3001`, Dockge `:5001`, Umami `:3000` — see [monitoring-stack.md](monitoring-stack.md) |
|
||||||
|
|
||||||
@ -81,6 +82,7 @@ Update this file whenever a guest is created, migrated, or re-IP’d. See [levki
|
|||||||
| caseware | `10.0.10.105` | LXC 215 | ✅ |
|
| caseware | `10.0.10.105` | LXC 215 | ✅ |
|
||||||
| auto | `10.0.10.59` | LXC 216 | ✅ |
|
| auto | `10.0.10.59` | LXC 216 | ✅ |
|
||||||
| portfolio | `10.0.10.106` | LXC 219 | ✅ |
|
| portfolio | `10.0.10.106` | LXC 219 | ✅ |
|
||||||
|
| levkin | `10.0.10.60` | LXC 220 | ✅ |
|
||||||
| identity | `10.0.10.21` | LXC 217 | ✅ |
|
| identity | `10.0.10.21` | LXC 217 | ✅ |
|
||||||
| monitoring | `10.0.10.22` | LXC 218 | ✅ |
|
| monitoring | `10.0.10.22` | LXC 218 | ✅ |
|
||||||
| vaultwardenVM | `10.0.10.142` | VM 104 | ✅ |
|
| vaultwardenVM | `10.0.10.142` | VM 104 | ✅ |
|
||||||
|
|||||||
@ -11,6 +11,58 @@ Reference doc for the Proxmox homelab. Lives alongside the Cursor project that h
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Progress summary (updated 2026-05-23)
|
||||||
|
|
||||||
|
| Area | Status |
|
||||||
|
|------|--------|
|
||||||
|
| **Phase 0** Foundation | ✅ Mostly done — static IPs on pve10 LXCs; Caddy still on **VM 106** |
|
||||||
|
| **Phase 1** Identity (Authentik) | ✅ LXC **217** @ `10.0.10.21` |
|
||||||
|
| **Phase 2** Monitoring (Kuma, Dockge, Umami) | ✅ LXC **218** @ `10.0.10.22` |
|
||||||
|
| **Phase 3** Cal.com | ✅ LXC **210** — OIDC + auto site button still open |
|
||||||
|
| **Phase 4** SSO migration | ⏳ Not started (Cal → Authentik first) |
|
||||||
|
| **Phase 5–8** Immich, Crater, Outline, etc. | ⏳ Deferred |
|
||||||
|
| **Site consolidation** | ⏳ **Partial** — **levkin.ca** on LXC **220** @ `10.0.10.60` ✅; caseware/auto/portfolio on **215/216/219** ([site-lxc-git.md](site-lxc-git.md)); moving all static to Caddy VM is optional later |
|
||||||
|
| **dev-apps** (punim/pote/mirrormatch) | ⏳ **Not started** — punimTag **9101** still on **pve201** (active testing; do not migrate yet) |
|
||||||
|
| **Nextcloud retire** | ⏳ VM **201 is running again** on pve10 — finish decommission |
|
||||||
|
| **Portainer retire** | ⏳ VM **109 still running** (16 GB maxmem) on pve10 — stop after Dockge confirmed |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Capacity headroom (live check 2026-05-23)
|
||||||
|
|
||||||
|
Use this before adding LXCs/VMs. Re-check with `pvesm status` and `free -h` on each node.
|
||||||
|
|
||||||
|
### pve10 (PVENAS) — **primary place for new homelab services**
|
||||||
|
|
||||||
|
| Resource | Total | Used | **Available** | Notes |
|
||||||
|
|----------|-------|------|---------------|--------|
|
||||||
|
| **local-lvm** (thin) | ~1.67 TiB | ~22% | **~1.30 TiB** | Plenty of disk for new LXCs |
|
||||||
|
| **RAM** (host) | 62 GiB | ~44 GiB | **~17 GiB** | Enough for **2–3 small LXCs** (2 GB each) as-is |
|
||||||
|
|
||||||
|
**Realistic new capacity on pve10 (without stopping anything):** ~**4–6 GiB RAM** + **100–200 GiB disk** for one productivity/media LXC (Outline, Mealie, Immich-lite).
|
||||||
|
|
||||||
|
**If you free RAM first (recommended):**
|
||||||
|
|
||||||
|
| Stop / retire | Frees (maxmem) |
|
||||||
|
|---------------|----------------|
|
||||||
|
| Portainer VM **109** | **16 GiB** |
|
||||||
|
| Nextcloud VM **201** | **8 GiB** |
|
||||||
|
| Hermes VM **117** (if not needed) | **16 GiB** |
|
||||||
|
| Site LXCs 215/216 → Caddy static (future) | **~1 GiB** |
|
||||||
|
|
||||||
|
After Portainer + Nextcloud off: **~41 GiB effective headroom** on pve10 — room for Immich, Crater, Beszel, or a **dev-apps** LXC (6–8 GiB).
|
||||||
|
|
||||||
|
### pve201 (pve) — **do not add new services**
|
||||||
|
|
||||||
|
| Resource | Total | Used | **Available** | Notes |
|
||||||
|
|----------|-------|------|---------------|--------|
|
||||||
|
| **local-lvm** | ~1.67 TiB | ~46% | **~922 GiB** | Disk OK |
|
||||||
|
| **RAM** | 125 GiB | ~122 GiB | **~3 GiB** | Saturated; GPU VM **104** (73 GB), punimTag **9101** (16 GB) |
|
||||||
|
|
||||||
|
**Verdict:** New stacks belong on **pve10**. pve201 only benefits from **stopping/migrating** guests (punim after testing, GPU resize, old Kuma already stopped).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Current state (May 2026)
|
## Current state (May 2026)
|
||||||
|
|
||||||
**Already running:**
|
**Already running:**
|
||||||
@ -18,7 +70,7 @@ Reference doc for the Proxmox homelab. Lives alongside the Cursor project that h
|
|||||||
- Mailcow — VM, mail domain is `levkine.ca` (with e)
|
- Mailcow — VM, mail domain is `levkine.ca` (with e)
|
||||||
- Vaultwarden, Vikunja, n8n, Listmonk, Mattermost, Nextcloud — across various LXCs
|
- Vaultwarden, Vikunja, n8n, Listmonk, Mattermost, Nextcloud — across various LXCs
|
||||||
- **Cal.com** — LXC id `210`, `cal.levkin.ca`, Postgres included, admin user `ilia`, 15-min consult event live at `cal.levkin.ca/ilia/consult` with Jitsi link
|
- **Cal.com** — LXC id `210`, `cal.levkin.ca`, Postgres included, admin user `ilia`, 15-min consult event live at `cal.levkin.ca/ilia/consult` with Jitsi link
|
||||||
- Caddy entries live for: `caseware.levkin.ca`, `auto.levkin.ca`, `iliadobkin.com`, `cal.levkin.ca`, `listmonk.levkin.ca`, `pdf.levkin.ca`, `search.levkin.ca`, `auth.levkin.ca`
|
- Caddy entries live for: `levkin.ca`, `caseware.levkin.ca`, `auto.levkin.ca`, `iliadobkin.com`, `cal.levkin.ca`, `listmonk.levkin.ca`, `pdf.levkin.ca`, `search.levkin.ca`, `auth.levkin.ca`, `stats.levkin.ca`
|
||||||
- **Authentik** — LXC **217** @ `10.0.10.21`, `https://auth.levkin.ca`, admin + TOTP enrolled
|
- **Authentik** — LXC **217** @ `10.0.10.21`, `https://auth.levkin.ca`, admin + TOTP enrolled
|
||||||
- **Monitoring** — LXC **218** @ `10.0.10.22`: Uptime Kuma `:3001`, Dockge `:5001`, Umami `:3000` (LAN-only) — [monitoring-stack.md](monitoring-stack.md)
|
- **Monitoring** — LXC **218** @ `10.0.10.22`: Uptime Kuma `:3001`, Dockge `:5001`, Umami `:3000` (LAN-only) — [monitoring-stack.md](monitoring-stack.md)
|
||||||
- **Umami** + **Authentik** admin/TOTP/backup codes — done
|
- **Umami** + **Authentik** admin/TOTP/backup codes — done
|
||||||
@ -27,7 +79,10 @@ Reference doc for the Proxmox homelab. Lives alongside the Cursor project that h
|
|||||||
- **Snapshots** `backup-20260522` on LXCs **217**, **218**
|
- **Snapshots** `backup-20260522` on LXCs **217**, **218**
|
||||||
- **Jellyfin** (VM 101) — stopped
|
- **Jellyfin** (VM 101) — stopped
|
||||||
- LXC **210, 215–218, 219** — static via `pct set`; **Caddy VM 106** — static in-guest `.50`
|
- LXC **210, 215–218, 219** — static via `pct set`; **Caddy VM 106** — static in-guest `.50`
|
||||||
- **Nextcloud VM 201** — export done; **retire soon** (no SSO, remove Kuma monitor + Caddy block when off)
|
- **Nextcloud VM 201** — export done; VM **still running** on pve10 — **retire next** (8 GB RAM reclaimed)
|
||||||
|
- **Portainer VM 109** — still **running** on pve10 (16 GB) — retire; Dockge on 218 replaces it
|
||||||
|
- **Marketing sites** — LXC **220** (`levkin.ca`), **215/216/219** (git deploy), not yet on Caddy VM static roots
|
||||||
|
- **punimTag dev** — pve201 LXC **9101** @ `10.0.10.121` (16 GB) — leave until testing done; then `dev-apps` on pve10
|
||||||
|
|
||||||
**Decisions locked in:**
|
**Decisions locked in:**
|
||||||
- Container manager: **Dockge** (not Portainer, not Coolify/Dokploy/CapRover)
|
- Container manager: **Dockge** (not Portainer, not Coolify/Dokploy/CapRover)
|
||||||
@ -71,6 +126,7 @@ Only expose what actually needs to be public. Internal services use Tailscale/Wi
|
|||||||
|
|
||||||
| Subdomain | Service | Group | Why public | Status |
|
| Subdomain | Service | Group | Why public | Status |
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
|
| `levkin.ca` | Company site (spec + `/folders`) | edge | Main brand | ✅ LXC 220 — **DNS must point to home IP** (was parked elsewhere) |
|
||||||
| `caseware.levkin.ca` | Static site | edge | Marketing | ✅ live |
|
| `caseware.levkin.ca` | Static site | edge | Marketing | ✅ live |
|
||||||
| `auto.levkin.ca` | Static site | edge | Marketing | ✅ live |
|
| `auto.levkin.ca` | Static site | edge | Marketing | ✅ live |
|
||||||
| `iliadobkin.com` | Portfolio (SDET) | edge | Personal site | ✅ live (pve10 LXC 219) |
|
| `iliadobkin.com` | Portfolio (SDET) | edge | Personal site | ✅ live (pve10 LXC 219) |
|
||||||
@ -155,10 +211,10 @@ Steps:
|
|||||||
7. Keep the old VM snapshot for a week, then delete
|
7. Keep the old VM snapshot for a week, then delete
|
||||||
|
|
||||||
### Phase 2 — Quick wins ✅
|
### Phase 2 — Quick wins ✅
|
||||||
1. ✅ **Umami** — tracking on caseware, auto, and iliadobkin.com (portfolio)
|
1. ✅ **Umami** — tracking on levkin.ca, caseware, auto, and iliadobkin.com (portfolio)
|
||||||
2. ✅ **Uptime Kuma** — monitors in UI
|
2. ✅ **Uptime Kuma** — monitors in UI
|
||||||
3. ✅ **Dockge** — logged in; register `/opt/monitoring` stack (see [monitoring-stack.md](monitoring-stack.md))
|
3. ✅ **Dockge** — logged in; register `/opt/monitoring` stack (see [monitoring-stack.md](monitoring-stack.md))
|
||||||
4. ⏳ **Kuma email alerts** — SMTP via Mailcow `alerts@levkine.ca` → your inbox (steps in monitoring-stack.md)
|
4. ✅ **Kuma email alerts** — SMTP via Mailcow (see [homelab-status-2026-05-22.md](homelab-status-2026-05-22.md))
|
||||||
|
|
||||||
### Phase 3 — Cal.com (mostly done) ✅
|
### Phase 3 — Cal.com (mostly done) ✅
|
||||||
1. ✅ Cal.com deployed in `business` LXC (id 210, Postgres included)
|
1. ✅ Cal.com deployed in `business` LXC (id 210, Postgres included)
|
||||||
@ -256,18 +312,21 @@ pct reboot <ID>
|
|||||||
|
|
||||||
### Hosts known to need conversion right now
|
### Hosts known to need conversion right now
|
||||||
|
|
||||||
- **LXC 210 (cal)** — currently DHCP `10.0.10.228/24`, must be static before Caddy migration
|
- ~~**LXC 210 (cal)**~~ — static at `10.0.10.228` ✅
|
||||||
|
- **Site LXCs 220, 215/216/219** — static; served via Caddy → nginx on each LXC (git deploy). Optional future: static files on Caddy VM only.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Backlog (priority order)
|
## Backlog (priority order)
|
||||||
|
|
||||||
### P0 — next batch after Phase 1 admin bootstrap
|
### P0 — next (Phase 1–2 largely ✅)
|
||||||
1. **Umami** — analytics on landing pages, 10 min to deploy, immediate signal
|
1. ~~Umami~~ ✅
|
||||||
2. **Uptime Kuma** — monitor what you already have
|
2. ~~Uptime Kuma~~ ✅
|
||||||
3. **Dockge** — UI over existing compose
|
3. ~~Dockge~~ ✅
|
||||||
4. **Beszel** — homelab resource visibility
|
4. **Cal.com → Authentik OIDC** — first SSO
|
||||||
5. **Mealie** — family recipes, simple win
|
5. **Retire Nextcloud VM 201** + **Portainer VM 109** — frees **~24 GiB** on pve10
|
||||||
|
6. **Beszel** — fits on monitoring LXC 218 or small agent LXCs
|
||||||
|
7. **Mealie** — new small LXC on pve10 (~2 GB)
|
||||||
|
|
||||||
### P1 — when ready
|
### P1 — when ready
|
||||||
- **Outline** — wiki for client docs
|
- **Outline** — wiki for client docs
|
||||||
@ -311,18 +370,32 @@ The whole LXC gets snapshotted — much simpler than file-level container backup
|
|||||||
|
|
||||||
## Next steps (priority order)
|
## Next steps (priority order)
|
||||||
|
|
||||||
See **[homelab-status-2026-05-22.md](homelab-status-2026-05-22.md)** for done vs todo.
|
See **[homelab-status-2026-05-22.md](homelab-status-2026-05-22.md)** for automation checklist.
|
||||||
|
|
||||||
| # | Task | Effort | Doc |
|
| # | Task | Status | Effort | Frees / unlocks |
|
||||||
|---|------|--------|-----|
|
|---|------|--------|--------|-----------------|
|
||||||
| 1 | **Kuma SMTP** test in UI | 5 min | [monitoring-stack.md](monitoring-stack.md) |
|
| 1 | **Kuma SMTP** | ✅ done | — | — |
|
||||||
| 2 | **UniFi DHCP reservations** | 20 min | [unifi-static-dhcp.md](unifi-static-dhcp.md) |
|
| 2 | **Cal.com → Authentik OIDC** | ⏳ **next** | 1–2 h | First SSO; test before Vikunja/Listmonk |
|
||||||
| 3 | **Cal.com → Authentik OIDC** | 1–2 h | Phase 3 below |
|
| 3 | **auto.levkin.ca** → Cal booking link | ⏳ | 15 min | Phase 3 item 6 |
|
||||||
| 4 | **Retire Nextcloud VM 201** | 30 min | [nextcloud-export-2026-05-21.md](nextcloud-export-2026-05-21.md) |
|
| 4 | **Stop Portainer VM 109** | ⏳ | 10 min | **~16 GiB RAM** on pve10 |
|
||||||
| 5 | **NAS.SP00** disk replace → Jellyfin | hardware | [nas-sp00-drive-failure-report.md](nas-sp00-drive-failure-report.md) |
|
| 5 | **Retire Nextcloud VM 201** | ⏳ | 30 min | **~8 GiB RAM**; remove Caddy + Kuma monitor |
|
||||||
| 6 | **Caddy → edge LXC `.20`** | ~30 min | Phase 1.5 |
|
| 6 | **UniFi DHCP reservations** | ⏳ | 20 min | [unifi-static-dhcp.md](unifi-static-dhcp.md) |
|
||||||
|
| 7 | **Beszel** on 218 or agents | ⏳ | 1 h | Capacity visibility before Immich |
|
||||||
|
| 8 | **NAS.SP00** disk → Jellyfin | ⏳ hardware | — | VM 101 |
|
||||||
|
| 9 | **Caddy → edge LXC `.20`** | ⏳ defer | ~30 min | Phase 1.5 |
|
||||||
|
| 10 | **dev-apps LXC** (pote, mirrormatch, then punim) | ⏳ defer | half day | pve201 RAM; punim **last** |
|
||||||
|
| 11 | **Static sites → Caddy VM** (optional) | ⏳ defer | 1 h | ~1 GiB; breaks git-on-LXC workflow unless you move deploy to Caddy |
|
||||||
|
|
||||||
**Defer:** Nextcloud SSO, Immich, Crater, Beszel until above are done.
|
**Defer:** Immich, Crater, Outline, Plane, SSO for Vikunja/Listmonk/Mailcow until rows 2–5 done.
|
||||||
|
|
||||||
|
### Adding a new service — quick rule
|
||||||
|
|
||||||
|
| Want to add… | Node | RAM budget | Prerequisite |
|
||||||
|
|--------------|------|------------|--------------|
|
||||||
|
| Small app (Mealie, Linkwarden) | pve10 | 2 GB LXC | Stop 109 and/or 201 first if host feels tight |
|
||||||
|
| Medium (Outline, Crater) | pve10 | 4 GB LXC | Free **~24 GiB** via Portainer + Nextcloud retire |
|
||||||
|
| Heavy (Immich + ML) | pve10 or pve201 GPU | 4–8 GB+ | NAS healthy; pve201 only after GPU/punim sized down |
|
||||||
|
| Dev sandbox | pve10 `dev-apps` | 6–8 GB | punim 9101 migration only after testing |
|
||||||
|
|
||||||
### Nextcloud decommission (VM 201)
|
### Nextcloud decommission (VM 201)
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ All admin UIs are **LAN-only** (no public Caddy blocks). Use Tailscale or local
|
|||||||
|---------|-----|------|-------|
|
|---------|-----|------|-------|
|
||||||
| **Uptime Kuma** | http://10.0.10.22:3001 | 3001 | Admin + monitors configured ✅ (replaces pve201 LXC **305** @ `.197`, stopped) |
|
| **Uptime Kuma** | http://10.0.10.22:3001 | 3001 | Admin + monitors configured ✅ (replaces pve201 LXC **305** @ `.197`, stopped) |
|
||||||
| **Dockge** | http://10.0.10.22:5001 | 5001 | Manage compose on **this LXC only** |
|
| **Dockge** | http://10.0.10.22:5001 | 5001 | Manage compose on **this LXC only** |
|
||||||
| **Umami** | http://10.0.10.22:3000 | 3000 | Password changed ✅; caseware + auto tracked |
|
| **Umami** | http://10.0.10.22:3000 | 3000 | Password changed ✅; levkin.ca + caseware + auto + portfolio tracked |
|
||||||
|
|
||||||
Secrets: `/opt/monitoring/.env` on the LXC (mode 600). Not in git.
|
Secrets: `/opt/monitoring/.env` on the LXC (mode 600). Not in git.
|
||||||
|
|
||||||
@ -195,7 +195,7 @@ When comfortable: stop VM **109** (portainer) on pve10; use Dockge on 218 instea
|
|||||||
## Umami
|
## Umami
|
||||||
|
|
||||||
- ✅ Running at http://10.0.10.22:3000 (LAN / Tailscale only)
|
- ✅ Running at http://10.0.10.22:3000 (LAN / Tailscale only)
|
||||||
- ✅ **Public tracking** via `https://stats.levkin.ca/script.js` on caseware, auto, and **iliadobkin.com** (portfolio LXC 219)
|
- ✅ **Public tracking** via `https://stats.levkin.ca/script.js` on **levkin.ca** (LXC 220), caseware, auto, and **iliadobkin.com** (portfolio LXC 219)
|
||||||
|
|
||||||
**Three choices (pick one later; none block the sites):**
|
**Three choices (pick one later; none block the sites):**
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
# Site LXCs — git deploy (caseware / auto / portfolio)
|
# Site LXCs — git deploy (levkin / caseware / auto / portfolio)
|
||||||
|
|
||||||
## Remotes (correct)
|
## Remotes (correct)
|
||||||
|
|
||||||
Use **`git.levkin.ca`**, not `10.0.30.169`:
|
Use **`git.levkin.ca`**, not `10.0.30.169`:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
git@git.levkin.ca:ilia/levkin.ca.git
|
||||||
git@git.levkin.ca:ilia/caseware.git
|
git@git.levkin.ca:ilia/caseware.git
|
||||||
git@git.levkin.ca:ilia/auto.git
|
git@git.levkin.ca:ilia/auto.git
|
||||||
git@git.levkin.ca:ilia/sdetProfile.git
|
git@git.levkin.ca:ilia/sdetProfile.git
|
||||||
@ -40,6 +41,28 @@ Portfolio uses `~/.ssh/id_ed25519_gitea` in `/root/.ssh/config` for `Host git.le
|
|||||||
| 215 | caseware | `~/.ssh/id_ed25519` → `root@caseware` |
|
| 215 | caseware | `~/.ssh/id_ed25519` → `root@caseware` |
|
||||||
| 216 | auto | `~/.ssh/id_ed25519` → `root@auto` |
|
| 216 | auto | `~/.ssh/id_ed25519` → `root@auto` |
|
||||||
| 219 | sdetProfile | `~/.ssh/id_ed25519_gitea` → `deploy-portfolio-sdetProfile` |
|
| 219 | sdetProfile | `~/.ssh/id_ed25519_gitea` → `deploy-portfolio-sdetProfile` |
|
||||||
|
| 220 | levkin.ca | `~/.ssh/id_ed25519_gitea` → `deploy-levkin-levkin.ca` (add in Gitea UI) or HTTPS clone with read token |
|
||||||
|
|
||||||
|
## levkin.ca routes (LXC 220)
|
||||||
|
|
||||||
|
| Public URL | Served from |
|
||||||
|
|------------|-------------|
|
||||||
|
| `https://levkin.ca/` | `www/index.html` (spec) |
|
||||||
|
| `https://levkin.ca/folders/` | `www/folders/` (stack-folder) |
|
||||||
|
|
||||||
|
Build before push:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ~/Documents/code/levkin.ca
|
||||||
|
npm run build:www
|
||||||
|
git add www/ && git commit -m "Rebuild www" && git push
|
||||||
|
```
|
||||||
|
|
||||||
|
On LXC:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pct exec 220 -- bash -c 'cd /var/www/levkin && git pull origin main'
|
||||||
|
```
|
||||||
|
|
||||||
## Push / pull
|
## Push / pull
|
||||||
|
|
||||||
@ -48,6 +71,7 @@ Portfolio uses `~/.ssh/id_ed25519_gitea` in `/root/.ssh/config` for `Host git.le
|
|||||||
pct exec 215 -- bash -c 'cd /var/www/caseware && git pull origin main && git push origin main'
|
pct exec 215 -- bash -c 'cd /var/www/caseware && git pull origin main && git push origin main'
|
||||||
pct exec 216 -- bash -c 'cd /var/www/auto && git pull origin master && git push origin master'
|
pct exec 216 -- bash -c 'cd /var/www/auto && git pull origin master && git push origin master'
|
||||||
pct exec 219 -- bash -c 'cd /var/www/portfolio && git pull origin master && git push origin master'
|
pct exec 219 -- bash -c 'cd /var/www/portfolio && git pull origin master && git push origin master'
|
||||||
|
pct exec 220 -- bash -c 'cd /var/www/levkin && git pull origin main'
|
||||||
```
|
```
|
||||||
|
|
||||||
After editing `index.html`, commit on the LXC, push, then hard-refresh the public site.
|
After editing `index.html`, commit on the LXC, push, then hard-refresh the public site.
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
**Controller:** https://192.168.2.1/
|
**Controller:** https://192.168.2.1/
|
||||||
**Goal:** Pin Proxmox VM MAC addresses to stable `10.0.10.x` addresses so Caddy and Ansible inventory do not drift.
|
**Goal:** Pin Proxmox VM MAC addresses to stable `10.0.10.x` addresses so Caddy and Ansible inventory do not drift.
|
||||||
|
|
||||||
LXCs on pve10 (**210, 215–219**) are already static via `pct set` — **no UniFi lease needed** for those rows.
|
LXCs on pve10 (**210, 215–220**) are already static via `pct set` — **no UniFi lease needed** for those rows.
|
||||||
This guide is for **VMs** (and pve201 guests) that still use DHCP.
|
This guide is for **VMs** (and pve201 guests) that still use DHCP.
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -58,6 +58,7 @@ This guide is for **VMs** (and pve201 guests) that still use DHCP.
|
|||||||
| 217 | identity | 10.0.10.21 | `pct set` |
|
| 217 | identity | 10.0.10.21 | `pct set` |
|
||||||
| 218 | monitoring | 10.0.10.22 | `pct set` |
|
| 218 | monitoring | 10.0.10.22 | `pct set` |
|
||||||
| 219 | portfolio | 10.0.10.106 | `pct set` (`iliadobkin.com`) |
|
| 219 | portfolio | 10.0.10.106 | `pct set` (`iliadobkin.com`) |
|
||||||
|
| 220 | levkin | 10.0.10.60 | `pct set` (`levkin.ca`) |
|
||||||
| 106 | caddy | 10.0.10.50 | static in `/etc/network/interfaces` |
|
| 106 | caddy | 10.0.10.50 | static in `/etc/network/interfaces` |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@ -1,8 +1,18 @@
|
|||||||
---
|
---
|
||||||
# Configure sudo path for git-ci-01
|
# git-ci-01 — Gitea Actions runner (VM 115 on pve201 @ 10.0.10.223)
|
||||||
# Sudo may not be in PATH for non-interactive shells
|
|
||||||
ansible_become_exe: /usr/bin/sudo
|
ansible_become_exe: /usr/bin/sudo
|
||||||
ansible_become_method: sudo
|
ansible_become_method: sudo
|
||||||
|
|
||||||
# Alternative: if sudo is in a different location, update this
|
# Proxmox (manual / qm): VMID 115, 2 cores, 4096 MB RAM, 64 GB disk (scsi0)
|
||||||
# ansible_become_exe: /usr/local/bin/sudo
|
# act_runner: /etc/act_runner/config.yaml — capacity 2, force_pull false
|
||||||
|
# Maintenance: /etc/cron.weekly/docker-prune-ci (docker system prune -af --filter until=168h)
|
||||||
|
#
|
||||||
|
# Capacity notes (2026-05-23):
|
||||||
|
# - pve201: ~3 GB RAM free (125 Gi total, heavily overcommitted — GPU VM 104 @ 72 Gi)
|
||||||
|
# - capacity 3 needs ~8–12 GB RAM on this VM → migrate runner to pve10 or add RAM after freeing pve201
|
||||||
|
# - 12 repos: capacity 2 on one runner is OK; second runner on pve10 if queues stack up
|
||||||
|
|
||||||
|
git_ci_runner_capacity: 2
|
||||||
|
git_ci_disk_gb: 64
|
||||||
|
git_ci_proxmox_vmid: 115
|
||||||
|
git_ci_proxmox_node: pve201
|
||||||
|
|||||||
@ -13,6 +13,7 @@ pve201 ansible_host=10.0.10.201 ansible_user=root
|
|||||||
pve10 ansible_host=10.0.10.10 ansible_user=root
|
pve10 ansible_host=10.0.10.10 ansible_user=root
|
||||||
|
|
||||||
[sites]
|
[sites]
|
||||||
|
levkin ansible_host=10.0.10.60 ansible_user=root url=https://levkin.ca proxmox_vmid=220 proxmox_node=PVENAS
|
||||||
caseware ansible_host=10.0.10.105 ansible_user=root url=https://caseware.levkin.ca proxmox_vmid=215 proxmox_node=PVENAS
|
caseware ansible_host=10.0.10.105 ansible_user=root url=https://caseware.levkin.ca proxmox_vmid=215 proxmox_node=PVENAS
|
||||||
auto ansible_host=10.0.10.59 ansible_user=root url=https://auto.levkin.ca proxmox_vmid=216 proxmox_node=PVENAS
|
auto ansible_host=10.0.10.59 ansible_user=root url=https://auto.levkin.ca proxmox_vmid=216 proxmox_node=PVENAS
|
||||||
portfolio ansible_host=10.0.10.106 ansible_user=root url=https://iliadobkin.com proxmox_vmid=219 proxmox_node=PVENAS
|
portfolio ansible_host=10.0.10.106 ansible_user=root url=https://iliadobkin.com proxmox_vmid=219 proxmox_node=PVENAS
|
||||||
|
|||||||
55
playbooks/caddy-levkin-site.yml
Normal file
55
playbooks/caddy-levkin-site.yml
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
---
|
||||||
|
# Playbook: caddy-levkin-site
|
||||||
|
# Purpose: Add levkin.ca reverse proxy to Caddy (site LXC 220)
|
||||||
|
# Targets: caddy
|
||||||
|
# Usage: make caddy-levkin
|
||||||
|
|
||||||
|
- name: Add levkin.ca proxy block to Caddy
|
||||||
|
hosts: caddy
|
||||||
|
become: true
|
||||||
|
become_method: ansible.builtin.su
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Ensure levkin.ca HTTPS block exists (after caseware block)
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
set -euo pipefail
|
||||||
|
if grep -q '^levkin\.ca,' /etc/caddy/Caddyfile || grep -q '^levkin\.ca {' /etc/caddy/Caddyfile; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
awk -v upstream="{{ levkin_site_upstream | default('10.0.10.60:80') }}" '
|
||||||
|
/^caseware\.levkin\.ca \{/ { in_cw=1 }
|
||||||
|
in_cw && /^}$/ && !done {
|
||||||
|
print
|
||||||
|
print ""
|
||||||
|
print "levkin.ca, www.levkin.ca {"
|
||||||
|
print " import security-headers"
|
||||||
|
print " @www host www.levkin.ca"
|
||||||
|
print " redir @www https://levkin.ca{uri} permanent"
|
||||||
|
print " reverse_proxy " upstream
|
||||||
|
print "}"
|
||||||
|
done=1
|
||||||
|
next
|
||||||
|
}
|
||||||
|
{ print }
|
||||||
|
' /etc/caddy/Caddyfile > /tmp/Caddyfile.new
|
||||||
|
mv /tmp/Caddyfile.new /etc/caddy/Caddyfile
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
register: levkin_https_block
|
||||||
|
changed_when: levkin_https_block.rc == 0
|
||||||
|
notify: Reload caddy
|
||||||
|
|
||||||
|
- name: Ensure levkin.ca HTTP redirect in :80 block
|
||||||
|
ansible.builtin.blockinfile:
|
||||||
|
path: /etc/caddy/Caddyfile
|
||||||
|
marker: "# {mark} ANSIBLE MANAGED levkin.ca :80"
|
||||||
|
insertafter: '@vikunja host todo.levkin.ca'
|
||||||
|
block: |
|
||||||
|
@levkin host levkin.ca www.levkin.ca
|
||||||
|
redir @levkin https://levkin.ca{uri} permanent
|
||||||
|
notify: Reload caddy
|
||||||
|
|
||||||
|
handlers:
|
||||||
|
- name: Reload caddy
|
||||||
|
ansible.builtin.command: caddy reload --config /etc/caddy/Caddyfile
|
||||||
|
changed_when: true
|
||||||
Loading…
x
Reference in New Issue
Block a user