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

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:
ilia 2026-05-22 22:38:56 -04:00
parent 35d17ed527
commit f0ff00a8dc
10 changed files with 204 additions and 30 deletions

View File

@ -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=""; \

View File

@ -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 (~12 h) — [levkin-selfhost-plan-2.md](levkin-selfhost-plan-2.md) - [ ] **Cal.com → Authentik OIDC** — first SSO (~12 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` |

View File

@ -41,6 +41,7 @@ Update this file whenever a guest is created, migrated, or re-IPd. 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-IPd. 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 | ✅ |

View File

@ -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 58** 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 **23 small LXCs** (2 GB each) as-is |
**Realistic new capacity on pve10 (without stopping anything):** ~**46 GiB RAM** + **100200 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 (68 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, 215218, 219** — static via `pct set`; **Caddy VM 106** — static in-guest `.50` - LXC **210, 215218, 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 12 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** | 12 h | First SSO; test before Vikunja/Listmonk |
| 3 | **Cal.com → Authentik OIDC** | 12 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 25 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 | 48 GB+ | NAS healthy; pve201 only after GPU/punim sized down |
| Dev sandbox | pve10 `dev-apps` | 68 GB | punim 9101 migration only after testing |
### Nextcloud decommission (VM 201) ### Nextcloud decommission (VM 201)

View File

@ -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):**

View File

@ -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.

View File

@ -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, 215219**) are already static via `pct set`**no UniFi lease needed** for those rows. LXCs on pve10 (**210, 215220**) 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` |
--- ---

View File

@ -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 ~812 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

View File

@ -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

View 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