Files
felhom.eu/REPORT-night-2026-10-14.md
T

11 KiB
Raw Blame History

Night 2026-10-14 — https only (P1), then the media drive events (unattended)

What waits on you this morning

  1. Vouch controller 0.312.0, then raise the global floor to 0.312.0 (hub → Configs). This makes every box https only, Tester 2 too. If you do not: only the three test boxes are https only.
  2. Decide the Plex access (D9, R-1046): the household's Plex token, or Plex trusts the box's own address. I recommend: trust the box's address.
  3. Plex claim test, 5 minutes (R-1028): open plex.tv/claim. Put the code in ~/.felhom-tester1/plex-claim on DooPlex, chmod 600. Do not paste it in chat. Then say „done”. I claim the throwaway plex-k6 with it and read the result.
  4. HSTS length (D10, R-1041): keep one day now, or one year now. I recommend: one day now, one year after a month with no trouble.
  5. Optional (R-1042): give each box's Cloudflare key „Zone → Zone Settings → Edit” in the Cloudflare dashboard. Then Cloudflare's „Always Use HTTPS” can be a second layer. Without it, the box layer is enough.
  6. Tester 2 (sajatfelhom.hu): nothing to do there. It gets https only with the floor of item 1, when it is on again.
  7. Teardown word for Tester 1 (R-1022): say „tear it down” when you want it back. Now it has three test drives and a throwaway Plex.
  8. System poster: it needs a refresh for „https only” (the facts file is updated; the drawing is not).

No leg stopped. No STOP condition was hit.

Decision I took (decided by CC unattended — you may reverse)

  • 09 §3 decision 246: https only is enforced on the box (traefik), not at Cloudflare. Reason: no box's Cloudflare key may change zone settings (measured 403 on all three zones). The box layer covers every name, also unknown names. It is re-applied when it drifts.
  • Your two rulings are recorded as decisions 244 (R-1033 is P1) and 245 (drive events = option A).

