# Serenity Cleanup Wave 1 Plan

Status: approved planning baseline for the first safe cleanup pass on Serenity.

## Goal

Reduce obvious legacy clutter on Serenity without breaking the still-needed torrent/media-locality group or the still-needed Serenity Newt path.

This wave is intentionally conservative.
It does not move qBittorrent/ARR off Serenity yet.
It does not retire Serenity yet.
It does not delete databases that still back live apps.

## Operator decisions already resolved

- Nothing should intentionally remain on Serenity after PD owns the disks locally.
- Technitium already covers the DNS role John wants.
- Serenity Pi-hole remnants should be treated as removable.
- Serenity Newt is still needed and must be preserved.
- GameVault and RomM should migrate, not be pruned.
- Final end-state remains:
  - move qbit + ARR family to PD after storage cutover
  - leave no intentional production app role on Serenity
  - retire Serenity entirely

## Scope of cleanup wave 1

Wave 1 includes only these categories:

1. Remove legacy DNS clutter that should no longer be serving production traffic.
2. Remove obviously stale created/exited containers.
3. Document migration order for the two database-backed apps that should move later.

Wave 1 explicitly excludes:

- qbit
- GluetunVPN
- qbit_manage
- prowlarr
- sonarr
- sonarr-anime
- radarr
- lidarr
- readarr
- readarr-epub
- bazarr
- autobrr
- unpackerr
- Notifiarr
- shelfmark
- Newt
- technitium-dns-pilot
- GameVault
- romm
- reranker

## Live facts this plan is based on

From the live Serenity audit:

- ARR/torrent locality is still tied to `/mnt/user/data`
- `GameVault` points at local Postgres on `10.5.30.5:5432`
- `RomM` points at local MariaDB on `10.5.30.5:3306`
- quick live checks did not surface immediate DB dependencies for `Wizarr`, `Shelfmark`, or `Notifiarr`
- `Newt` is still needed
- legacy Pi-hole containers are still running even though Technitium is now the intended DNS path
- Serenity Newt-backed Pangolin routes still had stale health-check hostnames pointing at old `10.5.1.5` even though their target IPs had already been rewritten to `localhost`
- live workaround applied on 2026-05-25: Serenity now carries runtime alias `10.5.1.5/32` on `br0` so those stale health checks resolve locally again

## Wave 1-A: legacy Pi-hole removal

### Target containers

- `binhex-official-pihole`
- `pihole-serenity`
- `unbound-pihole-serenity`
- `keepalived-pihole-serenity`

### Why they are in scope

- They are legacy DNS/HA remnants.
- Current homelab docs describe the active internal DNS path as the Technitium trio.
- Operator confirmed Technitium covers the intended DNS role.
- Keeping old DNS stacks around increases confusion and future troubleshooting blast radius.

### Preconditions

Before removal, verify only these read-only checks:

1. Serenity Technitium backup node is healthy.
2. DHCP-advertised resolver set is still PD/NOMAD/Serenity Technitium, not Pi-hole.
3. No Pangolin route, bookmark, or admin workflow still intentionally points at a Pi-hole UI.
4. No host on the LAN still relies on the old Pi-hole admin port out of habit.

### Removal order

1. stop `keepalived-pihole-serenity`
2. stop `pihole-serenity`
3. stop `unbound-pihole-serenity`
4. stop `binhex-official-pihole`
5. verify Technitium-only DNS behavior still looks normal
6. remove the stopped containers
7. archive or delete their stale appdata only after a short observation window

### Verification after removal

- Serenity Technitium container remains healthy
- PD and NOMAD Technitium backup flow still looks normal
- no client-facing DNS complaints appear
- no scripts or bookmarks fail because of removed Pi-hole UI endpoints

## Wave 1-B: stale container pruning

### Created-only clutter to remove

- `calibre-web`
- `SuggestArr`
- `Cleanuparr`
- `calibre`
- `agregarr`

### Exited clutter to remove

- `Huntarr`
- `omegabrr`

### Why they are in scope

- They are not live workloads.
- They add noise to `docker ps -a` and make host intent harder to understand.
- There is no current architecture reason to preserve them as active Serenity residents.

### Safe pruning rules

Before deleting each one:

1. confirm container status is still `Created` or `Exited`
2. confirm it is not referenced by a live reverse-proxy route
3. confirm it is not the only source of some needed config/data you still care about
4. if uncertain, export one final metadata snapshot first:
   - image name
   - mounts
   - env file path if obvious

### Practical order

1. remove `Created` containers first
2. remove long-dead exited containers second
3. leave appdata in place initially
4. only delete appdata later after a short cooling-off window

## Wave 1-C: cloudflared deadwood removal

### Target container

- `Unraid-Cloudflared-Tunnel`

### Why it is in scope

- It is already documented in repo docs as dead/stale.
- Pangolin/Newt is the active exposure pattern now.

### Preconditions

1. verify no current DNS/public route still expects this tunnel
2. verify no local notes still treat it as the active exposure path
3. verify Newt-based routes are the real live path

### Action

- stop container
- observe briefly for any missed dependency
- remove container
- leave appdata for later deletion if not immediately certain

## Wave 1-D: DB-backed migration ordering

These apps should not be deleted in wave 1.
They need planned migration.

### Pair 1: GameVault + local Postgres

Live dependency:
- `GameVault` -> `postgresql15`

