Files
homelab-configs/README.md
T

7.4 KiB

Homelab Configs

Docker Compose files and configuration for homelab infrastructure. All stacks are managed via Portainer at http://192.168.88.27:9000 (or https://portainer.jgitta.com).

Portainer Access

Item Value
URL http://192.168.88.27:9000
External URL https://portainer.jgitta.com
API Token ptr_1cThi+cjOKeICslJbSzCtUhORF06xUOykbAWPUoTyMU=

Note: The API token above is for automation/scripting. Keep it private. To call the Portainer API: curl -H "X-API-Key: <token>" http://192.168.88.27:9000/api/stacks

Important — Volume Paths: All volume mounts in Portainer stacks must use absolute paths (e.g. /srv/docker/myapp/data:/app/data). Relative paths (e.g. ./data) resolve to Portainer's internal /data/compose/<id>/ directory and will lose data if the stack is redeployed with a different ID. This was audited and corrected on 2026-05-07.

Hosts

Host IP Role Portainer Endpoint ID Docker Version
siklos 192.168.88.27 Main Docker server (VM 112 on Proxmox) 3 (local) 26.1.5
jellyfin 192.168.88.10 Media server 4 (agent) 26.1.5
jgpc 192.168.88.41 Workstation / Ollama / AI 5 (agent) 29.4.2

Stack Inventory

siklos (192.168.88.27) — 20 stacks

Stack Port(s) Data Path URL Notes
actual-budget 5006 /srv/docker/actual-budget budget.jgitta.com Budget tracking
beszel 8085 /srv/docker/beszel beszel.jgitta.com Beszel hub — all-in-one monitoring (replaced Prometheus/Grafana/cAdvisor)
dashboard 8096 /srv/docker/dashboard dashboard.jgitta.com Custom homepage
dashy 8081 /srv/docker/dashy dashy.jgitta.com Dashboard
gitea 3002, 2222 /srv/docker/gitea/data gitea.jgitta.com Git server — this repo
glances 61208 glances.jgitta.com System monitoring
goldengames 3030 /srv/docker/goldengames goldengamer.org (built locally)
guacamole 8080 /srv/docker/guacamole apache.jgitta.com Apache Guacamole — remote desktop gateway
homarr 7575 /srv/docker/homarr/.homarr/appdata homarr.jgitta.com Dashboard
karakeep 3010 /srv/docker/karakeep notes.jgitta.com Bookmarks / read-later
kopia 51515 /srv/docker/kopia kopia.jgitta.com Backup tool (backs up to TrueNAS)
linkwarden 3015 /srv/docker/linkwarden/pgdata links.jgitta.com Link manager
litellm 4000 /srv/docker/litellm LLM API gateway
meshcentral 444 /srv/docker/meshcentral mesh.jgitta.com Remote management
onlyoffice 8880 /srv/docker/onlyoffice office.jgitta.com Office document server (replaced Collabora)
pihole host network /srv/docker/pihole pihole.jgitta.com DNS ad blocker
portainer 9000, 9443 /srv/docker/portainer portainer.jgitta.com Container management UI
uptime-kuma 3001 /srv/docker/uptime-kuma/data status.jgitta.com Uptime monitoring
watchtower Auto-updates containers
wordpress 8095 /srv/docker/wordpress jgitta.com WordPress site

jellyfin (192.168.88.10) — 3 stacks

Stack Port(s) Data Path Notes
arr-stack various /srv/docker Radarr, Sonarr, Prowlarr, Flaresolverr, Watchtower
beszel-agent 45876 Beszel agent (systemd binary, not Docker)
portainer-agent 9001 Portainer agent (fully managed)

jgpc (192.168.88.41) — 4 stacks

