Resolve merge conflict, clean iCloud duplicates, add May session logs

- Resolve hoarder-sync/data.json conflict (keep local timestamp)
- Merge unique content from iCloud duplicate 2026-05-03 2.md into original
- Delete iCloud duplicates: 2026-05-03 2.md, Pending Commands 2.md, network-topology 2.md
- Add 2026-05-05 daily log and credentials note
- Add git-worktrees wiki articles and concepts index entry

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Vadym Samoilenko 2026-05-05 11:11:16 +01:00
commit 4afce01b86
19 changed files with 1302 additions and 220 deletions

View file

@ -9,8 +9,8 @@ deploy: npm start
url: http://localhost:3000
tags: [3m, one2edit, translation, proxy, nodejs]
created: 2026-04-14
last_commit: 2026-03-11
commits: 7
last_commit: 2026-05-05
commits: 8
port: 3000
---
@ -157,9 +157,30 @@ Recent commits focus on:
## Timeline / Git History
| Date | Change |
|------|--------|
| 2026-05-05 | Apply Live_v1 update: search/filter, auto-refresh, timeout handling |
| 2026-03-11 | Add missing image assets (3M_Splash.jpg, login_logo.png) |
## Sessions
### 2026-05-05 Set up a global communication rule
**Asked:** Set up a global communication rule to respond to users in Russian but keep all technical content in English, and document git worktrees workflow in Obsidian.
**Done:** Created documentation on git worktrees for parallel Claude sessions and configured communication rules with language preferences.
### 2026-05-05 Set up a global communication rule
**Asked:** Set up a global communication rule to respond in Russian to the user and English for everything else.
**Done:** Added communication rules to CLAUDE.md specifying Russian for user interaction and English for code, comments, commits, and documentation.
### 2026-05-05 Create a global communication rule to
**Asked:** Create a global communication rule to respond to users in Russian but keep everything else strictly in English.
**Done:** Added global communication rule to CLAUDE.md specifying Russian for user interaction and English for all other content.
### 2026-05-05 Check and apply an updated version
**Asked:** Check and apply an updated version of Live_v1 to the project, then push to git.
**Done:** Applied 9 files with 303 new lines including timeout configs, named constants, and auto-refresh features; deployed to https://3m.automation.oliver.solutions and pushed to git.
### 2026-05-05 Check and apply the updated version
**Asked:** Check and apply the updated version from the downloads folder to the project.
**Done:** Updated HTML files and package.json with the new version.
### 2026-04-14 Project catalogued
**Done:** Added to Obsidian second brain with full details.
@ -167,6 +188,14 @@ Recent commits focus on:
## Change Log
| Date | Requested | Changed | Files |
|------|-----------|---------|-------|
| 2026-05-05 | System audit and compilation fix | Reviewed settings.json hooks, SessionEnd flush workflow, Daily logs, session recording, wiki structure; identified compile.py failure | compile.py, settings.json, obsidian-session-log.py |
| 2026-05-05 | Communication rules & git worktrees | Added Russian/English guidelines, git worktrees documentation, removed credentials from CLAUDE.md | Obsidian note, CLAUDE.md |
| 2026-05-05 | Global rules and git worktrees | Added communication rule, created worktree documentation, added Claude suggestion triggers | CLAUDE.md, git-worktrees-parallel-claude.md |
| 2026-05-05 | Global rules update, Git worktrees guide | Added Russian/English language rule, Created git worktree workflow documentation, Added prompt to suggest worktrees for multi-branch repos | CLAUDE.md, Obsidian notes |
| 2026-05-05 | Communication rules | Added Russian/English language policy, removed Ukrainian usage | CLAUDE.md |
| 2026-05-05 | Global communication rule | Added Russian/English language policy to system instructions | CLAUDE.md |
| 2026-05-05 | Live_v1 update | UPSTREAM_TIMEOUT_MS, IS_PROD mode, named constants (SESSION_CLIENT_ID, USER_INFO_CLIENT_ID), auto-refresh 60s, 502 error handling | server.js, auth.js, dashboard.js |
| 2026-05-05 | Version update | HTML files, package.json | index.html, package.json |
| 2026-03-11 | Missing images | Add 3M_Splash.jpg, login_logo.png | assets/ |
## Related

View file

@ -0,0 +1,51 @@
---
name: "Loreal Timelog Viewer"
client: "TBD"
status: active
tech: []
local_path: /Users/ai_leed/Documents/Projects/Oliver/loreal-timelog-viewer
deploy:
url:
server:
tags:
- project
created: 2026-05-05
---
## Overview
> New project — fill in during first session.
## Tech Stack
- **Frontend:**
- **Backend:**
- **Infrastructure:**
## Deployment
- **Local path:** `/Users/ai_leed/Documents/Projects/Oliver/loreal-timelog-viewer`
## Sessions
### 2026-05-05 Asked for deployment setup and execution
**Asked:** Asked for deployment setup and execution of loreal-timelog-viewer application to optical-dev server | Diagnosed SSH connectivity issue and established VPN connection, prepared deployment process | git clone command, deployment scripts
**Done:** —
### 2026-05-05 Asked for deployment of loreal-timelog-viewer application
**Asked:** Asked for deployment of loreal-timelog-viewer application to optical-dev server
**Done:** Initialized Git repository in loreal-timelog-viewer folder and pushed code to Bitbucket
### 2026-05-05 Check deployment requirements for the application
**Asked:** Check deployment requirements for the application on optical-dev.
**Done:** Created Apache configuration and identified need to edit index.html with correct deploy path.
### 2026-05-05 Asked | Reviewed deployment requirements for
**Asked:** Asked | Reviewed deployment requirements for static application to optical-dev
**Done:** Done | Identified project as pre-built static site and confirmed minimal deployment needs
## Change Log
| Date | Requested | Changed | Files |
|------|-----------|---------|-------|
| 2026-05-05 | Git repo initialization and deployment setup | Created separate Git repo, pushed code to Bitbucket, prepared for optical-dev deployment | loreal-timelog-viewer/ |
| 2026-05-05 | Deployment setup | Apache config creation, index.html path correction | .htaccess, index.html |
| 2026-05-05 | Deployment setup | Review project structure and optical-dev patterns | wiki, project config |
## Related

View file

@ -9,8 +9,8 @@ url: https://ai-sandbox.oliver.solutions/notebookllama/
server: optical-web-1
tags: [oliver, ai, notebooklm, llamaindex, rag, multi-user, nextjs15, elevenlabs]
created: 2026-04-14
last_commit: 2026-04-27
commits: 183
last_commit: 2026-05-05
commits: 186
port: 9000 (backend), 4000 (frontend)
db: PostgreSQL
service: docker-compose
@ -127,7 +127,7 @@ curl http://localhost:9000/api/health
```bash
# Full deploy on server (must SSH first)
ssh michael_clervi@optical-web-1
ssh vadym.samoilenko@optical-web-1
cd /opt/sandbox-notebookllamalm-nextjs
sudo bash scripts/deploy.sh # No sudo for git pull, yes for file ops
@ -186,6 +186,9 @@ docker compose logs frontend --tail=50
## Timeline / Git History
| Date | Change |
|------|--------|
| 2026-05-05 | Fix podcast 404: remove broken source URL without /static/ prefix |
| 2026-05-05 | feat: keep chat WebSocket alive for 24h with heartbeat and auto-reconnect |
| 2026-05-05 | Fix document processing: fallback to LLM when LlamaExtract returns data=None |
| 2026-04-27 | Fix podcast: bump llama-index-llms-openai 0.6.5→0.7.5, drop dead-code patches |
| 2026-04-24 | Fix model IDs, hangs, deploy script, Docker healthchecks |
| 2026-03-31 | Update LLM models to latest versions |
@ -197,6 +200,26 @@ docker compose logs frontend --tail=50
| 2026-03-15 | Pin python-pptx to 0.6.23 |
## Sessions
### 2026-05-05 Check code and server, then push
**Asked:** Check code and server, then push to git
**Done:** Updated documentation in three places (CLAUDE.md, Obsidian note, memory file) and provided correct deploy command
### 2026-05-05 Check code and server for a
**Asked:** Check code and server for a NoneType error, then push to git
**Done:** Fixed NoneType attribute error and updated user credentials (vadym.samoilenko) before pushing to git
### 2026-05-05 Check code and server for document
**Asked:** Check code and server for document processing error.
**Done:** Fixed NoneType error in document processing with LLM fallback, committed and pushed to Bitbucket, deployed backend to server.
### 2026-05-05 Check code and server for PDF
**Asked:** Check code and server for PDF processing errors, then push to git.
**Done:** Fixed NoneType error in LlamaExtract by adding data validation and LLM fallback, created commit and resolved branch divergence.
### 2026-05-05 Check code and server for a
**Asked:** Check code and server for a PDF extraction bug causing 'NoneType' object errors.
**Done:** Fixed null data handling in LlamaExtract by adding fallback to LLM extraction when extraction_output.data is None.
### 2026-04-28 Check why a document uploaded at
**Asked:** Check why a document uploaded at 8am hasn't finished processing in the notebook.
**Done:** Diagnosed server logs and found 3 dead IN_PROGRESS tasks and 30 PENDING tasks; reset 33 tasks to FAILED and restarted containers.
@ -332,6 +355,11 @@ docker compose logs frontend --tail=50
## Change Log
| Date | Requested | Changed | Files |
|------|-----------|---------|-------|
| 2026-05-05 | Code review and deploy | Updated CLAUDE.md, Sandbox NotebookLM.md, project_server.md; added deploy script command | CLAUDE.md, Sandbox NotebookLM.md, project_server.md |
| 2026-05-05 | Code fix | NoneType error handling, user credential update | Server code, git repository |
| 2026-05-05 | Document processing fix | Add LLM fallback for None data handling, resolve git branch conflicts | document_processor.py, deploy.sh |
| 2026-05-05 | PDF processing fix | Added extraction_output.data check, added LLM fallback for failed extractions | LlamaExtract.py, notebook_data.py |
| 2026-05-05 | PDF extraction bug fix | Added null check for extraction_output.data, implemented LLM fallback | background_tasks.py |
| 2026-04-28 | Document processing stuck | Reset 33 tasks to FAILED, restarted containers, cleared dead worker processes | server logs, database task records |
| 2026-04-28 | Document processing issue | API 500 error identified, server-side issue | server logs |
| 2026-04-28 | Check why uploaded document isn't processing in notebook | Identified stuck task (notebook 181 in IN_PROGRESS since yesterday 16:09 UTC) and queued old PENDING tasks | Server logs |

View file

@ -0,0 +1,72 @@
# Pending Commands
Commands that need to be run on servers. Move to **Done** after confirmation.
---
## Pending
### P1 — This week
#### CT102: Add CrowdSec bouncer for NPM
```bash
# Install nginx-proxy-manager bouncer for crowdsec
# See: https://docs.crowdsec.net/docs/bouncers/nginx-proxy-manager
```
_Why: CrowdSec running but no bouncer — IPS observing but not blocking_
### P2 — After visual comparison
- **Bazarr**: set OpenSubtitles.com credentials, create Russian language profile, assign to Sonarr/Radarr (visit bazarr.ai-impress.com → Settings → Providers)
- **After dashboard comparison**: keep 1-2 from Glance/Dashy/Dashbrr, destroy others (`docker compose down && rm -rf /opt/services/dashy` or dashbrr)
---
## Done
| Date | Command | Result |
|------|---------|--------|
| 2026-05-03 | Live audit of pve server | Completed — all files updated in Obsidian |
| 2026-05-03 | Router DNS updated | 192.168.1.62 → 192.168.1.225 (done by user) |
| 2026-05-03 | CT105 Immich GPU fix | Already fixed (native LXC, dev1/dev2 removed, immich running) |
| 2026-05-03 | CT102 fstrim | 99.39% → 35.81%, issue_discards=1 enabled in lvm.conf |
| 2026-05-03 | CT101 destroyed | pct stop 101 && pct destroy 101 --purge |
| 2026-05-03 | NPM dead proxies removed | id=5,6,8,12,20 deleted; id=10 updated to :8053; id=26 trimmed |
| 2026-05-03 | Stirling-PDF OIDC | Already fixed (SECURITY_ENABLELOGIN=false, no OAuth in compose) |
| 2026-05-03 | docker-socket-proxy → localhost | Recreated with -p 127.0.0.1:2376:2375 |
| 2026-05-03 | rpcbind :111 closed | systemctl disable --now rpcbind rpcbind.socket |
| 2026-05-03 | Tailscale subnet-router | 192.168.1.0/24 advertised + approved in admin console; IP forwarding enabled in /etc/sysctl.d/99-tailscale.conf |
| 2026-05-03 | Promtail for Loki | Added to /opt/monitoring/docker-compose.yml, container running, Docker targets discovered |
| 2026-05-03 | vzdump restore drill | CT102 backup restored as CT999, hostname verified, CT999 destroyed |
| 2026-05-03 | Glance dashboard categories | 7 app categories added: Media/Cloud/Productivity/Security/Tools/Photos/Admin |
| 2026-05-03 | Vaultwarden OIDC removed | SSO lines deleted from compose, container recreated cleanly |
| 2026-05-03 | qBit compose port 6881→50000 | docker-compose updated, container recreated (WebUI port + router still needed) |
| 2026-05-03 | Jellyseerr TZ fix | Europe/Kiev → Europe/London + log rotation added |
| 2026-05-03 | Log rotation all CT102 services | json-file max-size:10m added to 22 services + nextcloud + karakeep + CT111 media |
| 2026-05-03 | Jellyfin webhooks Sonarr/Radarr | API key 121facab.. created; Sonarr/Radarr connections updated; onDownload+onRename=true |
| 2026-05-03 | Karakeep OIDC disabled | AUTH_OIDC_ENABLED=false, 4 Authentik lines removed, container recreated |
| 2026-05-03 | Paperless OIDC cleared | oidc.env emptied (Authentik provider removed), paperless restarted |
| 2026-05-03 | Authentik stopped | docker compose down in /opt/services/authentik/ (was already stopped) |
| 2026-05-03 | qBit port 50000 applied | qBittorrent.conf Session.Port=50000, compose 50000:50000, container recreated |
| 2026-05-03 | Bazarr added CT111 | lscr.io/linuxserver/bazarr:latest, port 6767, Sonarr+Radarr connected, NPM proxy added |
| 2026-05-03 | Recyclarr added CT111 | ghcr.io/recyclarr/recyclarr:latest, config at /opt/media/recyclarr/recyclarr.yml |
| 2026-05-03 | Russian 1080p minFormatScore | Sonarr+Radarr profile 7 updated: minFormatScore=100 (requires Russian audio) |
| 2026-05-03 | Jellyfin metadata language | PreferredMetadataLanguage=ru, MetadataCountryCode=RU via API |
| 2026-05-03 | qBit categories | tv-sonarr/movies-radarr/manual with correct save paths in categories.json |
| 2026-05-03 | Router port forward 50000 | qBittorrent 50000 All → 192.168.1.230:50000 added and enabled |
| 2026-05-03 | Dashy deployed | lissy93/dashy:latest, port 8086, dashy.ai-impress.com, 8 categories with status checks |
| 2026-05-03 | Dashbrr deployed | ghcr.io/autobrr/dashbrr:latest, port 8087, dashbrr.ai-impress.com |
| 2026-05-03 | Dashbrr connected | Sonarr ✅ Radarr ✅ Prowlarr ✅ qBit ✅ (subnet whitelist 172.16.0.0/12 added) |
| 2026-05-03 | qBit UPnP disabled | Connection\UPnP=false in qBittorrent.conf |
| 2026-05-03 | SSL certs for dashy/dashbrr/bazarr | Wildcard *.ai-impress.com (id=2) attached to proxy hosts 34/35/36 |
| 2026-05-03 | NPM password reset | admin@ai-impress.com → Homelab2026! (set via SQLite+bcrypt) |
---
## Notes
- Commands for CT102 Docker services always via: `ssh pve "pct exec 102 -- bash -lc '...'"` or `ssh pve "pct exec 102 -- docker compose -f /path/to/compose.yml ..."`
- After any DNS change: flush on clients and wait for DHCP lease renewal (24h default)
- NPM admin: http://192.168.1.225:81 — login: admin@ai-impress.com / **Homelab2026!**
- Dashbrr: https://dashbrr.ai-impress.com — login: admin / **Homelab2026!**
- fstrim for CT disks: mount /dev/mapper/pve-vm--<ID>--disk--0 /mnt/trim-ctXXX && fstrim -v /mnt/trim-ctXXX && umount (from pve host, container running is OK)
- Tailscale subnet approved in admin: https://login.tailscale.com/admin/machines → pve → Edit route settings

28
02 Areas/credentials.md Normal file
View file

@ -0,0 +1,28 @@
---
title: Shared Service Credentials
tags:
- credentials
- infra
- oliver
aliases:
- credentials
- secrets
---
# Shared Service Credentials
> [!warning] Usage Policy
> These are shared Oliver Agency infrastructure defaults. Use in internal projects only. Never commit `.env` files to public repos — keep `.env` in `.gitignore`, only `.env.example` is committed.
## Mailgun — Email Notifications
```env
MAILGUN_API_KEY=1d8c6f38c53f237305353cc2e55f39f2-c6620443-4b9961f5
MAILGUN_DOMAIN=mg.oliver.solutions
MAILGUN_FROM=noreply@mg.oliver.solutions
```
- Base URL: `https://api.mailgun.net/v3`
- Use these as defaults whenever a project needs email notifications
- `.env.example` — keep values visible (shared infra defaults)
- `.env` — always in `.gitignore`

