GitOps — docker-prod-01
Philosophy
Two-tier service deployment model:
| Tier | Method | Used for |
|---|---|---|
| LXC containers | Proxmox, manually managed | Critical/architectural services — DNS, Gitea, Authelia, reverse proxy, etc. Stable, proven, not worth the overhead of GitOps. |
| Docker (GitOps) | Portainer + Gitea | Application-layer services — dashboards, media tools, productivity apps. Easy to update, redeploy, and replace. |
The rule of thumb: if losing or restarting it takes down infrastructure, it's an LXC. If it's a service that rides on top of infrastructure, it's a Docker stack.
Architecture
Gitea (CT100, pve1-media)
│ Stores docker-compose.yml per stack
│ Renovate bot updates image versions via PRs/commits
│
├──► Webhook on push
│
▼
Portainer (docker-prod-01, CT107)
│ Pulls stack definitions from Gitea
│ Redeploys on webhook trigger
│
▼
docker-prod-01 (CT107, pve1-media)
Runs all Docker stacks
Components
| Component | Host | Role |
|---|---|---|
| Gitea | CT100, pve1-media — git.home.pob.network |
Source of truth. One repo per stack (or grouped). Contains docker-compose.yml files. |
| Portainer | docker-prod-01 — docker-prod-01.pve.pob.network:9443 |
Stack manager. Connected to Gitea via Git stacks. Receives webhooks to trigger redeployment. |
| Renovate | Gitea Actions (workflow) | Monitors image tags in compose files. Opens PRs or commits updates automatically. Triggers redeployment pipeline on merge. |
| docker-prod-01 | CT107, pve1-media, 10.37.64.41 |
Docker host. Runs all stacks. Second NIC on VLAN 232 (IoT) for planned Home Assistant container. |
Deployment Flow
- Renovate detects a new image version in a
docker-compose.yml - Renovate commits/merges the update to the Gitea repo
- Gitea fires a webhook to Portainer
- Portainer pulls the updated stack definition and redeploys
Manual deployments also possible via Portainer UI or direct Gitea push.
Storage
App data for Docker stacks is stored on an encrypted ZFS dataset mounted into the container.
Running Stacks
All stacks managed via Portainer, sourced from Gitea.
| Stack | URL | Port | Notes |
|---|---|---|---|
actualbudget |
budget.home.pob.network |
4040 | Budget tracking |
babybuddy |
babybuddy.home.pob.network |
4010 | Baby tracking |
beszel-agent |
— | — | Monitoring agent reporting to beszel (CT102) |
homer |
home.pob.network |
4030 | Homelab dashboard |
invidious |
invidious.home.pob.network |
4020 | Private YouTube frontend |
signal-cli |
— | — | Signal messenger integration (no web UI) |
teslamate |
teslamate.home.pob.network |
4001 / 4002 / 4003 | Tesla data: main app / Grafana / API |
Portainer itself runs on docker-prod-01 at port 9443, accessible via docker-prod-01.pve.pob.network:9443 (Tailscale only, OIDC via Authelia).
Postfix runs directly on the LXC container (not a Docker stack). It serves as the internal SMTP relay (smtp.pve.pob.network) using Google Workspace for delivery. See dns.md for the CNAME.