Recommended sequence:
1. create PD-side target appdata path
2. create PD-side Postgres DB/user on shared-postgres, or a deliberate dedicated PD Postgres if there is a reason not to use shared-postgres
3. export GameVault DB from Serenity
4. import into PD target database
5. migrate GameVault appdata/config
6. recreate GameVault on PD attached to the shared database network if using shared-postgres
7. verify login, library visibility, and metadata path behavior
8. only then retire Serenity `postgresql15`

Default recommendation:
- prefer PD shared-postgres unless GameVault has a proven reason to stay isolated

### Pair 2: RomM + local MariaDB

Live dependency:
- `RomM` -> `MariaDB-Official`

Recommended sequence:
1. create PD-side target appdata path
2. create PD-side MariaDB DB/user on shared-mariadb, or a deliberate dedicated PD MariaDB only if needed
3. export RomM DB from Serenity
4. import into PD target MariaDB
5. migrate RomM appdata/config/assets/resources
6. recreate RomM on PD attached to the shared database network if using shared-mariadb
7. verify UI, library, metadata, and asset behavior
8. only then retire Serenity `MariaDB-Official`

Default recommendation:
- prefer PD shared-mariadb unless RomM proves awkward on the shared stack

## Recommended order across all wave 1 work

1. verify Technitium is the only intended active DNS path
2. remove legacy Pi-hole stack
3. remove dead Cloudflared tunnel
4. remove stale created/exited containers
5. leave GameVault/Postgres and RomM/MariaDB in place until their PD migration is prepared
6. keep qbit/ARR locality untouched until PD storage cutover is real

## Risks and guardrails

### Do not touch yet

Do not touch in this wave:
- qbit
- ARR family
- GluetunVPN
- qbit_manage
- Newt
- technitium-dns-pilot
- GameVault
- romm
- postgresql15
- MariaDB-Official

### Specific guardrails

- Do not delete any appdata directory in the same step as container removal unless the dependency is unquestionably dead.
- Do not remove `postgresql15` until GameVault is verified on PD.
- Do not remove `MariaDB-Official` until RomM is verified on PD.
- Do not move qbit/ARR until PD directly owns the relevant media/torrent paths.
- Do not break Serenity Newt while cleanup is happening.

## Suggested Kanban decomposition

### Card A1 — verify legacy Pi-hole is truly unused
Definition of done:
- current DNS path confirmed as Technitium-only
- no intentional admin dependency on Serenity Pi-hole remains

### Card A2 — remove Serenity legacy Pi-hole containers
Definition of done:
- all four legacy Pi-hole containers stopped and removed
- no DNS regression observed

### Card B1 — remove stale created containers
Definition of done:
- created-only clutter removed
- appdata retained for cooling-off period

### Card B2 — remove stale exited containers
Definition of done:
- exited clutter removed
- appdata retained for cooling-off period

### Card C1 — remove dead Unraid Cloudflared tunnel
Definition of done:
- no public path depends on it
- container removed

### Card D1 — prepare GameVault migration to PD
Definition of done:
- target DB/appdata path chosen
- export/import path documented
- cutover checklist ready

### Card D2 — prepare RomM migration to PD
Definition of done:
- target DB/appdata path chosen
- export/import path documented
- cutover checklist ready

## Open item that still needs verification

- `reranker` mounts `/mnt/user/appdate/reranker`
- verify whether `appdate` is intentional before any future reranker move or cleanup

## Expected result after wave 1

After wave 1, Serenity should still be alive for the workloads that currently justify it, but with much less misleading baggage:

- torrent/media-locality group still intact
- Newt still intact
- Technitium backup node still intact
- GameVault and RomM still live until their migration is prepared
- legacy Pi-hole gone
- dead Cloudflared gone
- stale created/exited clutter gone

That leaves a cleaner host and a safer runway for the later PD storage cutover and full Serenity retirement.

## Wave 1 verification results (2026-05-25)

Verified during this planning pass:

- Serenity still has these live containers relevant to wave 1:
  - `technitium-dns-pilot`
  - `binhex-official-pihole`
  - `pihole-serenity`
  - `unbound-pihole-serenity`
  - `keepalived-pihole-serenity`
  - `Newt`
  - `Unraid-Cloudflared-Tunnel`
- PD still runs the primary Technitium stack plus its own Pi-hole and Newt lane.
- From NOMAD, `/etc/resolv.conf` currently lists `10.5.30.8`, `10.5.30.9`, and `10.5.30.10` ahead of external fallback `9.9.9.9`.
- From NOMAD, `dig` to `10.5.30.8` and `10.5.30.10` succeeded for public DNS resolution; same-host checks to `10.5.30.9` were unreliable, matching the existing macvlan caveat in the docs.
- `Unraid-Cloudflared-Tunnel` is still running, but repo docs already classify it as dead/stale and its container has `Restart=no`.
- Serenity `Newt` must not be treated as deadwood: operator confirmed Pangolin tunnels Serenity resources through Serenity's local Newt instead of routing from PD or NOMAD to Serenity resources over the Serenity LAN IP.
- Live Serenity `Newt` logs still show repeated Pangolin health checks against stale `10.5.1.5` targets (`7474`, `8785`, `8787`, `8788`, `8990`, `8457`, `5690`, `5454`).

Operational implication:

- removing Cloudflared remains low-risk after one final dependency check
- removing the legacy Pi-hole stack remains appropriate
- removing Serenity `Newt` is not appropriate during wave 1
- Pangolin target drift for Serenity-hosted resources should be repaired later by rehoming those resources to the correct Serenity site/local-path model instead of stale literal pre-migration IPs