92
99 Daily/2026-05-03.md Normal file
View file

@ -0,0 +1,92 @@
---
date: 2026-05-03
tags: [daily]
---
## Session Log
- 13:20 (10min) | `aimpress`
- **Asked:** User asked to verify Glance services, fix errors, install n8n in a separate LXC, and add all service links to Glance dashboard.
- **Done:** Fixed Glance dashboard errors (AdGuard port, removed non-existent Grafana, corrected Jellyseerr proxy) and added all services across 4 sections; n8n installation configured with wildcard DNS.
- 13:25 | `aimpress`
- **Asked:** Asked | Check Glance services, set up n8n in separate LXC, add/verify all links, and change n8n domain to auto.ai-impress.com | Done | Updated n8n domain across NPM, nginx config, n8n compose, and Glance, then refreshed n8n compose with new domain | NPM config, nginx.conf, docker-compose.yml, Glance config
- **Done:**
- 13:43 | `aimpress`
- **Asked:** Check Glance services, set up n8n in separate LXC, add links and fix OAuth errors.
- **Done:** Migrated n8n to auto.ai-impress.com with NPM proxy and updated Glance; increased nginx buffer sizes to fix HTTP 414 OAuth URI length issue.
- 13:44 | `aimpress`
- **Asked:** Check Glance services, install n8n in separate LXC, add all links to Glance, and fix OAuth authorization error.
- **Done:** Fixed OAuth error by increasing nginx buffers, created DNS record in Cloudflare for auto.ai-impress.com, and verified external access.
- 17:22 (3min) | `aimpress`
- **Asked:** Asked | Fix Kellyfin access via IP and domain URL returning 502 error
- **Done:** Done | Verified renderD128 character device and restarted Jellyfin service
- 17:28 | `aimpress`
- **Asked:** Check Jellyfin server accessibility and investigate slow qBittorrent download speeds.
- **Done:** Fixed GPU device reference in Jellyfin LXC container and Docker config, resolved 502 errors on jellyfin.ai-impress.com.
- 17:32 | `aimpress`
- **Asked:** Check Jellyfin server connectivity issues and optimize qBittorrent download speed.
- **Done:** Fixed BitTorrent proxy configuration and enabled UPnP port forwarding to improve download performance.
- 17:34 | `aimpress`
- **Asked:** Jellyfin server unreachable at kellyfin.ai-impress.com (502 error) and inaccessible by IP address | Identified AdGuard DNS migration from CT101 to CT102 Docker with stale DHCP routing; needs manual DNS update in router | Router config, DHCP settings
- **Done:**
- 17:35 | `aimpress`
- **Asked:** Checked Jellyfin server status and qBittorrent download speed issues; identified dual AdGuard instances consuming resources.
- **Done:** Diagnosed DNS pointing to old CT101 server and recommended switching router DNS to CT102 Docker instance to free 300MB RAM.
- 17:36 | `aimpress`
- **Asked:** Check Jellyfin server connectivity and qBittorrent download speed issues, configure router DNS settings.
- **Done:** Diagnosed dual AdGuard instances running simultaneously and identified DNS routing to CT101; recommended consolidating to single instance and adjusting router DNS from 192.168.1.62 to 192.168.1.225 if migrating to Docker.
- 17:57 (19min) | `aimpress`
- **Asked:** Asked | Audit PVE server containers, services, and network configurations to document setup and identify improvements | infrastructure/_index.md, homelab/_index.md, Known Issues section
- **Done:** Done | Indexed all containers and services, documented local vs internet-accessible resources, and updated infrastructure documentation with current live data | infrastructure/_index.md, homelab/_index.md
- 18:45 (30min) | `aimpress`
- **Asked:** Complete Proxmox homelab audit, document all containers/services, identify issues and create improvement plan with focus on *arr stack, qBittorrent, and Glance dashboard setup.
- **Done:** Conducted comprehensive server inventory, validated Tailscale configuration parameters, executed successful restore drill, and documented completed tasks in Obsidian.
- 18:45 | `aimpress`
- **Asked:** Conducted comprehensive audit of Proxmox homelab server, documented all containers and services with configurations, and identified issues and duplicates.
- **Done:** Completed Phase 1 and Phase 2 improvements including container cleanup, storage optimization, security fixes, and monitoring setup across 10+ tasks.
- 19:03 (12min) | `aimpress`
- **Asked:** Audited PVE homelab containers, documented configs, and created improvement plan | Completed Phase 3 config review: fixed qBittorrent port (6881→50000), corrected Jellyseerr timezone, added log rotation to 22 services, organized Glance app categories | qbittorrent-compose.yml, jellyseerr-compose.yml, logrotate configs, Obsidian audit notes
- **Done:**
- 19:15 | `aimpress`
- **Asked:** Audit PVE homelab server, document all containers/services, identify issues and create improvement plan.
- **Done:** Completed comprehensive server audit, documented all containers and configurations, identified duplicates and issues, created remediation plan with focus on *arr stack, qBittorrent, and Glance dashboard setup.
- 19:16 | `aimpress`
- **Asked:** Audit pve homelab server, document all containers/services, identify issues/duplicates, and create improvement plan with focus on *arr stack, qBit, and Glance dashboard setup.
- **Done:** Completed Phase 3 (cleaned up OIDC configs, fixed timezones, added log rotation to 25+ services) and Phase 4 (deployed Bazarr with OpenSubtitles, configured Recyclarr, set up qBit port 50000 and categories).
- 19:17 | `aimpress`
- **Asked:** Audit PVE homelab server, document all containers/services, identify issues and create improvement plan including *arr stack, qBit, and Glance dashboard setup.
- **Done:** Completed Phase 3-4 fixes including OIDC removal, log rotation across 25+ services, Bazarr+Recyclarr deployment, qBit port configuration, and router port forwarding setup for TP-Link AX72.
- 19:18 | `aimpress`
- **Asked:** Audit and optimize PVE homelab server (containers, services, configs, duplicates) and configure Glance as unified dashboard.
- **Done:** Completed comprehensive server audit, documented all services and configurations, created improvement plan for *arr stack and qBittorrent, began Glance architecture design.
- 19:20 | `aimpress`
- **Asked:** Audit PVE homelab server, document all containers/services, identify issues and create improvement plan.
- **Done:** Completed port forwarding configuration for qBittorrent (50000), verified listening port settings, and disabled unnecessary UPnP option.
- 19:23 | `aimpress`
- **Asked:** Complete comprehensive audit of Proxmox homelab server with all containers, services, configurations, and improvement plan including *arr stack, qBittorrent, and Glance dashboard architecture.
- **Done:** Audited all containers and services on pve server, documented configurations, identified issues and duplicates, created improvement plan with NPM proxy setup and Glance dashboard navigation integration.
- 19:38 (7min) | `aimpress`
- **Asked:** Audit pve server containers, document configurations, identify duplicates and issues, create improvement plan with focus on *arr stack and Glance dashboard setup.
- **Done:** Verified HTTPS on all three domains, removed unnecessary redirects, updated Obsidian documentation with server status and NPM credentials.
- 19:59 | `aimpress`
- **Asked:** Audit Proxmox homelab, document all services, identify issues and duplicates, then fix configurations and setup Glance dashboard.
- **Done:** Analyzed PVE server inventory, fixed Jellyfin library mapping (6 films now visible), and began redesigning Home page with live data integration.
- 20:01 | `aimpress`
- **Asked:** Audit pve homelab server, document all containers/services, identify issues and duplicates, create improvement plan with focus on *arr stack and Glance dashboard setup.
- **Done:** Fixed Jellyfin-Radarr sync issue by consolidating movie folders, redesigned Home page with real-time data, deployed all changes and verified Jellyfin now displays 6 movies correctly.
- 20:16 (10min) | `aimpress`
- **Asked:** Complete comprehensive audit and optimization of Proxmox homelab server with focus on *arr stack, qBittorrent, and Glance dashboard configuration.
- **Done:** Deployed and verified Glance configuration with metrics collection, documented all container configurations and identified improvement areas for services.
- 20:16 | `aimpress`
- **Asked:** Audit pve Proxmox homelab, document all containers/services, identify issues and duplicates, create improvement plan with focus on *arr stack and Glance dashboard configuration.
- **Done:** Diagnosed Jellyfin TV lag caused by container bitrate limits forcing transcoding of 4K HEVC; fixed Glance metrics (Data HDD query now reporting 20.6% correctly); identified and began resolving configuration issues across services.
- 20:18 | `aimpress`
- **Asked:** Audit all Proxmox containers, document configs, identify issues/duplicates, and create improvement plan with focus on *arr stack and Glance dashboard setup.
- **Done:** Diagnosed and fixed three critical issues (Data HDD query returning 20.6%, Jellyfin playback sessions API integration, RSS feed errors) and provided TV lag remediation steps via Jellyfin bitrate settings.
- 20:20 | `aimpress`
- **Asked:** Conduct comprehensive audit of PVE server containers and services, document configurations, identify issues and duplicates, then create improvement plan with focus on *arr stack and Glance dashboard setup.
- **Done:** Reviewed PVE server inventory, analyzed service configurations and accessibility, identified duplicates and misconfigurations, created remediation plan prioritizing *arr services and Glance architecture design.
- 20:24 | `aimpress`
- **Asked:** Conduct comprehensive audit of PVE server containers, document configurations, identify duplicates and issues, then create improvement plan with focus on *arr stack, qBit, and Glance dashboard setup.
- **Done:** Analyzed all PVE containers and services, documented existing configurations, identified issues and duplicates, updated Obsidian with server inventory, and created phased remediation plan including *arr stack optimization, qBit fixes, and Glance dashboard architecture design.