1. https only

  • Which boxes: Tester 1 (enkicsifelhom.hu), demo-hp (enkisfelhom.hu), demo-felhom (demo-felhom.eu).
  • What it does: a plain http:// request gets 301 to the same https:// address. The path and the query stay. A name that does not exist also gets the 301. https:// answers are the same as before. Browsers get Strict-Transport-Security: max-age=86400 (one day). No includeSubDomains. No preload.
  • Proof: scripts/https_only_check.py asked 29 public names on the three boxes: all OK. Its negative control (a stub answering 200 over http) was convicted. Its positive control (Tester 1's dashboard) passed. Before and after headers per box are in documentation/audits/https-only-2026-10-14/.
  • Sonarr sign-in: Sonarr still sends its own http://…/login redirect. The browser then gets the 301 to https. The password goes to https only.
  • Where: in the controller's traefik file. The controller writes it at start and on every health tick. An old or changed file is rewritten. So a new box gets it with the controller, with no step.
  • Code: controller v0.312.0 (8bc7ec5). Two new tests. I saw both fail when I removed the redirect, and when I made HSTS one year. A third test failed when the drift rewrite was removed.
  • Other zones: only Tester 2 sajatfelhom.hu (box off, controller 0.292.0). Not changed.
  • Nightly check: nightly-rotation.md now runs https_only_check.py first every night.

2. While a drive is gone, what each app loses

Nothing. Media B was pulled for 4 minutes.

  • Plex scans (empty trash on and off): no item removed. Watch count kept.
  • Jellyfin scan: no item removed. Watched mark kept.
  • Sonarr and Radarr refresh and rescan (unmonitor on and off): nothing changed.
  • After the return: every torrent seeds again. No re-check. No missing files.
  • Every file on Media A and B was the same at the end as at 22:52.

Why it is safe: the guest keeps a dead mount. Every read is an I/O error. Each app reads that as „unavailable”, not as „deleted”.

Guards that are needed:

  1. Bind only the drives that are there. A bind to an absent path stops the app from starting.
  2. Before a safe removal, recreate the media apps without that drive.
  3. Restart through the controller's environment, never with a bare docker compose.
  4. When a drive comes back, restart every container that uses it, FileBrowser too.
  5. Write Transmission's settings at start, not by its API.

Guards NOT needed — do not build them: scan protection for Plex and Jellyfin; unmonitor protection for Sonarr and Radarr; torrent pausing on a pull.

One warning: the fix for R-1038 must not change the dead mount into an empty folder. An empty folder can look like „all files deleted” to a scan.

3. A new drive: what the box can make ready alone

Media C was added. One script run made it ready in every app. A second run changed nothing.

app alone?
qBittorrent, Transmission, Sonarr, Radarr, FileBrowser yes
Plex yes, but only with a token (D9 decides which)
Jellyfin yes, if the box made the first admin. If not: one household step (an API key)
Prowlarr nothing to do per drive

4. The other tests

  • Safe removal (K3): pausing only that drive's torrents works. But the eject does not free the drive from the running apps: they still read its files. After the eject the drive is also forgotten, so the household must attach it again. A restart after the eject fails, because the bind path is gone. → R-1044.
  • Dead-drive check (K4): read /proc/self/mountinfo. A dead drive shows shutdown. No disk access is needed. Each container's own mountinfo shows if it still holds the dead drive. A timed stat is not reliable: it said „ok” on a dead drive.
  • Real restart (K5): stop + start, or recreate, works in 2–10 s per app. FileBrowser: 5 s. Today's dashboard restart does nothing when the compose did not change (R-1026). A restart cuts a playing stream; Jellyfin answered again after 22 s.
  • Plex without the race (K6): Plex starts with no code. The code can be given later to the running server. So the box can ask for the code last. But an unclaimed Plex opens everything without a password to a private address. Through the tunnel every request comes from a private address. So an unclaimed Plex must never get a public name (R-1045, P2). Claim test done 2026-10-15: your code, given to the running server: claimed, token written, the open door closed (no token → 401). ADVERTISE_IP was not needed. Whether clients find the server without it could not be measured (the throwaway had no open port). plex-k6 is removed.
  • Old installs (K7): Sonarr and Radarr from before bc54c01 lose their library folder after the update. Nothing is deleted. Repair by the apps' own API, with no file moved: proven on the bench. → R-1047.
  • Hub mails (K8): a pulled drive sends an error mail. When it comes back, no mail is sent. → R-1049.

5. Proposed build plan (for the reviewer, not a spec)

step what where household
1 Restart = stop+start or recreate, with the stack's environment; the log says what changed (R-1026) controller —
2 Media apps get one bind per present drive (R-1023, R-1031); FileBrowser's pattern controller + catalog —
3 Drive returns → restart every container that uses it; find them by shutdown in their mountinfo (R-1038) controller —
4 Restart notice: „restart now” / „later”; check playing streams first controller UI one click
5 Safe removal = pause that drive's torrents → recreate apps without it → unmount; keep it known (R-1044) controller + agent —
6 New drive → wire every app (R-1024 calls, 15 §10); Plex „scan on change” on (R-1037) controller Plex: D9
7 Plex: install unclaimed, no public name, ask the code last, claim on the running server (R-1028, R-1045) controller + catalog the code
8 One-time Sonarr/Radarr path repair for old installs (R-1047) controller —
9 „Drive came back” mail (R-1049) hub —
10 Prowlarr into the live catalog (R-1048) catalog indexers

Order: 1 first (2–5 need it). Then 2, 3, 5 together. Then 6, 7. 8, 9, 10 are independent.

6. Disk detach times (CEST)

time what hub mail
22:54:48 Media B detached 22:55 „disconnected”
22:59:00 Media B re-attached none (R-1049)
23:03:10 Media C added —
23:10:23 Media C safe removal (eject) none
23:12:41 Media C detached none (it was forgotten)
23:13:11 Media C re-attached none
23:20:47 Media C detached (a pull) 23:21 „disconnected”
23:21:22 Media C re-attached none (R-1049)

Also 23:11: two „app does not run” mails (Plex, Jellyfin) — from the restart test after the eject.

7. Claims in the prompt that were wrong

  1. „Your test shows in Plex and Jellyfin may disappear during the scan test.” They did not. Nothing was removed.
  2. Option (a), Cloudflare „Always Use HTTPS” per zone: not possible. No stored key may change zone settings.
  3. K4's example check (a timed stat in a separate process): not reliable. It said „ok” on a dead drive.
  4. K3 assumed the safe removal frees the drive. It does not, while the apps run.
  5. K6 asked for a throwaway Plex on a test subdomain. I did not give it a public name. Reason: an unclaimed Plex is open without a password to every request through the tunnel.

My own predictions that were wrong: I expected Plex and Jellyfin to remove items, and the torrents to re-check. Neither happened.

Commits

  • felhom.eu: 0144be8c, b7807c11, 5aaa3312, and the final commit of this report.
  • felhom-controller: 8bc7ec5 (v0.312.0, image gitea.dooplex.hu/admin/felhom-controller:0.312.0, delivered to all three boxes; MinAgent unchanged).
  • app-catalog-drill: 925f3fd (Media C binds; drill catalog only).

Register

  • Rows before: 154. Rows after: 163. Opened: 9 (R-1041 … R-1049). Closed: 0.
  • Narrowed: R-1022, R-1023, R-1024, R-1026, R-1028, R-1033, R-1037, R-1038.
  • STATUS.md: 58 lines.
  • unproven.py --summary: not walked 35 of 55 — no number moved.

Teardown, three layers

  • Machine (Tester 1): not torn down, on purpose (your word is needed). Left: Media C, the throwaway plex-k6 and its volume plex-k6-config (for the claim test). Both are in R-1022.
  • Host (demo-hp): VM 341 has a new disk scsi4 (nvme-scratch:341/vm-341-disk-5.raw, 50 GB). The bench (LXC 9401) is off, as found.
  • Hub: nothing changed. Read only.
  • The echo container of the https spike was removed (0 left).

Fixed without a row

  • https_only_check.py: a browser-like User-Agent (Cloudflare refused Python's own); the script goes to the box on stdin.

Instruction files

None changed.

System poster

The facts file has the https sentence. The drawing has no such text, so STATUS.md has the line „System poster needs a refresh”.