Blame
|
1 | # Network Stack |
||||||
| 2 | ||||||||
| 3 | ← [[Home]] |
|||||||
| 4 | ||||||||
| 5 | Services running on PCT 108 (network, 192.168.2.82) — the Docker Swarm manager node. |
|||||||
| 6 | ||||||||
| 7 | --- |
|||||||
| 8 | ||||||||
| 9 | ## Service URLs |
|||||||
| 10 | ||||||||
| 11 | | Service | URL | Internal | |
|||||||
| 12 | |---------|-----|----------| |
|||||||
| 13 | | Traefik dashboard | `traefik.carr-family.org` | `192.168.2.82:443` | |
|||||||
| 14 | | Portainer | `portainer.carr-family.org` | `192.168.2.82:9443` (HTTPS) | |
|||||||
| 15 | | Homarr | `homepage.carr-family.org` | `192.168.2.82:7575` | |
|||||||
| 16 | | Authentik | `auth.carr-family.org` | — | |
|||||||
| 17 | | Guacamole | `guac.carr-family.org` | `192.168.2.82:8080` | |
|||||||
| 18 | | CloudBeaver | `db.carr-family.org` | `192.168.2.82:8978` | |
|||||||
| 19 | | Dozzle | `dozzle.carr-family.org` | — (global, all nodes) | |
|||||||
| 20 | ||||||||
| 21 | --- |
|||||||
| 22 | ||||||||
| 23 | ## Authentik (stack: `authentik`, compose 23) |
|||||||
| 24 | ||||||||
| 25 | SSO at `auth.carr-family.org`. Image: `ghcr.io/goauthentik/server:2026.2`. |
|||||||
| 26 | ||||||||
| 27 | Services: server, worker, proxy outpost, postgres:16-alpine (host port 5433), redis:7-alpine. |
|||||||
| 28 | ||||||||
|
29 | **Proxy outpost** (`ghcr.io/goauthentik/proxy:2026.2`) — handles Traefik ForwardAuth requests. Connects to `authentik` and `traefik-public` networks. ForwardAuth address: `http://authentik_authentik-proxy:9000/outpost.goauthentik.io/auth/traefik`. |
||||||
|
30 | |||||||
|
31 | The proxy outpost also has its own Traefik router (`authentik-outpost`) that catches all `*.carr-family.org` requests with path `/outpost.goauthentik.io/` (priority 15) so auth callbacks work after login. |
||||||
| 32 | ||||||||
| 33 | **Env file:** `/root/authentik.env` on PCT 108 (chmod 600). Required vars: `AUTHENTIK_SECRET_KEY`, `PG_USER`, `PG_PASS`, `PG_DB`. |
|||||||
|
34 | |||||||
| 35 | **Redeploy:** |
|||||||
| 36 | ```bash |
|||||||
| 37 | pct exec 108 -- bash -c "set -a && source /root/authentik.env && set +a && docker stack deploy -c /mnt/tank/appdata/portainer/compose/23/docker-compose.yml authentik" |
|||||||
| 38 | ``` |
|||||||
| 39 | ||||||||
|
40 | **Trusted IP bypass:** LAN `192.168.2.0/24`, Tailscale `100.64.0.0/10`, `205.194.16.9/32` (friend's house). Edit in Authentik Admin → Policy Engine → Policies → `Trusted IP Bypass`. |
||||||
| 41 | ||||||||
| 42 | **IP bypass mechanism:** Expression Policy `Trusted IP Bypass` is bound (un-negated) to the Identification and Password stages of `default-authentication-flow`. Returns `False` for trusted CIDRs → stages skipped → auto-authenticated. |
|||||||
|
43 | |||||||
|
44 | > Note (2026-06-12): `authentik` middleware removed from all `routes.yml` routers — all static routes are now unprotected. Services with authentik in their compose `deploy.labels` still have it but the middleware definition is gone. To re-enable for a service, add `authentik@file` middleware definition back to `routes.yml` first. |
||||||
| 45 | ||||||||
| 46 | > Note (2026-05-29): Secret key and PG_PASS were regenerated after Portainer lost env vars. Sessions invalidated; DB intact. |
|||||||
|
47 | |||||||
| 48 | --- |
|||||||
| 49 | ||||||||
| 50 | ## Homarr (stack: `documents-homarr`, compose 22) |
|||||||
| 51 | ||||||||
|
52 | Dashboard at `homepage.carr-family.org`. Image: `ghcr.io/homarr-labs/homarr:latest`. Pinned to manager node. |
||||||
|
53 | |||||||
|
54 | - **Port:** 3001 (published) → 7575 (internal nginx); Traefik label also targets 7575 (internal port is 7575, not 3000) |
||||||
| 55 | - **Appdata:** `/mnt/tank/appdata/homarr/` on PCT 108 rootfs (LVM, not ZFS) |
|||||||
|
56 | - **DB:** `/mnt/tank/appdata/homarr/db/db.sqlite` (SQLite) |
||||||
|
57 | - **Encryption key:** `SECRET_ENCRYPTION_KEY` in compose (AES-256-CBC) |
||||||
| 58 | - **Population script:** `/root/populate-homarr.js` on Proxmox host (regenerates all apps/sections/integrations from scratch) |
|||||||
|
59 | |||||||
|
60 | **After any re-populate, restore board permissions:** |
||||||
|
61 | ```bash |
||||||
| 62 | pct exec 108 -- sqlite3 /mnt/tank/appdata/homarr/db/db.sqlite " |
|||||||
| 63 | INSERT OR IGNORE INTO boardUserPermission VALUES ('a2tzcbvgfkkt16aamvuwa6rs','bskmlbq5oayy4845ekbomk9y','full'); |
|||||||
| 64 | INSERT OR IGNORE INTO boardGroupPermission VALUES ('a2tzcbvgfkkt16aamvuwa6rs','nw94xpf6j307ceruir2b82x9','full');" |
|||||||
| 65 | ``` |
|||||||
| 66 | ||||||||
|
67 | To edit DB safely: scale to 0, edit, scale to 1. |
||||||
| 68 | ||||||||
| 69 | **Integrations configured:** Sonarr, Radarr, Prowlarr, Jellyseerr (all apiKey). |
|||||||
| 70 | ||||||||
| 71 | **Manual setup required:** Jellyfin (username+password, not API key), qBittorrent. |
|||||||
| 72 | ||||||||
| 73 | **Do not add:** `immich` and `paperlessNgx` integration kinds crash the integrations page in this Homarr version. |
|||||||
|
74 | |||||||
| 75 | --- |
|||||||
| 76 | ||||||||
| 77 | ## Guacamole (stack: `network-guacamole`, compose 6) |
|||||||
| 78 | ||||||||
|
79 | Remote desktop gateway at `guac.carr-family.org`. guacamole v1.6.0 + guacd + postgresql:15 (host port 5434). All services 1/1. |
||||||
|
80 | |||||||
| 81 | --- |
|||||||
| 82 | ||||||||
| 83 | ## CloudBeaver (stack: `network-cloudbeaver`, compose 31) |
|||||||
| 84 | ||||||||
|
85 | DB viewer at `db.carr-family.org` (lan-only). Pinned to `network` node. Workspace: `/mnt/tank/appdata/cloudbeaver/workspace`. |
||||||
|
86 | |||||||
| 87 | **DB Connections:** |
|||||||
| 88 | ||||||||
|
89 | | Name | Host | Port | User | Password | DB | |
||||||
| 90 | |------|------|------|------|----------|----| |
|||||||
| 91 | | authentik | 192.168.2.82 | 5433 | authentik | (see `/root/authentik.env` on PCT 108) | authentik | |
|||||||
| 92 | | guacamole | 192.168.2.82 | 5434 | guacamole | 32Ab0321!! | guacamole | |
|||||||
| 93 | | nextcloud | 192.168.2.105 | 5432 | nextcloud | 32Ab0321!! | nextcloud | |
|||||||
| 94 | | paperless | 192.168.2.105 | 5433 | paperless | eWJarhDasRNBu0LfBwuI6VPOXwnRCUy | paperless | |
|||||||
| 95 | | linkwarden | 192.168.2.105 | 5434 | postgres | 32Ab0321!! | postgres | |
|||||||
| 96 | | immich | 192.168.2.105 | 5435 | immich | T5dBbAvgHWceH7jhsxjism4b2Cre9NA | immich | |
|||||||
| 97 | | litellm | 192.168.2.83 | 5433 | litellm | litellm | litellm | |
|||||||
|
98 | |||||||
|
99 | Postgres ports are exposed host-mode on each node's LAN IP. Redeploy the DB stack after adding new port mappings. |
||||||
|
100 | |||||||
| 101 | --- |
|||||||
| 102 | ||||||||
| 103 | ## Watchtower (stack: `watchtower`) |
|||||||
| 104 | ||||||||
|
105 | Automatic image updates daily at 04:00 AM (`0 0 4 * * *` — cron6 format, seconds first). |
||||||
|
106 | |||||||
|
107 | - **Mode:** Global (one instance per node — covers Swarm services and standalone containers on all nodes) |
||||||
|
108 | - **Config:** `WATCHTOWER_CLEANUP=true`, `WATCHTOWER_ROLLING_RESTART=true`, `DOCKER_API_VERSION=1.40` |
||||||
| 109 | - **Compose:** `/mnt/tank/appdata/watchtower/docker-compose.yml` |
|||||||
|
110 | - **TZ:** `America/New_York` |
||||||
| 111 | - **Notifications:** Disabled (removed 2026-06-12 — was spamming emails). The `smtp-relay` sidecar (`boky/postfix`) remains in the compose file but is unused. |
|||||||
| 112 | ||||||||
| 113 | `DOCKER_API_VERSION=1.40` is required — Watchtower defaults to 1.25 which Docker 29.x rejects (minimum accepted is 1.40). |
|||||||
|
114 | |||||||
|
115 | **Excluding containers** — containers with `network_mode: "service:..."` or `depends_on` are incompatible with `WATCHTOWER_ROLLING_RESTART=true`. Watchtower exits with code 1 on startup if it finds one. Exclude with: |
||||||
| 116 | ```yaml |
|||||||
| 117 | labels: |
|||||||
| 118 | - "com.centurylinklabs.watchtower.enable=false" |
|||||||
| 119 | ``` |
|||||||
| 120 | ||||||||
| 121 | **Currently excluded (update manually):** |
|||||||
| 122 | - `gluetun-proton` and `qbittorrent-vpn` — compose at `/root/stacks/bittorrent-vpn/docker-compose.yml` on PCT 101; qbittorrent-vpn uses `network_mode: "service:gluetun"` |
|||||||
|
123 | |||||||
| 124 | --- |
|||||||
| 125 | ||||||||
| 126 | ## Dozzle (stack: `dozzel`, compose 25) |
|||||||
| 127 | ||||||||
|
128 | Live container log viewer at `dozzle.carr-family.org`. Global mode — one instance per worker node (does not run on PCT 108 manager). |
||||||
| 129 | ||||||||
| 130 | --- |
|||||||
| 131 | ||||||||
| 132 | ## Portainer (stack: `network`) |
|||||||
| 133 | ||||||||
| 134 | Swarm UI at `portainer.carr-family.org` (port 9443 HTTPS). Image: `portainer/portainer-ce:latest`. |
|||||||
| 135 | ||||||||
| 136 | - Stack compose files: `/mnt/tank/appdata/portainer/compose/<id>/docker-compose.yml` |
|||||||
| 137 | - Internal DB: `network_portainer_data` Docker volume on PCT 108 rootfs |
|||||||
| 138 | - **Env var gotcha:** Portainer stores stack env vars in its internal DB — there are no `.env` files on disk. When redeploying via CLI, always export vars manually in the shell first. |
|||||||