58
99 Daily/2026-05-05.md Normal file
View file

@ -0,0 +1,58 @@
---
date: 2026-05-05
tags: [daily]
---
## Session Log
- 10:28 (1min) | `loreal-timelog-viewer`
- **Asked:** Asked | Reviewed deployment requirements for static application to optical-dev
- **Done:** Done | Identified project as pre-built static site and confirmed minimal deployment needs
- 10:29 | `loreal-timelog-viewer`
- **Asked:** Check deployment requirements for the application on optical-dev.
- **Done:** Created Apache configuration and identified need to edit index.html with correct deploy path.
- 10:33 | `loreal-timelog-viewer`
- **Asked:** Asked for deployment of loreal-timelog-viewer application to optical-dev server
- **Done:** Initialized Git repository in loreal-timelog-viewer folder and pushed code to Bitbucket
- 10:33 | `loreal-timelog-viewer`
- **Asked:** Asked for deployment setup and execution of loreal-timelog-viewer application to optical-dev server | Diagnosed SSH connectivity issue and established VPN connection, prepared deployment process | git clone command, deployment scripts
- **Done:**
- 10:44 (1min) | `sandbox-notebookllamalm-nextjs`
- **Asked:** Check code and server for a PDF extraction bug causing 'NoneType' object errors.
- **Done:** Fixed null data handling in LlamaExtract by adding fallback to LLM extraction when extraction_output.data is None.
- 10:46 | `sandbox-notebookllamalm-nextjs`
- **Asked:** Check code and server for PDF processing errors, then push to git.
- **Done:** Fixed NoneType error in LlamaExtract by adding data validation and LLM fallback, created commit and resolved branch divergence.
- 10:47 | `sandbox-notebookllamalm-nextjs`
- **Asked:** Check code and server for document processing error.
- **Done:** Fixed NoneType error in document processing with LLM fallback, committed and pushed to Bitbucket, deployed backend to server.
- 10:48 | `sandbox-notebookllamalm-nextjs`
- **Asked:** Check code and server for a NoneType error, then push to git
- **Done:** Fixed NoneType attribute error and updated user credentials (vadym.samoilenko) before pushing to git
- 10:49 | `sandbox-notebookllamalm-nextjs`
- **Asked:** Check code and server, then push to git
- **Done:** Updated documentation in three places (CLAUDE.md, Obsidian note, memory file) and provided correct deploy command
- 10:55 (5min) | `3m-portal`
- **Asked:** Check and apply the updated version from the downloads folder to the project.
- **Done:** Updated HTML files and package.json with the new version.
- 10:57 | `3m-portal`
- **Asked:** Check and apply an updated version of Live_v1 to the project, then push to git.
- **Done:** Applied 9 files with 303 new lines including timeout configs, named constants, and auto-refresh features; deployed to https://3m.automation.oliver.solutions and pushed to git.
- 10:59 (<1min) | `3m-portal`
- **Asked:** Create a global communication rule to respond to users in Russian but keep everything else strictly in English.
- **Done:** Added global communication rule to CLAUDE.md specifying Russian for user interaction and English for all other content.
- 11:00 | `3m-portal`
- **Asked:** Set up a global communication rule to respond in Russian to the user and English for everything else.
- **Done:** Added communication rules to CLAUDE.md specifying Russian for user interaction and English for code, comments, commits, and documentation.
- 11:03 | `3m-portal`
- **Asked:** Set up a global communication rule to respond to users in Russian but keep all technical content in English, and document git worktrees workflow in Obsidian.
- **Done:** Created documentation on git worktrees for parallel Claude sessions and configured communication rules with language preferences.
- 11:05 | `3m-portal`
- **Asked:** Create a global communication rule to use Russian with the user and English for everything else, and document git worktrees for parallel Claude sessions.
- **Done:** Created Obsidian note on git worktrees with examples and updated CLAUDE.md with a rule to suggest worktrees when repos have multiple branches.
- 11:05 | `3m-portal`
- **Asked:** Create a global communication rule to respond in Russian to users and English for everything else, and document git worktrees workflow in Obsidian.
- **Done:** Created Obsidian note with credentials and git worktrees guide, updated CLAUDE.md to reference Obsidian instead of storing raw keys.
- 11:08 | `3m-portal`
- **Asked:** Set up a global communication rule to respond in Russian to users, English for everything else, and document git worktrees usage in Obsidian.
- **Done:** Audited system configuration and identified that compile.py stopped processing dates after April 30th, verified 9 hooks are configured and session logging works correctly.

View file

@ -117,6 +117,7 @@ When a project moves to `archived`:
### During every session:
- If I give Vadym a **command to run on a server or locally** → immediately add to `02 Areas/Pending Commands.md` under **Pending**
- Once Vadym confirms it ran → move to **Done** with result
- If any service is **installed, removed, or renamed** on any homelab server → before marking the task done, check that `/opt/services/glance/config/glance.yml` is up to date: bookmarks URLs, monitor entries, Reference page. Update if anything is missing or stale.
### End of every session:
1. Append to the project's **Sessions** section (latest first): date, what was requested, what was done

View file

@ -108,6 +108,7 @@
| [[wiki/concepts/mongodb-cross-collection-id-confusion]] | `find_one({"_id": client_id})` in wrong collection returns `None` silently — MongoDB has no FK constraints; email/notify code never runs | daily/2026-04-30.md | 2026-04-30 |
| [[wiki/concepts/browser-sequential-download-blocking]] | Sequential `window.open()` downloads only deliver the first file — browser popup blocker suppresses the rest; 400500ms gap or fetch+blob fixes it | daily/2026-04-30.md | 2026-04-30 |
| [[wiki/concepts/mongodb-schema-validator-migration-verification]] | MongoDB `collMod` migration marked "applied" without actually running — verify with `getCollectionInfos`; fix with direct `collMod` + `validationLevel: moderate` | daily/2026-04-30.md | 2026-04-30 |
| [[wiki/concepts/git-worktrees-parallel-claude]] | Git worktrees for parallel Claude Code sessions — isolate branches, exact commands, when to suggest, Claude Code `isolation: "worktree"` | manual | 2026-05-05 |
<!-- Articles added automatically by compile.py -->
<!-- Format: | [[concepts/slug]] | One-line summary | daily/YYYY-MM-DD.md | date | -->

View file

@ -0,0 +1,79 @@
---
title: Git Worktrees — Parallel Claude Sessions
tags:
- git
- claude-code
- workflow
- productivity
aliases:
- git worktrees
- parallel claude
---
# Git Worktrees — Параллельные сессии Claude
Git worktree позволяет иметь несколько рабочих директорий из одного репозитория одновременно, каждая на своей ветке. Это ключевой инструмент для параллельной работы нескольких сессий Claude Code без конфликтов.
## Зачем это нужно
Без worktrees две сессии Claude работают на одних файлах → конфликты, перезапись изменений, сломанный dev server.
С worktrees каждая сессия получает **изолированную копию файлов** + **общий `.git`**.
## Команды
```bash
# Создать worktree на новой ветке
git worktree add ../project-feature-x feature-x
# Создать worktree на существующей ветке
git worktree add ../project-hotfix hotfix/urgent-fix
# Список всех активных worktrees
git worktree list
# Удалить после завершения работы
git worktree remove ../project-feature-x
# Принудительно удалить (если есть uncommitted changes)
git worktree remove --force ../project-feature-x
```
## Типичный сценарий
```
~/project/ ← main, сессия 1: текущая фича
~/project-hotfix/ ← hotfix/v2.1, сессия 2: срочный баг
~/project-refactor/ ← refactor/auth, сессия 3: рефакторинг
```
Все три сессии Claude работают независимо, не мешая друг другу.
## Когда предлагать
- Репо имеет несколько веток и нужно работать над двумя задачами параллельно
- Нужен срочный hotfix, но основная ветка в середине незавершённой фичи
- Долгая задача идёт фоном, пока ты работаешь над другим
- Claude нужна свобода экспериментировать без риска сломать рабочее состояние
## Claude Code — встроенная поддержка
Claude Code имеет встроенный инструмент `EnterWorktree`. Агент с параметром `isolation: "worktree"` автоматически создаёт изолированный worktree, работает в нём, и либо возвращает путь к ветке (если были изменения), либо чистит за собой (если нет).
```
Agent({
isolation: "worktree", ← агент работает в изолированной копии
prompt: "..."
})
```
## Ограничения
- Одну ветку нельзя открыть в двух worktrees одновременно
- Нельзя `checkout` ветку, которая уже открыта в другом worktree
- `git stash` работает глобально — применяется к любому worktree
## Связанные заметки
- [[wiki/concepts/claude-code-agents|Claude Code Agents]]
- [[wiki/architecture/_index|Architecture Patterns]]

View file

@ -43,6 +43,7 @@ Self-hosted infra: Proxmox install, IOMMU/PCI passthrough, hypervisor setup, bud
| [[wiki/homelab/glance-dashboard\|Glance — Self-hosted Dashboard]] | Glance setup replacing Homarr: Docker config, 5-page layout, Prometheus RAPL metrics, key patterns ($include caveat, internal IPs only) | session 2026-04-29 | 2026-04-29 |
| [[wiki/homelab/homelab-media-stack\|Homelab Media Stack — Jellyfin + *arr + qBittorrent Setup]] | CT111 media LXC: unified /data mount pattern, Intel QuickSync GPU passthrough, step-by-step qBittorrent categories + Sonarr/Radarr/Prowlarr wiring | session 2026-04-26 | 2026-04-26 |
| [[wiki/homelab/hp-elitedesk-800g3-proxmox\|HP Elitedesk 800 G3 — Proxmox Setup Log]] | Real homelab server setup log: i5-7500, 24 GB RAM, 256 GB NVMe + 6 TB HDD, LXC containers, GPU passthrough (AMD/Intel) | session 2026-04-18 | 2026-04-21 |
| [[wiki/homelab/router-tplink-ax72-config\|Router — TP-Link AX72 + Mesh RE605X + RE705X]] | Complete router config: LAN/DHCP, DNS (split-DNS via AdGuard), DHCP reservations with MACs, NAT port forwarding, UPnP/DMZ security, Wi-Fi, OneMesh setup | session 2026-05-03 | 2026-05-03 |
| [[wiki/homelab/hp-elitedesk-800g3-teardown-upgrade\|HP EliteDesk 800 G3 SFF — Teardown, Upgrade & Benchmarks]] | Full disassembly/reassembly guide: proprietary connectors caveat, dual-channel RAM, CPU cooler swap, GTX 1050 Ti, thermal benchmarks (GTA V, Flight Sim) | raw/HP EliteDesk 800 G3 SFF - Teardown, re-assembly and upgrade.md | 2026-04-30 |
| [[wiki/homelab/hp-elitedesk-800g3-rtx3060-gaming-upgrade\|HP EliteDesk 800 G3 Tower — RTX 3060 Gaming Upgrade]] | Tower form factor gaming build: drop-in HP 500W PSU swap, Asus Dual mini RTX 3060, 16 GB DDR4, 1 TB NVMe; FurMark + gaming benchmarks | raw/HP EliteDesk 800 G3 RTX 3060, NVMe 1TB, HP 500W PSU, gaming upgrade.md | 2026-04-30 |
| [[wiki/homelab/hp-elitedesk-800g3-sff-gaming-upgrade\|HP EliteDesk 800 G3 SFF — RTX 3050 LP Gaming Upgrade]] | SFF gaming build: stock 180W PSU constraint, RTX 3050 6GB LP as optimal GPU, i7-7700 CPU ceiling, Doom: The Dark Ages benchmarks, £330 total | raw/I upgraded my HP Elitedesk 800 G3 Office PC..md | 2026-04-30 |

View file

