8.9 KiB
Jupiter — Docker → Unraid Template/Compose Adoption Plan
System: Jupiter (Unraid primary container host) — 172.16.3.20, SSH root@:22
(creds: infrastructure/jupiter-unraid-primary.sops.yaml).
Goal: make every container show Unraid's UI features (WebUI button, icon, update-check,
rich Edit form) by giving it the net.unraid.docker.* labels it currently lacks.
Status: INSPECTION + PLANNING complete (2026-06-01). Target #1 (gururmm-agent) DONE
2026-06-01 — workflow validated. Remaining recreates HELD for a maintenance window.
Execution log
- 2026-06-01 — gururmm-agent [DONE]. Wrote
templates-user/my-gururmm-agent.xml; backed up full inspect to/root/gururmm-agent.inspect.bak.json; stopped+rm'd, recreated viadocker runwith-l net.unraid.docker.managed=dockerman+ the captured spec. Verified: label=dockerman, config faithful, agent re-authenticated and resumed metrics/inventory/check polling. One clean exit-0 restart at startup = the agent's self-update finalize (cleaned rollback artifacts), then stable. Now shows as a managed container in the Unraid Docker tab with the rich Edit form.- device-id persistence [FIXED 2026-06-01]: the agent's device-id lived at
/var/lib/gururmm/.device-idinside the container (ephemeral). Fix:docker cp'd the live/var/lib/gururmm/.out to/mnt/user/appdata/gururmm/lib/(preserving device-id88abeef0-cb3a-4c3f-9353-61fedcdf587d), added a-v /mnt/user/appdata/gururmm/lib:/var/lib/gururmmmapping + matching template Config, and recreated. Verified the agent reused the same device-id (no "Persisting new device ID") and the same agent_id443bfabb— identity now durable across recreates/updates. Enrollment identity also persists viaconfig.tomlin/config. - Ghost check [CLEAN]: GuruRMM
/api/agentsshows exactly one Jupiter row (443bfabb, last-seen current). The three recreates created no duplicate. Incidental:GURU-KALIhas ~11 duplicate agent rows (v0.6.46/0.6.50, stale) — same ephemeral-identity pattern on a frequently-reinstalled box; cleanup candidate, out of scope for this task.
- device-id persistence [FIXED 2026-06-01]: the agent's device-id lived at
Why the features are missing
Unraid's per-container UI (WebUI/icon/update-check/Edit) is driven by container labels
(net.unraid.docker.managed, .webui, .icon) + a template XML in
/boot/config/plugins/dockerMan/templates-user/. Those labels are immutable on a running
container — they're baked in at docker create time. Containers started by raw
docker run / docker-compose CLI (instead of Unraid's "Add Container" form or the Compose
Manager plugin) never get them. The only fix is to RECREATE each container through the
proper mechanism. Data in mapped volumes is untouched by a recreate; the risk is downtime +
getting the recreate config exactly right.
Two correct mechanisms (both yield the full UI feature set):
- dockerman template — for single CLI containers. Unraid "Add Container" → template.
- composeman (Compose Manager plugin) — for multi-container compose stacks. Adopt the
existing
docker-compose.ymlinto the plugin so the whole stack gets the labels while keeping its compose orchestration + private network. Plugin IS installed (only "RustDesk" registered today).
Inventory (21 containers; 14 raw / managed=NONE)
Already templated (managed=dockerman) — no action
DockerUISP, Seerr, qbittorrent, binhex-emby, binhex-sabnzbd, binhex-plexpass, rsync-server
Raw (managed=NONE) — the targets, grouped by disposition
| Container | Image | Created via | Existing template | Disposition | Risk |
|---|---|---|---|---|---|
| gururmm-agent | localhost:3000/azcomputerguru/gururmm-agent:latest | CLI, net=host | none | NEW dockerman template | LOW |
| youtube-sync-test | azcomputerguru/youtube-sync:latest | CLI | none | NEW template (or retire — "test") | LOW |
| binhex-radarr | binhex/arch-radarr | CLI | my-binhex-radarr.xml | reconcile + recreate from template | MED |
| binhex-sonarr | binhex/arch-sonarr | CLI | my-binhex-sonarr.xml | reconcile + recreate from template | MED |
| MariaDB-Official | mariadb:latest | CLI | my-MariaDB-Official.xml | reconcile + recreate (snapshot appdata first) | MED (DB) |
| seafile + seafile-mysql + seafile-memcached + seafile-elasticsearch | seafileltd/seafile-pro-mc:12.0 / mariadb:10.6 / memcached:1.6.18 / elasticsearch:7.17.26 | compose dockercompose @ /mnt/user0/SeaFile/DockerCompose/docker-compose.yml |
partial (my-SeaFile*.xml, my-memcached.xml) | adopt stack into Compose Manager | MED-HIGH |
| gitea + gitea-db | gitea/gitea:latest / mysql:8 | compose gitea @ /mnt/cache/appdata/gitea/docker-compose.yml |
none | adopt stack into Compose Manager | HIGH (repos + GuruRMM build pipeline) |
| npm | jc21/nginx-proxy-manager:latest | CLI | my-NginxProxyManager.xml | reconcile + recreate from template | HIGH (public reverse proxy) |
| app (Discourse) | local_discourse/app | Discourse ./launcher (no compose file) |
none | LEAVE AS-IS — self-managed; templating breaks ./launcher rebuild |
n/a |
| radio-archive | radio-archive:latest | compose app |
none | tied to Discourse project — leave with app | LOW |
Note: several CLI containers (npm, radarr, sonarr, MariaDB-Official) already HAVE a matching template XML — the running container just isn't linked to it (recreated via CLI later, which stripped the managed label). For these, recreate-from-existing-template is the easy path, but verify the template's ports/paths/env still match the live container before applying.
Recreate sequencing (least → most critical)
Do them one at a time, verify each comes back healthy before the next.
- gururmm-agent — LOW. Local image, net=host, no public dependents. Proves the workflow. Spec captured below.
- youtube-sync-test, radio-archive — LOW. (Confirm youtube-sync-test isn't disposable first.)
- binhex-radarr, binhex-sonarr — MED. Media, non-critical, templates already exist.
- MariaDB-Official — MED. Snapshot
/mnt/.../appdata(or mysqldump) first. - seafile stack — MED-HIGH. Adopt into Compose Manager. Backup first.
down→ register →up. - gitea + gitea-db — HIGH, dedicated window. Backup gitea appdata +
mysqldumpgitea-db first. Pausing Gitea stops repo access AND the GuruRMM webhook build pipeline. Adopt the existing compose into Compose Manager. - npm — HIGH, schedule with comms. Recreating drops the public reverse proxy → all proxied
public services (connect., rmm., git., community., seafile.) briefly down. Backup
/data+/etc/letsencryptfirst. Recreate from my-NginxProxyManager.xml (verify port maps: 80→1880, 81→7818, 443→18443). - Discourse (app) — LEAVE.
Captured recreate spec — gururmm-agent (target #1)
Image: localhost:3000/azcomputerguru/gururmm-agent:latest
Network: host
Restart: unless-stopped
Privileged: false CapAdd: none Devices: none (kvm passed as a bind mount)
Entrypoint: /usr/local/bin/gururmm-agent
Cmd: run
Env: GURURMM_CONFIG=/config/config.toml
Volumes:
/dev/kvm -> /dev/kvm (ro)
/proc -> /proc (ro)
/sys -> /sys (ro)
/var/run/docker.sock -> /var/run/docker.sock (rw)
/var/run/libvirt/libvirt-sock -> /var/run/libvirt/libvirt-sock (ro)
/mnt/user/appdata/gururmm -> /config (rw)
Equivalent docker run (what the dockerman template encodes):
docker run -d --name gururmm-agent \
--network host --restart unless-stopped \
-e GURURMM_CONFIG=/config/config.toml \
-v /dev/kvm:/dev/kvm:ro \
-v /proc:/proc:ro \
-v /sys:/sys:ro \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/run/libvirt/libvirt-sock:/var/run/libvirt/libvirt-sock:ro \
-v /mnt/user/appdata/gururmm:/config \
--entrypoint /usr/local/bin/gururmm-agent \
localhost:3000/azcomputerguru/gururmm-agent:latest run
Recreate path: build the template in Unraid "Add Container" (Repository, Network=host, the 6
path mappings, the env var, Extra Params --entrypoint /usr/local/bin/gururmm-agent, Post
Arguments run), docker stop && docker rm gururmm-agent, then apply the template. Note: it's
a localhost-registry image, so Unraid update-check won't be meaningful — but WebUI(n/a)/icon/Edit
form all come back.
Open items before execution
- Confirm
youtube-sync-testis keep-or-retire (the "-test" name suggests disposable). - For each "template exists" container (npm/radarr/sonarr/MariaDB-Official): diff the template
XML against the live
docker inspect(ports/paths/env) so the recreate doesn't lose config. - Pick the maintenance window(s). Suggest: a low-risk batch (1-4) any time; seafile its own slot; gitea + npm each in a dedicated announced window, backup-first.