Stack Port(s) Data Path Notes
frigate 5000, 8554, 8555 /srv/docker/frigate NVR / camera AI
open-webui 3000 /srv/docker/open-webui Ollama web UI
portainer-agent 9001 Portainer agent (shows "limited" — expected, see notes)
stirling-pdf 8081 /srv/docker/stirling-pdf PDF tools
beszel-agent 45876 Beszel agent (systemd binary, not Docker)

Caddy Reverse Proxy

Caddy runs on a dedicated VM at 192.168.88.110 (alias: caddy) as a systemd service. It handles all HTTPS termination and reverse proxying for *.jgitta.com subdomains. TLS certificates are obtained automatically via Cloudflare DNS challenge (Let's Encrypt).

Config location: /etc/caddy/ on the caddy VM.

File Structure

File Purpose
Caddyfile Main file — sets global options, imports snippets and sites
snippets.caddy Reusable blocks: web_secure, internal_only, proxy_timeouts, etc.
sites/infrastructure.caddy Management/tool services (portainer, kopia, beszel, pihole, etc.)
sites/media.caddy Media and automation stack (jellyfin, sonarr, radarr, next, etc.)
sites/homenet.caddy Internal .homenet HTTP-only domains (no TLS)
sites/goldengamer.caddy goldengamer.org external domain

Key Snippets

  • internal_only — Blocks requests from outside 192.168.88.0/24 and 192.168.2.0/24 via abort. Used on sensitive services (portainer, pihole, proxmox, etc.).
  • web_secure — Standard security headers + gzip compression.
  • proxy_timeouts — 90s read/write timeouts on upstream connections.

DNS Notes

  • Internal services use MikroTik DNS (192.168.88.1) to resolve *.jgitta.com192.168.88.110.
  • Browsers with DNS-over-HTTPS (DoH) enabled (e.g. Brave) bypass MikroTik DNS and use public resolvers, which have no record of internal-only subdomains. Disable DoH in browser settings or ensure Cloudflare DNS has grey-cloud records pointing to the WAN IP for all subdomains.
  • Public-facing services use Cloudflare DNS (grey cloud) → WAN IP → MikroTik port-forwards 443 → Caddy VM.
  • internal_only services should use grey-cloud Cloudflare records (not orange/proxied) — orange cloud sends traffic from Cloudflare's IPs which internal_only will abort, causing a 520 error.

Data Directory Convention

All stack data is stored under /srv/docker/<stack-name>/ on each host. All Portainer volume mounts must use absolute paths — relative paths break on stack redeploy.

Old compose files were renamed to .bak after migration to Portainer.

Kopia Backup Notes (updated 2026-05-07)

Kopia backs up Nextcloud data (VM 103) and other sources to TrueNAS NFS.

  • Cache limit set to 4 GB content + 512 MB metadata (kopia cache set)
  • /tmp and /app/logs are bind-mounted out of the container to prevent overlay2 growth
  • After-snapshot hook pings Uptime Kuma heartbeat at status.jgitta.com after each backup
  • If disk fills up again, check /srv/docker/kopia/tmp/ for leftover verify/restore artifacts
  • Ignore policy active for /data/.claude in the Nextcloud data source

Portainer Agent Notes

Portainer agents run on jellyfin and jgpc, allowing the central Portainer instance on siklos to manage all three Docker hosts from one UI.

  • jellyfin agent: Fully managed by Portainer (Stack ID 36)
  • jgpc agent: Shows as "limited" in Portainer UI — this is expected and harmless. The portainer-agent cannot redeploy itself through its own proxy (catch-22). The agent is stable and the endpoint is fully functional. Agent data is persisted in the portainer_agent_data Docker named volume so TLS certs survive restarts.

Proxmox / Infrastructure Notes

Item Details
Proxmox host 192.168.88.25
PBS 192.168.88.60
TrueNAS 192.168.88.24
Nextcloud VM VM 103 (192.168.88.62)
OCIS VM VM 114 (192.168.88.63) — cloud.jgitta.com
Docker server VM VM 112 = siklos (192.168.88.27)
Caddy proxy VM 192.168.88.110