@ -3,7 +3,7 @@ title: "Glance — Self-hosted Dashboard"
aliases: [glance, homelab-dashboard]
tags: [homelab, docker, dashboard, glance]
created: 2026-04-29
updated: 2026-04-29
updated: 2026-05-03
status: live
---
@ -44,15 +44,20 @@ services:
TZ: ${TZ:-Europe/London}
```
## Dashboard Decision (2026-05-03)
Dashy и Dashbrr были развёрнуты для сравнения A/B/C. После ревью оставили **только Glance** — Dashy и Dashbrr удалены полностью (контейнеры, директории `/opt/services/`, NPM proxy hosts).
## Pages / Tabs
| Вкладка | Виджеты |
|---------|---------|
| Home | clock (Henley/Kyiv/UTC), weather (Henley-on-Thames), core services monitor, server-stats CT102, split-column power+temp, bookmarks |
| Services | docker-containers, full monitor (28 сервисов), server-stats |
| Energy | iframe power.ai-impress.com, live power draw (RAPL), PSYS total, CPU temp |
| Media | *arr stack monitor, bookmarks |
| News | Hacker News, RSS (Verge/Phoronix/Ars Technica), Reddit (selfhosted/homelab), weather |
| Home | clock (Henley/Kyiv/UTC), weather, monitor (критические сервисы), alerts (Alertmanager), server-stats CT102, power (RAPL Вт), CPU temp, disk (root NVMe + data HDD), Jellyfin live sessions, Radarr/Sonarr history, qBit active downloads, quick bookmarks |
| Services | docker-containers (авто, все контейнеры), full monitor (28+ сервисов CT102 + CT111), server-stats |
| Reference | Все сервисы с IP/портами/публичными URL и иконками — одна страница вместо поиска |
| Energy | live power draw (RAPL), PSYS total, CPU temp, graph 24h, £/day forecast |
| Media | *arr stack monitor, Sonarr/Radarr queue, bookmarks |
| News | Hacker News, RSS Habr (ИИ/ML/Нейросети/LLM/DevOps/IoT/Умный дом), RSS EN (HuggingFace/Simon Willison/n8n), Reddit (selfhosted/MachineLearning/homelab), weather |
## Key Config Patterns
@ -93,6 +98,44 @@ ssh pve "pct exec 102 -- bash -lc 'cd /opt/services/glance && docker compose res
Минимальная длина пароля — 6 символов.
## Known Gotchas
### Jellyfin sessions — правильный способ
Токен передавать через `headers:`, не query param. Проверять наличие `NowPlayingItem` через `.Exists`, а не вложенный путь `.String "NowPlayingItem.Name"` (вложенный путь в range-блоке ненадёжен):
```yaml
- type: custom-api
url: http://192.168.1.230:8096/Sessions
headers:
X-MediaBrowser-Token: <api_key>
template: |
{{ $playing := false }}
{{ range .JSON.Array "" }}
{{ if .Exists "NowPlayingItem" }}
{{ $playing = true }}
...{{ .String "NowPlayingItem.Name" }}...
{{ end }}
{{ end }}
{{ if not $playing }}<div>Никто не смотрит</div>{{ end }}
```
### Data HDD — правильный mountpoint
CT102 монтирует data-hdd в `/mnt/data` (не `/mnt/media` — это CT111). В Prometheus-запросе:
```
node_filesystem_avail_bytes{mountpoint="/mnt/data",instance="docker-host"}
```
### RSS Habr — правильный URL-формат
Используй `hubs` (множественное число), не `hub`:
```
✅ https://habr.com/ru/rss/hubs/artificial_intelligence/articles/all/
❌ https://habr.com/ru/rss/hub/artificial_intelligence/articles/all/ ← 404
```
Рабочие хабы: `artificial_intelligence`, `machine_learning`, `neural_networks`, `llm_tools`, `devops`, `sysadm`, `iot`, `smart_home`.
## Related
- [[homelab-services-map]] — полная карта сервисов

View file

@ -3,14 +3,14 @@ title: "Homelab Media Stack — Jellyfin + *arr + qBittorrent Setup"
aliases: [media-stack, jellyfin-setup, arr-stack]
tags: [homelab, jellyfin, sonarr, radarr, prowlarr, qbittorrent, docker, gpu, quicksync]
created: 2026-04-26
updated: 2026-04-26
updated: 2026-05-03
status: live
---
## Container Info
- **CT111** — 192.168.1.230, 4 GB RAM, Debian 12, unprivileged
- **GPU:** Intel HD Graphics 630, QuickSync via `/dev/dri/renderD129`
- **GPU:** Intel HD Graphics 630, QuickSync via `/dev/dri/renderD128` (not renderD128 — не существует)
- **Media disk:** 500 GB LVM (`data-hdd:vm-111-media`) → `/mnt/media`
- **Docker data:** `/mnt/media/docker-data` (set via `data-root` in daemon.json)
@ -22,13 +22,14 @@ All containers mount `/mnt/media` as `/data`. This is critical — without a uni
```
/mnt/media/
├── movies/ # Radarr root folder: /data/movies
├── movies/
│ ├── films/ # Radarr root 1: /data/movies/films → Jellyfin "Фильмы"
│ └── kids/ # Radarr root 2: /data/movies/kids → Jellyfin "Мультики"
├── tv/ # Sonarr root folder: /data/tv
└── downloads/
├── complete/
│ ├── movies/ # qBittorrent category "movies"
│ └── tv/ # qBittorrent category "tv"
└── incomplete/ # active torrents
├── tv-sonarr/ # qBit category "tv-sonarr"
├── movies-radarr/ # qBit category "movies-radarr"
└── manual/ # qBit category "manual"
```
**Ownership:** all dirs owned by `1000:1000` (linuxserver `abc` user = PUID/PGID=1000).
@ -59,7 +60,7 @@ services:
- /opt/media/jellyfin/cache:/cache
- /mnt/media:/data
devices:
- /dev/dri/renderD129:/dev/dri/renderD129
- /dev/dri/renderD128:/dev/dri/renderD128
- /dev/dri/card1:/dev/dri/card1
group_add: ["44", "993"]
@ -96,7 +97,7 @@ services:
image: lscr.io/linuxserver/qbittorrent:latest
container_name: qbittorrent
restart: unless-stopped
ports: ["8080:8080", "6881:6881", "6881:6881/udp"]
ports: ["8080:8080", "50000:50000", "50000:50000/udp"]
environment: [PUID=1000, PGID=1000, TZ=Europe/London, WEBUI_PORT=8080]
volumes:
- /opt/media/qbittorrent:/config
@ -122,11 +123,18 @@ ssh pve "pct exec 111 -- docker logs qbittorrent 2>&1 | grep -i 'temporary passw
- Default save path: `/data/downloads/complete`
- Keep incomplete in: `/data/downloads/incomplete`
**Settings → Downloads → Default Save Path:** `/data/downloads/`
**Add categories** (right-click sidebar → Add Category):
| Category | Save Path |
|----------|-----------|
| `movies` | `/data/downloads/complete/movies` |
| `tv` | `/data/downloads/complete/tv` |
| `movies-radarr` | `/data/downloads/movies-radarr` |
| `tv-sonarr` | `/data/downloads/tv-sonarr` |
| `manual` | `/data/downloads/manual` |
**Connection:** Listening port `50000` (fixed). UPnP: OFF. Router Virtual Server: 50000 TCP+UDP → 192.168.1.230:50000 ✅ done.
**WebUI whitelist:** `192.168.1.0/24,172.16.0.0/12` (Docker bridge для Dashbrr и др.)
Change WebUI password immediately → save in Vaultwarden.
@ -178,21 +186,72 @@ After adding apps, Prowlarr syncs all indexers automatically.
Run first-time setup wizard. Create admin account.
**Add Libraries:**
| Library | Path |
|---------|------|
| Movies | `/data/movies` |
| TV Shows | `/data/tv` |
| Library | Path | Note |
|---------|------|------|
| Фильмы | `/data/movies/films` | Radarr root 1 |
| Мультики | `/data/movies/kids` | Radarr root 2 |
| TV Shows | `/data/tv` | Sonarr root |
**Enable QuickSync:**
Dashboard → Playback → Hardware acceleration:
- Acceleration type: **Intel QuickSync (VAAPI)**
- VA-API device: `/dev/dri/renderD129`
- VA-API device: `/dev/dri/renderD128`
- Enable: H.264, HEVC, MPEG2, VC1, VP8, VP9, AV1 (all available)
**Default language:**
- Dashboard → Playback → Default Audio Language: **Russian**
- Dashboard → Playback → Default Subtitle Language: **Russian**
- Subtitle mode: Smart (auto-load if audio not Russian)
**Webhooks (Sonarr + Radarr → Jellyfin):**
Settings → Connect → Add → Emby/Jellyfin:
- Host: `192.168.1.230`, Port: `8096`, API Key: `121facab6f7940c6a949501d144a6d3f`
- Events: On Import ✅, On Upgrade ✅, On Rename ✅, On Delete ✅
Verify transcoding works: play a file → force transcode → Admin → Dashboard → Active Streams.
---
### 6. Bazarr — https://bazarr.ai-impress.com
Location: `/opt/media/bazarr/` (CT111, port 6767). Added 2026-05-03.
```yaml
services:
bazarr:
image: lscr.io/linuxserver/bazarr:latest
environment: [PUID=1000, PGID=1000, TZ=Europe/London]
volumes:
- /opt/media/bazarr/config:/config
- /mnt/media/movies:/movies
- /mnt/media/tv:/tv
ports: ["6767:6767"]
```
Settings → Languages → Single language: `Russian`, Fallback: `English`.
Settings → Providers → OpenSubtitles.com (requires account).
Settings → Sonarr: `http://sonarr:8989`, API key from Sonarr.
Settings → Radarr: `http://radarr:7878`, API key from Radarr.
---
### 7. Recyclarr — TRaSH-guides sync
Location: `/opt/media/recyclarr/` (CT111). Added 2026-05-03.
```yaml
services:
recyclarr:
image: ghcr.io/recyclarr/recyclarr:latest
volumes:
- ./config:/config
environment: [TZ=Europe/London]
```
Config: `/opt/media/recyclarr/config/recyclarr.yml`. Run manually: `docker exec recyclarr recyclarr sync`.
---
## GPU Passthrough Details (unprivileged LXC)
The Intel HD 630 iGPU is on `/dev/dri/card1` (not card0 — AMD display card is card0).
@ -204,7 +263,7 @@ lxc.cgroup2.devices.allow: c 226:1 rwm
lxc.cgroup2.devices.allow: c 226:128 rwm
lxc.cgroup2.devices.allow: c 226:129 rwm
lxc.mount.entry: /dev/dri/card1 dev/dri/card1 none bind,optional,create=file
lxc.mount.entry: /dev/dri/renderD129 dev/dri/renderD129 none bind,optional,create=file
lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file
lxc.idmap: u 0 100000 65536
lxc.idmap: g 0 100000 44
lxc.idmap: g 44 44 1
@ -225,7 +284,7 @@ root:993:1
Inside CT111, verify device access:
```bash
ssh pve "pct exec 111 -- ls -la /dev/dri/"
# renderD129 should be group render (GID 993)
# renderD128 should be group render (GID 993)
# card1 should be group video (GID 44)
```
@ -233,7 +292,7 @@ ssh pve "pct exec 111 -- ls -la /dev/dri/"
## Troubleshooting
**"Permission denied" on /dev/dri/renderD129 inside Jellyfin:**
**"Permission denied" on /dev/dri/renderD128 inside Jellyfin:**
```bash
# Check groups inside container
ssh pve "pct exec 111 -- docker exec jellyfin id"

View file

@ -3,7 +3,8 @@ title: "Homelab — Full Services Map & Network Reference"
aliases: [homelab-map, services-map, homelab-reference]
tags: [homelab, proxmox, docker, dns, networking, reference]
created: 2026-04-26
updated: 2026-04-29
updated: 2026-05-03
last_verified: 2026-05-03 (live audit)
status: live
---
@ -11,130 +12,227 @@ status: live
| CT/VM | Name | IP | RAM | Cores | Status | Role |
|-------|------|----|-----|-------|--------|------|
| host | pve | 192.168.1.48 | 24 GB | 4 | running | Proxmox VE (`ssh pve`) |
| CT101 | adguard | 192.168.1.62 | 512 MB | 1 | running | AdGuard Home DNS (native, port 80 + 6060 admin) |
| host | pve | 192.168.1.48 | 24 GB | 4 | running | Proxmox VE 9.1.9 (`ssh pve`) |
| ~~CT101~~ | ~~adguard~~ | ~~192.168.1.62~~ | — | — | **destroyed** | Legacy AdGuard — destroyed 2026-05-03 |
| CT102 | docker | 192.168.1.225 | 9 GB | 4 | running | All Docker services (root 20GB + data-hdd 300GB) |
| CT105 | immich | 192.168.1.71 | 8 GB | 4 | running | Immich photos (native install, DHCP reservation!) |
| CT105 | immich | 192.168.1.71 | 8 GB | 4 | running | Immich photos (native install, GPU bug fixed 2026-05-03) |
| CT111 | media | 192.168.1.230 | 4 GB | 4 | running | Jellyfin + *arr stack + GPU passthrough |
| VM200 | kali-linux | DHCP | 8 GB | — | stopped | Pentest (start manually via `pct/qm start 200`) |
| CT112 | n8n | 192.168.1.232 | 2 GB | 2 | running | n8n workflow automation |
| VM200 | kali-linux | DHCP | 8 GB | — | stopped | Pentest (start manually: `qm start 200`) |
> **CT103/104/107/109/110 destroyed** — old beszel, vaultwarden, homarr, grafana, uptimekuma LXCs removed.
> **CT103/104/107/109/110 already destroyed** — old beszel, vaultwarden, homarr, grafana, uptime-kuma LXCs removed. All services migrated to CT102 Docker.
---
## CT101 — AdGuard Home (192.168.1.62)
| Service | URL | Port | Auth |
|---------|-----|------|------|
| AdGuard Home (web admin) | http://192.168.1.62:6060 | :6060 | credentials in ~/.secrets/ |
| DNS | — | :53 | — |
- Native install at `/opt/AdGuardHome/`
- DNS-over-HTTPS: :443, DNS-over-TLS: :853
---
## CT102 — Docker Services (192.168.1.225)
| Service | External URL | Internal Port | Config Path | Status |
|---------|-------------|---------------|-------------|--------|
| Nginx Proxy Manager | http://192.168.1.225:81 | :81 / :80 / :443 | /opt/npm/ | ✅ running |
| Portainer | https://192.168.1.225:9443 | :9443 (HTTPS) | Docker volume | ✅ running |
| **Glance** | https://home.ai-impress.com | :8085 | /opt/services/glance/ | ✅ running |
| Nextcloud | https://nextcloud.ai-impress.com | :8080 | /opt/nextcloud/ | ✅ running |
| Vaultwarden | https://passwords.ai-impress.com | :8082 | /opt/services/vaultwarden/ | ✅ running |
| Karakeep | http://192.168.1.225:3000 | :3000 | Docker volume | ✅ running |
| Uptime Kuma | http://192.168.1.225:3001 | :3001 | /opt/services/uptime-kuma/ | ✅ running |
| Beszel Hub | http://192.168.1.225:8090 | :8090 | /opt/services/beszel/ | ✅ running |
### Edge / Reverse Proxy
| Service | URL | Internal Port | Config | Status |
|---------|-----|---------------|--------|--------|
| Nginx Proxy Manager | http://192.168.1.225:81 (admin) | :80/:443/:81 | /opt/npm/ | ✅ running |
| CrowdSec | — | — | /opt/services/crowdsec/ | ✅ running (IPS only — no bouncer yet) |
### Dashboard / Management
| Service | URL | Internal Port | Config | Status |
|---------|-----|---------------|--------|--------|
| Glance | https://home.ai-impress.com 🌐 | :8085 | /opt/services/glance/ | ✅ running |
| Portainer | https://192.168.1.225:9443 | :9000/:9443 | `portainer_data` volume | ✅ running |
| Dozzle | http://192.168.1.225:9999 | :9999 | /opt/services/dozzle/ | ✅ running |
| Ntfy | http://192.168.1.225:2586 | :2586 | /opt/services/ntfy/ | ✅ running |
| Backrest | http://192.168.1.225:9898 | :9898 | /opt/services/backrest/ | ✅ running |
| Paperless-ngx | http://192.168.1.225:8010 | :8010 | /opt/services/paperless/ | ✅ running |
| IT Tools | http://192.168.1.225:8880 | :8880 | /opt/services/it-tools/ | ✅ running |
| Actual Budget | http://192.168.1.225:5006 | :5006 | /opt/services/actual/ | ✅ running |
| Uptime Kuma | http://192.168.1.225:3001 | :3001 | /opt/services/uptime-kuma/ | ✅ running |
| Beszel Hub | https://beszel.ai-impress.com 🏠 | :8090 | /opt/services/beszel/ | ✅ running |
### Apps
| Service | URL | Internal Port | Config | Status |
|---------|-----|---------------|--------|--------|
| Nextcloud | https://nextcloud.ai-impress.com 🌐 | :8080 | /opt/nextcloud/ | ✅ running |
| Collabora (CODE) | — (internal to Nextcloud) | :9980 | docker compose w/ nextcloud | ✅ running |
| Vaultwarden | https://passwords.ai-impress.com 🌐 | :8082 | /opt/services/vaultwarden/ | ✅ running |
| Paperless-ngx | https://docs.ai-impress.com 🏠 | :8010 | /opt/services/paperless/ | ✅ running |
| Forgejo | https://git.ai-impress.com 🏠 | :3002 / :222 (ssh) | /opt/services/forgejo/ | ✅ running |
| Karakeep | https://links.ai-impress.com 🏠 | :3000 | /opt/karakeep/ | ✅ running |
| Stirling PDF | https://pdf.ai-impress.com 🏠 | :8088 | /opt/services/stirling-pdf/ | ⚠️ BROKEN |
| IT Tools | https://tools.ai-impress.com 🏠 | :8880 | /opt/services/it-tools/ | ✅ running |
| Documenso | https://edoc.ai-impress.com 🌐 | :3004 | /opt/services/documenso/ | ✅ running |
| Cheatsheet | http://192.168.1.225:8999 | :8999 | /opt/services/cheatsheet/ | ✅ running |
### Finance / Planning
| Service | URL | Internal Port | Config | Status |
|---------|-----|---------------|--------|--------|
| Actual Budget | https://budget.ai-impress.com 🏠 | :5006 | /opt/services/actual/ | ✅ running |
| Maybe Finance | https://finance.ai-impress.com 🏠 | :3003 | /opt/services/maybe/ | ✅ running |
| Plane | https://plan.ai-impress.com 🏠 | :8181 | /opt/services/plane/ | ✅ running |
### Media Requests
| Service | URL | Internal Port | Config | Status |
|---------|-----|---------------|--------|--------|
| Jellyseerr | https://media.ai-impress.com 🌐 | :5055 | /opt/services/jellyseerr/ | ✅ running |
### DNS (CT102)
| Service | URL | Internal Port | Config | Status |
|---------|-----|---------------|--------|--------|
| AdGuard Home (Docker) | https://dns.ai-impress.com 🏠 | :53 / :8053 (admin UI) | /opt/services/adguard/ | ✅ running |
### Monitoring & Alerting
| Service | URL | Internal Port | Config | Status |
|---------|-----|---------------|--------|--------|
| Prometheus | http://192.168.1.225:9090 | :9090 | /opt/monitoring/ | ✅ running |
| Alertmanager | http://192.168.1.225:9093 | :9093 | /opt/monitoring/ | ✅ running |
| Loki | — | :3100 | /opt/monitoring/ | ✅ running |
| Power Cost | https://power.ai-impress.com | :8091 | /opt/services/power-cost/ | ✅ running |
| Cheatsheet | http://192.168.1.225:8999 | :8999 | /opt/services/cheatsheet/ | ✅ running |
| CrowdSec | — | — | /opt/services/crowdsec/ | ✅ running |
| Diun | — | — | /opt/services/diun/ | ✅ running |
| Watchtower | — | — | /opt/services/watchtower/ | ✅ running |
| Docker Socket Proxy | — | :2376 | — | ✅ running |
| Promtail | — | :9080 | /opt/monitoring/ | ✅ running (Docker + syslog targets) |
| Node Exporter | — | :9100 | — | ✅ running |
| **Stirling PDF** | http://192.168.1.225:8088 | :8088 | /opt/services/stirling-pdf/ | ⚠️ BROKEN |
| ~~Homarr~~ | ~~https://home.ai-impress.com~~ | :7575 | /opt/services/homarr/ | 🛑 stopped (replaced by Glance) |
| ~~Authentik~~ | ~~https://auth.ai-impress.com~~ | — | /opt/services/authentik/ | 🗑️ deleted |
| Beszel Agent | — | (internal) | — | ✅ running |
| Ntfy | https://ntfy.ai-impress.com 🌐 | :2586 | /opt/services/ntfy/ | ✅ running |
| Power Cost | https://power.ai-impress.com 🌐 | :8091 | /opt/services/power-cost/ | ✅ running |
### Stirling PDF — Known Issue
Crashes on startup with `Unable to resolve Configuration with Issuer https://auth.ai-impress.com/application/o/stirling-pdf/`.
**Root cause:** OIDC config points to Authentik which no longer exists.
**Fix:** Edit `/opt/services/stirling-pdf/docker-compose.yml` — set `SECURITY_OAUTH2_ENABLED=false` and `SECURITY_ENABLELOGIN=false`, then `docker compose up -d --force-recreate`.
### Backup & Infra
### NPM Proxy Hosts (id reference)
| Domain | Backend | cert_id |
|--------|---------|---------|
| home.ai-impress.com | 192.168.1.225:8085 | 2 |
| nextcloud.ai-impress.com | 192.168.1.225:8080 | 2 |
| passwords.ai-impress.com | 192.168.1.225:8082 | 2 |
| power.ai-impress.com | 192.168.1.225:8091 | 2 (id=27) |
| jellyfin.ai-impress.com | 192.168.1.230:8096 | 2 |
| qbit.ai-impress.com | 192.168.1.230:8080 | 2 |
| sonarr.ai-impress.com | 192.168.1.230:8989 | 2 |
| radarr.ai-impress.com | 192.168.1.230:7878 | 2 |
| prowlarr.ai-impress.com | 192.168.1.230:9696 | 2 |
| auth.ai-impress.com | (502 — Authentik deleted) | — |
---
## CT105 — Immich (192.168.1.71)
| Service | URL | Port |
|---------|-----|------|
| Immich | https://photo.ai-impress.com | :2283 |
- **Native install** (not Docker): `/opt/immich/`
- DHCP reservation required: MAC `BC:24:11:EA:8F:FD → 192.168.1.71`
- GPU: Intel HD Graphics 630 passthrough for ML
| Service | URL | Internal Port | Config | Status |
|---------|-----|---------------|--------|--------|
| Backrest (restic) | https://backup.ai-impress.com 🏠 | :9898 | /opt/services/backrest/ | ✅ running |
| Watchtower | — | — | /opt/services/watchtower/ | ✅ running |
| Diun | — | — | /opt/services/diun/ | ✅ running |
| Docker Socket Proxy | — | **127.0.0.1:2376** | — | ✅ running ✅ fixed |
---
## CT111 — Media Stack (192.168.1.230)
| Service | External URL | Port | Config |
|---------|-------------|------|--------|
| Jellyfin | https://jellyfin.ai-impress.com | :8096 | /opt/media/jellyfin/ |
| Sonarr | https://sonarr.ai-impress.com | :8989 | /opt/media/sonarr/ |
| Radarr | https://radarr.ai-impress.com | :7878 | /opt/media/radarr/ |
| Prowlarr | https://prowlarr.ai-impress.com | :9696 | /opt/media/prowlarr/ |
| qBittorrent | https://qbit.ai-impress.com | :8080 | /opt/media/qbittorrent/ |
| FlareSolverr | — | :8191 | — |
| Service | URL | Port | Config | Status |
|---------|-----|------|--------|--------|
| Jellyfin | https://jellyfin.ai-impress.com 🌐 | :8096 | /opt/media/jellyfin/ | ✅ running |
| Sonarr | https://sonarr.ai-impress.com 🏠 | :8989 | /opt/media/sonarr/ | ✅ running |
| Radarr | https://radarr.ai-impress.com 🏠 | :7878 | /opt/media/radarr/ | ✅ running |
| Prowlarr | https://prowlarr.ai-impress.com 🏠 | :9696 | /opt/media/prowlarr/ | ✅ running |
| qBittorrent | https://qbit.ai-impress.com 🏠 | :8080 (WebUI) / :50000 (P2P) | /opt/media/qbittorrent/ | ✅ running |
| Bazarr | https://bazarr.ai-impress.com 🏠 | :6767 | /opt/media/bazarr/ | ✅ running (added 2026-05-03) |
| Recyclarr | — (cron only) | — | /opt/media/recyclarr/ | ✅ running (added 2026-05-03) |
| FlareSolverr | — | :8191 | — | ✅ running |
- GPU: Intel HD Graphics 630, QuickSync via `/dev/dri/renderD129` (GID 993)
- Media mount: `data-hdd:vm-111-media → /mnt/media`
- GPU: Intel HD Graphics 630 → `/dev/dri/card1` + `/dev/dri/renderD128` (NOT renderD129 — that doesn't exist)
- Media mount: `data-hdd:vm-111-media` (500 GB LV) → `/mnt/media`
- qBit port: changed 6881 → 50000 (compose + config). **Pending**: router Virtual Server 50000 TCP+UDP → 192.168.1.230:50000
- Russian 1080p quality profile: minFormatScore=100 (requires Russian audio). Custom formats: Russian Audio +500, English Audio +50
- Prowlarr indexers: RuTracker, RuTor, NNM-Club, 1337x, Nyaa, Anidub, LimeTorrents
- Bazarr: connected to Sonarr+Radarr, OpenSubtitles.com provider enabled
- Recyclarr: config at /opt/media/recyclarr/recyclarr.yml (Sonarr+Radarr API keys set)
---
## CT105 — Immich (192.168.1.71) — STOPPED
| Service | URL | Port |
|---------|-----|------|
| Immich | https://photo.ai-impress.com 🌐 | :2283 (native install, not Docker) |
- Native install: `/opt/immich/`
- DHCP reservation: MAC `BC:24:11:EA:8F:FD → 192.168.1.71`
- Fix: `pct set 105 --delete dev1 && pct set 105 --delete dev2 && pct start 105`
---
## CT112 — n8n (192.168.1.232)
| Service | URL | Port |
|---------|-----|------|
| n8n | https://auto.ai-impress.com 🌐 | :5678 |
- NPM proxy id=32
- Compose: CT112 root `/` (Docker process, not compose file)
---
## NPM Proxy Hosts — Full List
| id | Domain | Backend | Enabled | Notes |
|----|--------|---------|---------|-------|
| 1 | nextcloud.ai-impress.com | 192.168.1.225:8080 | ✅ | 🌐 |
| 2 | links.ai-impress.com | 192.168.1.225:3000 | ✅ | 🏠 Karakeep |
| 3 | home.ai-impress.com | 192.168.1.225:8085 | ✅ | 🌐 Glance |
| 4 | passwords.ai-impress.com | 192.168.1.225:8082 | ✅ | 🌐 Vaultwarden |
| 5 | flow.ai-impress.com | 192.168.1.105:80 | ✅ | ❌ DEAD — 192.168.1.105 doesn't exist |
| 6 | ssh.ai-impress.com | 192.168.1.142:80 | ✅ | ❌ DEAD — 192.168.1.142 doesn't exist |
| 7 | uptime.ai-impress.com | 192.168.1.225:3001 | ✅ | 🏠 Uptime Kuma |
| 8 | grafana.ai-impress.com | 192.168.1.88:3000 | ✅ | ❌ DEAD — Grafana deleted |
| 9 | photo.ai-impress.com | 192.168.1.71:2283 | ✅ | 🌐 Immich (502 — CT stopped) |
| 10 | dns.ai-impress.com | 192.168.1.62:80 | ✅ | ⚠️ Points to CT101 — should be 192.168.1.225:8053 |
| 11 | beszel.ai-impress.com | 192.168.1.225:8090 | ✅ | 🏠 |
| 12 | auth.ai-impress.com | 192.168.1.225:9001 | ✅ | ❌ DEAD — Authentik deleted |
| 13 | logs.ai-impress.com | 192.168.1.225:9999 | ✅ | 🏠 Dozzle |
| 14 | ntfy.ai-impress.com | 192.168.1.225:2586 | ✅ | 🌐 |
| 15 | backup.ai-impress.com | 192.168.1.225:9898 | ✅ | 🏠 Backrest |
| 16 | docs.ai-impress.com | 192.168.1.225:8010 | ✅ | 🏠 Paperless |
| 17 | tools.ai-impress.com | 192.168.1.225:8880 | ✅ | 🏠 IT Tools |
| 18 | pdf.ai-impress.com | 192.168.1.225:8088 | ✅ | 🏠 Stirling-PDF (broken) |
| 19 | budget.ai-impress.com | 192.168.1.225:5006 | ✅ | 🏠 Actual |
| 20 | uptime.ai-impress.com | 192.168.1.225:3001 | ❌ disabled | duplicate of id=7 |
| 21 | jellyfin.ai-impress.com | 192.168.1.230:8096 | ✅ | 🌐 |
| 22 | sonarr.ai-impress.com | 192.168.1.230:8989 | ✅ | 🏠 |
| 23 | radarr.ai-impress.com | 192.168.1.230:7878 | ✅ | 🏠 |
| 24 | prowlarr.ai-impress.com | 192.168.1.230:9696 | ✅ | 🏠 |
| 25 | qbit.ai-impress.com | 192.168.1.230:8080 | ✅ | 🏠 |
| 26 | mail.ai-impress.com | 57.128.160.249:443 | ✅ | 🌐 → aimpress VPS (Mailcow) |
| 27 | power.ai-impress.com | 192.168.1.225:8091 | ✅ | 🌐 |
| 28 | git.ai-impress.com | 192.168.1.225:3002 | ✅ | 🏠 Forgejo |
| 29 | plan.ai-impress.com | 192.168.1.225:8181 | ✅ | 🏠 Plane |
| 30 | finance.ai-impress.com | 192.168.1.225:3003 | ✅ | 🏠 Maybe |
| 31 | media.ai-impress.com | 192.168.1.225:5055 | ✅ | 🌐 Jellyseerr |
| 32 | auto.ai-impress.com | 192.168.1.232:5678 | ✅ | 🌐 n8n (CT112) |
| 33 | edoc.ai-impress.com | 192.168.1.225:3004 | ✅ | 🌐 Documenso |
**Dead proxies to clean up:** id=5, 6, 8, 12 (delete or disable)
**Wrong target:** id=10 — change to `192.168.1.225:8053` (after CT101 migration complete)
---
## DNS Architecture
### Internal (AdGuard Home — CT101: 192.168.1.62)
### Current State (2026-05-03)
```
All *.ai-impress.com → NPM (192.168.1.225) → backend containers
AdGuard listens on CT101:53
CT102 resolv.conf: 192.168.1.62 + 8.8.8.8
CT105 resolv.conf: 192.168.1.62 + 8.8.8.8
pve resolv.conf: 192.168.1.62 + 8.8.8.8
LAN devices → DNS: 192.168.1.62 (CT101, native AdGuard)
*.ai-impress.com → 192.168.1.225 (NPM)
mail.ai-impress.com → 57.128.160.249 (VPS)
upstreams: quad9 + cloudflare + google
```
### External (Cloudflare — public IP 83.151.203.105)
### Target State (after router DNS update)
Active A records pointing to homelab:
- nextcloud.ai-impress.com, photo.ai-impress.com, passwords.ai-impress.com
- home.ai-impress.com, jellyfin.ai-impress.com, power.ai-impress.com
```
LAN devices → DNS: 192.168.1.225 (CT102 Docker AdGuard :53)
*.ai-impress.com → 192.168.1.225 (NPM, split-DNS)
mail.ai-impress.com → 57.128.160.249 (VPS override)
```
Keep internal only (LAN only, no Cloudflare):
- dns / beszel / logs / tools / pdf / sonarr / radarr / prowlarr / qbit
**Pending**: Update router DHCP Primary DNS: 192.168.1.62 → **192.168.1.225**
### External DNS (Cloudflare)
Public A records → `83.151.203.105` (home public IP):
- `nextcloud`, `photo`, `passwords`, `home`, `jellyfin`, `power`, `media`, `auto`, `edoc`, `ntfy`
LAN-only (no Cloudflare A record):
- `dns`, `beszel`, `logs`, `tools`, `pdf`, `sonarr`, `radarr`, `prowlarr`, `qbit`, `backup`, `docs`, `links`, `git`, `budget`, `finance`, `plan`
---
## Storage Layout
| Pool | Device | Size | Used by |
|------|--------|------|---------|
| local-lvm | NVMe SSD | 141 GB | All CT root disks (CT101:4G, CT102:20G, CT105:20G, CT111:16G, CT112:8G, VM200:60G) |
| data-hdd | HDD | 5.6 TB | CT102 data mount (300G), CT105 upload (200G) + data (50G), CT111 media (500G LV) |
| usb-backup | USB Toshiba 1TB | 916 GB | vzdump backups (daily 12:20) |
---
@ -147,27 +245,28 @@ ssh pve
# Run command in CT102 (docker host)
ssh pve "pct exec 102 -- bash -lc '<cmd>'"
# Full docker list
ssh pve "pct exec 102 -- docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'"
# Restart a service in CT102
ssh pve "pct exec 102 -- bash -lc 'cd /opt/services/<name> && docker compose restart'"
# Check all running containers
ssh pve "pct exec 102 -- docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'"
# Check NPM proxy hosts
ssh pve "pct exec 102 -- sqlite3 /opt/npm/data/database.sqlite 'SELECT id, domain_names, forward_host, forward_port, enabled FROM proxy_host;'"
# View logs
ssh pve "pct exec 102 -- docker logs --tail=50 <container>"
# Check AdGuard rewrites
ssh pve "pct exec 102 -- docker exec adguard cat /opt/adguardhome/conf/AdGuardHome.yaml | grep -A3 rewrites"
# Push file to CT102
scp /local/file pve:/tmp/file && ssh pve "pct push 102 /tmp/file /dest/path"
# All LXC containers
ssh pve "pvesh get /nodes/pve/lxc --output-format json"
# Free thin-pool (run after bulk deletes)
ssh pve "pct exec 102 -- fstrim -av"
```
---
## Storage Layout
## Related
| Pool | Device | Size | Used by |
|------|--------|------|---------|
| local-lvm | SSD | 256 GB | VM/CT root disks |
| data-hdd | HDD | 6 TB | CT102 data (300GB), CT105 upload (200GB) + data (50GB), CT111 media (large) |
- [[wiki/infrastructure/server-pve|server-pve]] — host hardware + storage details
- [[wiki/infrastructure/network-topology|network-topology]] — traffic flow diagram
- [[wiki/homelab/router-tplink-ax72-config|router-tplink-ax72-config]] — AX72 DHCP/DNS/ports
- [[wiki/homelab/homelab-media-stack|homelab-media-stack]] — CT111 GPU setup details
- [[wiki/homelab/glance-dashboard|glance-dashboard]] — CT102 Glance config

View file

@ -0,0 +1,190 @@
---
title: "Router — TP-Link AX72 + Mesh RE605X + RE705X"
tags: [homelab, network, router, mesh, dhcp, dns]
created: 2026-05-03
updated: 2026-05-03
status: reference
---
# TP-Link AX72 + OneMesh (RE605X + RE705X)
> Web UI: `http://192.168.1.1` (after initial setup)
> Default factory: `http://tplinkwifi.net` or `http://192.168.0.1`
> App: TP-Link Tether
**Hardware:**
- AX72 — AX5400 dual-band Wi-Fi 6 (main router)
- RE605X — AX1800 mesh extender (mid range)
- RE705X — AX3000 mesh extender (main extension, has Ethernet backhaul port)
---
## LAN / DHCP Server
**Network → LAN:**
- Router IP: `192.168.1.1`
- Subnet mask: `255.255.255.0`
**Network → DHCP Server:**
- Status: Enabled
- Pool: `192.168.1.100` `192.168.1.199`
- Lease time: `1440` min (24h)
- Gateway: `192.168.1.1`
> IP range design: `.1.99` = static/reserved (servers), `.100.199` = DHCP pool, `.200.254` = IoT/guest reserve
---
## DNS — Critical
**Network → DHCP Server → DNS settings:**
- **Primary DNS: `192.168.1.225`** ← CT102 Docker AdGuard (split-DNS for `*.ai-impress.com`)
- **Secondary DNS: `1.1.1.1`** ← fallback if CT102 is down
> ⚠️ Do NOT use `192.168.1.62` (CT101 legacy AdGuard — pending destruction)
> After changing: flush DNS on clients (`ipconfig /flushdns` Win, `sudo killall -HUP mDNSResponder` Mac)
---
## DHCP Address Reservations
**Network → DHCP Server → Address Reservation:**
| Device | MAC | Reserved IP | Notes |
|--------|-----|-------------|-------|
| pve (host) | (run `ssh pve "ip link show eno1"`) | `192.168.1.48` | Proxmox host |
| CT101 adguard (legacy) | `BC:24:11:56:36:05` | `192.168.1.62` | until destroyed |
| CT102 docker | `BC:24:11:52:32:9F` | `192.168.1.225` | **DNS server — critical** |
| CT105 immich | `BC:24:11:EA:8F:FD` | `192.168.1.71` | |
| CT111 media | `BC:24:11:7A:1B:8A` | `192.168.1.230` | |
| CT112 n8n | `BC:24:11:A2:32:01` | `192.168.1.232` | |
| RE605X extender | (see sticker) | `192.168.1.2` | mesh node 1 |
| RE705X extender | (see sticker) | `192.168.1.3` | mesh node 2 |
> MACs verified on 2026-05-03 from `pct config <ID> | grep hwaddr`
---
## NAT / Port Forwarding
**NAT Forwarding → Virtual Servers:**
| External Port | Internal IP | Internal Port | Protocol | Purpose |
|---------------|-------------|---------------|----------|---------|
| 80 | 192.168.1.225 | 80 | TCP | NPM HTTP (Let's Encrypt ACME + HTTP→HTTPS redirect) |
| 443 | 192.168.1.225 | 443 | TCP | NPM HTTPS — all public services |
> **If Cloudflare Tunnel is implemented (P1 task):** delete both rules. Cloudflared uses outbound connection only — no NAT holes needed.
**Ports NOT to forward (access via Tailscale instead):**
| Port | Service |
|------|---------|
| 22 | SSH to pve |
| 8006 | Proxmox Web UI |
| 81 | NPM admin |
| 53 | DNS |
| 8090 | Beszel |
| 9090/9093/3100 | Prometheus/AM/Loki |
| 9999 | Dozzle |
| 9898 | Backrest |
---
## DMZ
**NAT Forwarding → DMZ:** **Disabled** (never use — use explicit Virtual Servers only)
---
## UPnP
**NAT Forwarding → UPnP:** **Disabled**
> UPnP allows any LAN device to silently open ports — security risk. qBittorrent works fine without it. If qBit needs incoming connections: add explicit Virtual Server `50000 TCP+UDP → 192.168.1.230:50000`.
---
## Firewall / Security
**Security → Settings:**
- SPI Firewall: Enabled
- DoS Protection: Enabled (Medium)
- ICMP-Flood protection: Enabled
- TCP-SYN-Flood protection: Enabled
- UDP-Flood protection: Enabled
- **Ignore Ping From WAN: Enabled** (hide router from ICMP scans)
- Ignore Ping From LAN: Disabled
---
## IPv6
**Advanced → IPv6:**
If ISP provides IPv6 — enable **but** block all inbound IPv6 in firewall (established/related only).
If unsure — **disable IPv6 on WAN** to avoid bypass of NAT port rules.
---
## Wi-Fi (AX72 Main)
**Wireless → Wireless Settings:**
- 2.4 GHz SSID: same as 5 GHz (e.g. `home-network`)
- 5 GHz SSID: **same SSID** — enables band steering + seamless mesh handover
- Security: WPA2/WPA3 mixed
- Smart Connect: **Enabled** (merges 2.4 + 5 GHz under single SSID)
- WPS: **Disabled** (security)
- Transmit Power: High
**Guest Network (Wireless → Guest Network):**
- SSID: `home-network-guest`
- WPA2
- **Allow guests to access my local network: Disabled** — isolation from 192.168.1.0/24
---
## OneMesh — RE605X + RE705X Setup
**Advanced → OneMesh → Add Device:**
1. Power on extender near the router during pairing
2. Press WPS on extender, or use Tether app → Add Device
3. Both appear in `OneMesh → Network` topology
**Recommended placement:**
- RE705X (AX3000, stronger) — far room / different floor. **Use Ethernet backhaul if possible**: plug LAN cable from switch → RE705X LAN port → zero Wi-Fi bandwidth wasted on backhaul
- RE605X (AX1800, lighter) — mid-distance corridor or entrance area
**What mesh nodes provide:**
- Same SSID + password (clients don't notice the handover)
- DHCP served by AX72 only (nodes are bridge/AP mode)
- DNS setting comes from AX72 DHCP options
**Verify topology:**
- `OneMesh → Network` shows: root=AX72, leaves=RE605X/RE705X, backhaul type (Wi-Fi 5GHz or Ethernet)
---
## Firmware Updates
**Advanced → System → Firmware Upgrade → Check for Updates**
- AX72: update if available
- RE605X / RE705X: update via their web UI (192.168.1.2 / .3) or via AX72 OneMesh management
- Enable Auto-Update if available in Tether app
---
## Config Backup
**Advanced → System → Backup & Restore → Backup**
Save `.bin` file after any settings change.
Store at: `03 Resources/Infrastructure/router-tplink-ax72-backup-YYYY-MM-DD.bin`
---
## Related
- [[wiki/infrastructure/server-pve|server-pve]] — Proxmox host details
- [[wiki/homelab/homelab-services-map|homelab-services-map]] — full services, ports, DNS
- [[wiki/infrastructure/network-topology|network-topology]] — traffic flow (Internet → router → NPM → services)

View file

@ -31,6 +31,7 @@ Server inventory for all SSH-accessible machines. Last audited: 2026-04-24. Upda
| Article | Purpose |
|---------|---------|
| [[wiki/infrastructure/ssh-aliases\|ssh-aliases]] | All aliases, IPs, keys, health-check one-liner |
| [[wiki/infrastructure/network-topology\|network-topology]] | Internet→router→NPM→services flow, LAN subnet map, DNS paths, Tailscale overlay |
## ⚠ Known Issues
@ -50,16 +51,34 @@ Server inventory for all SSH-accessible machines. Last audited: 2026-04-24. Upda
### 🟡 Capacity
- `librechat-prod` `2026-04-24` — data directory **197 GB** (484 GB total, 65%) — monitor growth
- `pve` local-lvm `2026-04-24`**71%** full (100/141 GB) — monitor
- `pve` usb-backup `2026-05-03`**37.58%** (345GB/916GB) — was 12% — growing fast, check vzdump retention
- `pve` vm-102-disk-0 `2026-05-03` — thin-pool 99.39% allocated — run `fstrim` in CT102 (df shows 36% — not urgent but should be cleaned)
- `aimpress` `2026-04-24` — 26.58 GB reclaimable Docker images (`docker image prune -a`)
- `baic` `2026-04-24` — large vhosts: ustudio.global 22 GB, ustudiostaging2 19 GB, ie.oliver.agency 13 GB
### 🟠 Security
- `optical` `2026-04-24` — All databases bound to `0.0.0.0`: Redis ×3 (:6379/:6380/:6399), PostgreSQL ×3 (:5432/:5433/:5437), MongoDB ×3 (:27017/:27019/:27021), Neo4j (:7474/:7475/:7687/:7688)
- `librechat-prod` `2026-04-24` — MongoDB :27017 on `0.0.0.0` — publicly exposed, no auth config found
- `baic` `2026-04-24` — PostgreSQL :5432 + rpcbind :111 on `0.0.0.0`
- `optical-dev` `2026-04-24` — PostgreSQL :5436/:5491/:5493 + olivas :8000 + cc-dashboard :8800 on `0.0.0.0`
- `baic` `2026-04-21` — Grafana default `admin:admin` password unchanged
- `pve` CT102 `2026-05-03`**docker-socket-proxy on 0.0.0.0:2376** — Docker API accessible on LAN (should be 127.0.0.1)
### 🔵 Maintenance
- `optical-dev` `2026-04-24` — hp-prod-tracker + dow-prod-tracker containers unhealthy (healthcheck misconfigured, apps running fine)
- `box-cli` `2026-04-24` — CentOS 7 EOL since Jun 2024 — needs OS migration
- `pve` `2026-04-21` — Uptime Kuma webhook to monitoring-agent not yet configured
- `pve` CT105 `2026-05-03`**Immich STOPPED** — fix: `pct set 105 --delete dev1 && pct set 105 --delete dev2 && pct start 105`
- `pve` CT101 `2026-05-03`**Legacy AdGuard still running** — router DHCP DNS still points to 192.168.1.62, needs update to 192.168.1.225
- `pve` CT102 `2026-05-03`**Stirling-PDF broken** — OIDC points to deleted Authentik — fix: set SECURITY_OAUTH2_ENABLED=false
- `pve` CT102 `2026-05-03`**Loki without Promtail** — logs not flowing
- `pve` CT102 `2026-05-03`**CrowdSec without bouncer** — IPS observing but not blocking
- `pve` CT102 `2026-05-03`**5 dead NPM proxy hosts** — id=5,6,8,12 (delete), id=10 (change to CT102 AdGuard :8053)
- `pve` host `2026-05-03` — rpcbind :111 open on 0.0.0.0 — disable if no NFS: `systemctl disable --now rpcbind rpcbind.socket`
- `pve` `2026-05-03` — Tailscale no subnet-router — LAN not accessible remotely without port forwarding
### ✅ Resolved
- `pve` local-lvm `2026-05-03` — improved to 58.85% (was 71%) — old stale LXCs (CT103/104/107/109/110) destroyed
- `pve` CT 102 (docker) — resolved 2026-04-24 — Docker data-root moved to `/mnt/data/docker`, now 51%
- `pve` CT 105 (immich) — resolved 2026-04-24 — PostgreSQL + cache moved to data-hdd, now 62%
- `pve` — resolved 2026-04-24 — Proxmox security updates applied (libngtcp2, cluster libs)
- `optical` `2026-04-24` — SSL cert ai-sandbox.oliver.solutions — track separately (check if renewed)

View file

@ -0,0 +1,157 @@
---
title: "Homelab — Network Topology"
tags: [homelab, network, dns, infrastructure, reference]
created: 2026-05-03
updated: 2026-05-03
last_verified: 2026-05-03 (live audit)
---
# Homelab Network Topology
## Public Internet → Services
```
Internet
Cloudflare DNS (ai-impress.com zone)
├── *.ai-impress.com → A record → 83.151.203.105 (home public IP)
└── mail.ai-impress.com → A record → 57.128.160.249 (aimpress VPS)
Home Router TP-Link AX72 (83.151.203.105 WAN)
Port Forward: 80/TCP → 192.168.1.225:80
Port Forward: 443/TCP → 192.168.1.225:443
Nginx Proxy Manager — CT102 Docker (192.168.1.225:80/443)
├── nextcloud.ai-impress.com → :8080 (Nextcloud)
├── passwords.ai-impress.com → :8082 (Vaultwarden)
├── photo.ai-impress.com → CT105:2283 (Immich — STOPPED)
├── home.ai-impress.com → :8085 (Glance)
├── jellyfin.ai-impress.com → CT111:8096 (Jellyfin)
├── media.ai-impress.com → :5055 (Jellyseerr)
├── auto.ai-impress.com → CT112:5678 (n8n)
├── edoc.ai-impress.com → :3004 (Documenso)
├── ntfy.ai-impress.com → :2586 (ntfy)
├── power.ai-impress.com → :8091 (Power Cost)
└── mail.ai-impress.com → 57.128.160.249:443 (passthrough to VPS)
```
## LAN-Only Services (no external A record)
```
LAN client → AdGuard DNS → *.ai-impress.com → 192.168.1.225 (split-DNS)
→ NPM → internal services:
dns.ai-impress.com → :8053 (AdGuard admin) 🏠
beszel.ai-impress.com → :8090 (Beszel) 🏠
logs.ai-impress.com → :9999 (Dozzle) 🏠
tools.ai-impress.com → :8880 (IT Tools) 🏠
pdf.ai-impress.com → :8088 (Stirling-PDF) 🏠 ⚠️ broken
sonarr.ai-impress.com → CT111:8989 (Sonarr) 🏠
radarr.ai-impress.com → CT111:7878 (Radarr) 🏠
prowlarr.ai-impress.com → CT111:9696 🏠
qbit.ai-impress.com → CT111:8080 (qBit) 🏠
backup.ai-impress.com → :9898 (Backrest) 🏠
docs.ai-impress.com → :8010 (Paperless) 🏠
links.ai-impress.com → :3000 (Karakeep) 🏠
git.ai-impress.com → :3002 (Forgejo) 🏠
budget.ai-impress.com → :5006 (Actual) 🏠
finance.ai-impress.com → :3003 (Maybe) 🏠
plan.ai-impress.com → :8181 (Plane) 🏠
```
## Tailscale Overlay (remote access)
```
Remote device (Tailscale node)
▼ (WireGuard tunnel, UDP)
pve host — Tailscale IP: 100.122.192.8
└── ssh pve → direct to Proxmox
└── http://192.168.1.48:8006 → PVE Web (need LAN or Tailscale subnet route)
```
> **Note**: Tailscale subnet-router NOT configured (2026-05-03). To access LAN IPs remotely:
> ```bash
> ssh pve "tailscale up --advertise-routes=192.168.1.0/24 --accept-routes"
> ```
> After enabling: approve subnet in Tailscale admin console → all LAN IPs accessible via Tailscale.
---
## LAN Subnet
```
Network: 192.168.1.0/24
Gateway: 192.168.1.1 (TP-Link AX72)
DHCP pool: 192.168.1.100.199
Static/reserved IPs:
.1 — Router (AX72)
.2 — RE605X mesh extender
.3 — RE705X mesh extender
.48 — pve (Proxmox host)
.62 — CT101 (legacy AdGuard, pending destroy)
.71 — CT105 (Immich)
.225 — CT102 (Docker, DNS, NPM)
.230 — CT111 (media)
.232 — CT112 (n8n)
```
---
## DNS Flow (Current vs Target)
### Current (2026-05-03)
```
LAN client DHCP → DNS: 192.168.1.62 (CT101 native AdGuard)
```
### Target (after router DNS update)
```
LAN client DHCP → DNS: 192.168.1.225 (CT102 Docker AdGuard)
Secondary DNS: 1.1.1.1 (fallback)
```
**One-line change**: Router → Network → DHCP → Primary DNS: `192.168.1.225`
---
## Internal Docker Networks (CT102)
Docker containers communicate via internal networks, not through NPM for inter-service calls.
Key networks:
- `npm_default` — NPM + proxy targets
- `monitoring_default` — Prometheus + exporters + Loki + Alertmanager
- `nextcloud_default` — Nextcloud + MariaDB + Redis + Collabora + notify-push
docker-socket-proxy: `0.0.0.0:2376` → LAN-accessible (⚠️ security — should be `127.0.0.1`)
---
## Firewall Summary
| Layer | Rule | Status |
|-------|------|--------|
| Router WAN | Port 80 → NPM | ✅ configured |
| Router WAN | Port 443 → NPM | ✅ configured |
| Router WAN | All other ports | ✅ blocked (SPI firewall) |
| Router WAN | UPnP | ✅ disabled |
| Proxmox | No firewall rules found | ⚠️ consider enabling pve firewall |
| CrowdSec | IPS running | ⚠️ no bouncer — not blocking yet |
---
## Related
- [[wiki/homelab/homelab-services-map|homelab-services-map]] — full service list
- [[wiki/homelab/router-tplink-ax72-config|router-tplink-ax72-config]] — router settings
- [[wiki/infrastructure/server-pve|server-pve]] — Proxmox host

View file

@ -1,6 +1,7 @@
---
tags: [infrastructure, server, proxmox, homelab, personal]
updated: 2026-04-30
updated: 2026-05-03
last_verified: 2026-05-03 (live audit)
---
# pve — Proxmox VE Homelab
@ -8,99 +9,118 @@ updated: 2026-04-30
> SSH alias: `pve``root@192.168.1.48:22`
> Key: `~/.ssh/id_ed25519`
> Web UI: https://192.168.1.48:8006
> Tailscale: 100.122.192.8 (remote access)
## Overview
Home Proxmox VE server. Runs VMs and LXC containers for personal projects, self-hosted services, and homelab experimentation. Connected via Tailscale for remote access.
Home Proxmox VE server (HP EliteDesk 800 G3). Runs LXC containers for personal self-hosted services and homelab experimentation.
- **Platform**: Bare-metal (home server)
- **OS**: Proxmox VE 9.1.8 (kernel 6.17.13-2-pve) — security update 2026-04-24: pve-manager 9.1-8, libngtcp2-quic0, libproxmox-rs-perl, cluster libs
- **IP**: 192.168.1.48 (LAN)
- **Tailscale**: 100.122.192.8 (accessible remotely)
- **CPU/RAM**: Not audited (runs 8 containers + 1 VM comfortably)
- **OS**: Proxmox VE **9.1.9** (kernel **6.17.13-3-pve**)
- **CPU**: Intel i5-7500 (4c/4t, VT-x + VT-d, no HT) — running at load avg ~2.5 (2026-05-03)
- **RAM**: 24 GB DDR4 — **9.7 GB used, 2.2 GB free, 12 GB buff/cache** (2026-05-03)
- **IP**: 192.168.1.48 (LAN) / 100.122.192.8 (Tailscale)
## Storage
| Pool | Type | Total | Used | Available | % |
|------|------|-------|------|-----------|---|
| data-hdd | LVM-thin | 5.6 TB | 31 GB | 5.5 TB | 0.55% |
| local | dir | 68 GB | 6.6 GB | 58 GB | 9.5% |
| local-lvm | LVM-thin | 141 GB | 100 GB | 41 GB | 71% |
| usb-backup | dir | 916 GB | 110 GB | 759 GB | 12% |
| Pool | Type | Total | Used | % | Notes |
|------|------|-------|------|---|-------|
| data-hdd | LVM-thin | 5.6 TB | ~390 GB | 6.99% | HDD — CT102 data (300G), CT105 upload+data (250G), CT111 media (500G) |
| local | dir | 68 GB | 8.3 GB | 13% | NVMe — PVE OS |
| local-lvm | LVM-thin | 141 GB | ~83 GB | **58.85%** | NVMe — all CT/VM root disks |
| usb-backup | dir | 916 GB | 345 GB | **37.58%** | USB Toshiba — vzdump backups |
**local-lvm is 71% full** — watch this pool
### ⚠ LVM-thin thin-pool alert — CT102 root disk
`vm-102-disk-0` (CT102 root, 20GB) shows **99.39%** thin-pool data allocation in `lvs` output.
Inside the container `df` shows only 36% (6.7G/20G) — the gap is due to **missing `fstrim`**.
History: disk was nearly full in April 2026, files deleted but thin-pool blocks not returned.
**Fix (when needed):**
```bash
ssh pve "pct exec 102 -- fstrim -av"
# Or enable periodic trim:
ssh pve "pct exec 102 -- systemctl enable fstrim.timer && systemctl start fstrim.timer"
```
## Virtual Machines
| VMID | Name | Status | RAM | Disk |
|------|------|--------|-----|------|
| 200 | kali-linux | stopped | 8 GB | 60 GB |
| VMID | Name | Status | RAM | Disk | Onboot |
|------|------|--------|-----|------|--------|
| 200 | kali-linux | **stopped** | 8 GB | 60 GB | no (manual only) |
## LXC Containers
| VMID | Name | Status | IP | Purpose |
|------|------|--------|----|---------|
| 101 | adguard | running | 192.168.1.62 | DNS ad-blocking (AdGuard Home) + Docker AdGuard |
| 102 | docker | running | 192.168.1.225 | General Docker host — ~50 containers |
| 105 | immich | running | 192.168.1.71 | Self-hosted photo management |
| 111 | media | running | 192.168.1.230 | Media stack (Jellyfin, Radarr, Sonarr, Jellyseerr) |
| VMID | Name | IP | RAM | Cores | Status | Role |
|------|------|----|-----|-------|--------|------|
| 101 | adguard | 192.168.1.62 | 512 MB | 1 | running | **Legacy** — native AdGuard Home. DNS for LAN currently. Pending destroy. |
| 102 | docker | 192.168.1.225 | 9 GB | 4 | running | Main Docker host — 55+ containers |
| 105 | immich | 192.168.1.71 | 8 GB | 4 | **stopped** | Immich photos — GPU bug (see below) |
| 111 | media | 192.168.1.230 | 4 GB | 4 | running | Jellyfin + *arr + qBit (Intel iGPU) |
| 112 | n8n | 192.168.1.232 | 2 GB | 2 | running | n8n workflow automation |
> CT103/104/107/109/110 **already destroyed** (beszel/vaultwarden/homarr/grafana/uptime-kuma — all migrated to CT102 Docker).
### CT105 — GPU Fix (PENDING)
Host `/dev/dri` contains only: **`card1`** and **`renderD128`** (Intel HD 630).
CT105 conf references `renderD129` and `card0` which **do not exist** → container fails to start.
**Fix:**
```bash
# Remove dev1 (renderD129) and dev2 (card0) — they don't exist on host
ssh pve "pct stop 105" # if running
ssh pve "pct set 105 --delete dev1 && pct set 105 --delete dev2"
ssh pve "pct start 105"
# Keep: dev0 (renderD128) + dev3 (card1)
```
## Host Ports
| Port | Service |
|------|---------|
| 8006 | Proxmox Web UI (HTTPS) |
| 3128 | SPICE proxy |
| 22 | SSH |
| 45876 | Beszel agent |
| 9101 | node_exporter (Prometheus metrics) |
| Port | Service | Binding |
|------|---------|---------|
| 22 | SSH | 0.0.0.0 (all interfaces) |
| 8006 | Proxmox Web UI (HTTPS) | * (all) |
| 3128 | SPICE proxy | * |
| 9101 | node_exporter | * |
| 45876 | Beszel agent | * |
| 111 | rpcbind (NFS leftover) | 0.0.0.0 — consider disabling if no NFS |
## Key Services on Host
- **Tailscale** — remote access overlay (100.122.192.8)
- **Beszel agent** — system monitoring
- **node_exporter** — Prometheus metrics
- **Postfix** — local mail relay
- **Tailscale** — remote access (100.122.192.8). No subnet-router advertised (as of 2026-05-03).
- **Beszel agent** — system monitoring (:45876)
- **node_exporter** — Prometheus metrics (:9101)
- **Postfix** — local mail relay (127.0.0.1:25 only)
## GPU passthrough
Host `/dev/dri`: `card1` (Intel HD 630, minor 1) + `renderD128` (Intel rendernode, minor 128).
AMD Radeon HD 8490 detected as `card0`**does NOT appear in `/dev/dri`** (not loaded for passthrough).
| CT | GPU device | Status |
|----|-----------|--------|
| CT111 | card1 + renderD128 | ✅ working (QuickSync for Jellyfin) |
| CT105 | card1 + renderD128 (dev0+dev3) | ⚠️ blocked — needs dev1+dev2 removed |
## Backup
vzdump job: **daily at 12:20**, mode snapshot, zstd compression, all VMs/LXCs → `usb-backup`.
Config: `/etc/pve/jobs.cfg`
> ⚠ USB backup = single point of failure. Off-site backup (Backblaze B2 / Cloudflare R2 via Backrest) is pending (P2 task).
## Beszel Monitoring
Hub runs in Docker (CT 102) at `http://192.168.1.225:8090`
Hub: CT102 Docker `:8090` (`beszel.ai-impress.com`)
| System | IP | Port | Status |
|--------|-----|------|--------|
| ProxMox (host) | 192.168.1.48 | 45876 | up |
| adguard (CT 101) | 192.168.1.62 | 45876 | up |
| docker (CT 102) | 192.168.1.225 | 45879 | up |
| immich (CT 105) | 192.168.1.71 | 45876 | up |
| media (CT 111) | 192.168.1.230 | 45876 | up |
## Container Details
### CT 101 — adguard
- AdGuard Home DNS server (LXC)
- Also runs Docker AdGuard container — LAN DNS resolver
- IP: 192.168.1.62, Beszel agent: port 45876
### CT 102 — docker
- General-purpose Docker host — ~50 containers
- Check inside with `pct exec 102 -- docker ps`
- **Docker data-root**: `/mnt/data/docker` (data-hdd mount)
- Config: `/etc/docker/daemon.json``{"data-root": "/mnt/data/docker"}`
- **Beszel Hub** at port 8090 — manages all monitoring
- **Beszel agent** at port 45879 (monitors Docker host itself)
- System disk: ~51%
### CT 105 — immich
- Photo management (Google Photos alternative)
- IP: 192.168.1.71, Beszel agent: port 45876
- **PostgreSQL data dir**: `/opt/immich/data/postgresql` (data-hdd symlink)
- **Upload dir**: `/opt/immich/upload` (200 GB data-hdd mount)
### CT 111 — media
- Media stack: Jellyfin, Radarr, Sonarr, Jellyseerr
- IP: 192.168.1.230, Beszel agent: port 45876
- Jellyseerr at `media.ai-impress.com` (5055)
- Jellyfin at 192.168.1.230:8096
|--------|----|------|--------|
| pve (host) | 192.168.1.48 | 45876 | ✅ up |
| adguard (CT101) | 192.168.1.62 | 45876 | ✅ up |
| docker (CT102) | 192.168.1.225 | 45879 | ✅ up |
| immich (CT105) | 192.168.1.71 | 45876 | ⚠️ stopped (CT stopped) |
| media (CT111) | 192.168.1.230 | 45876 | ✅ up |
## Useful Commands
@ -112,26 +132,32 @@ ssh pve "qm list && pct list"
ssh pve "pct exec 102 -- docker ps"
# Start/stop container
ssh pve "pct start 110"
ssh pve "pct stop 110"
ssh pve "pct start 105"
ssh pve "pct stop 101"
# Check storage
ssh pve "pvesm status"
# Check storage utilisation
ssh pve "pvesm status && lvs --units g"
# Free thin-pool space (run after bulk deletes)
ssh pve "pct exec 102 -- fstrim -av"
# Check vzdump jobs
ssh pve "cat /etc/pve/jobs.cfg"
```
## Key Takeaways
## Key Takeaways (2026-05-03)
- **local-lvm at 71%** — clean up unused volumes or expand before hitting 85%
- Kali Linux VM (200) stopped
- AdGuard (CT 101) = DNS for LAN — changing it affects all home devices
- All 4 LXC containers running — healthy cluster
- Tailscale enables access from anywhere without port forwarding
- CT 102 Docker data moved to data-hdd — system disk at 51% (healthy)
- CT 105 PostgreSQL/Immich data moved to data-hdd (healthy)
- Beszel monitoring all 5 systems (pve + 4 LXC) — all UP ✅ (2026-04-30)
- **local-lvm at 58.85%** — improved from 71% (old stale LXCs destroyed)
- **vm-102-disk-0 thin-pool 99.39%** — needs `fstrim` in CT102 (not urgent, df shows 36%)
- **usb-backup 37.58%** — grew from 12% to 37% — monitor retention policy
- CT101 (old adguard) still running and serving LAN DNS — router DHCP still points to 192.168.1.62
- CT105 Immich stopped — GPU fix is 2 commands (`pct set --delete dev1/dev2`)
- Tailscale no subnet-router advertised — LAN-only services not accessible remotely
- rpcbind :111 open on host — disable if NFS not in use
## Related
- [[wiki/homelab/_index|homelab/]] — full homelab docs
- [[wiki/infrastructure/server-aimpress|server-aimpress]]
- [[wiki/homelab/homelab-services-map|homelab-services-map]] — full Docker services + NPM proxy table
- [[wiki/infrastructure/network-topology|network-topology]] — Internet/LAN/Tailscale traffic map
- [[wiki/homelab/router-tplink-ax72-config|router-tplink-ax72-config]] — AX72 + mesh settings
- [[wiki/infrastructure/ssh-aliases|ssh-aliases]]

View file

@ -0,0 +1,49 @@
---
tags: [tech-patterns, auto-generated]
source: 3m-portal
created: 2026-05-05
---
# Using Git Worktrees for Parallel Claude Development Sessions
## When to use
Use git worktrees when you need to run multiple independent Claude sessions simultaneously on different branches without context switching or stashing work.
## Prerequisites
- Git 2.7+
- A repository with multiple branches
- Multiple Claude sessions (or ability to open new ones)
## Steps
1. Create a new worktree for your branch:
```bash
git worktree add ../path-to-worktree branch-name
```
2. Navigate to the worktree directory:
```bash
cd ../path-to-worktree
```
3. Start a new Claude session in this worktree directory
4. Each session works independently on its own branch without affecting others
5. When done, remove the worktree:
```bash
git worktree remove ../path-to-worktree
```
## Key Configuration
- Main worktree location: `project-root/`
- Secondary worktrees: `project-root-worktree-name/` (sibling directories recommended)
- Each worktree maintains its own git state, node_modules, and build artifacts
## Gotchas
- **Shared dependencies**: `node_modules` and build caches are duplicated per worktree—can consume significant disk space
- **Long-running worktrees**: Clean up finished worktrees promptly to avoid confusion
- **Hotfix scenarios**: Best practice is to always create worktrees for hotfix/feature branches, never work directly on main worktree
- **Multiple branch work**: If a branch has uncommitted changes, `git worktree add` will fail—commit or stash first
## Source
Project: 3m-portal