In-browser file browser deployed on telep-mainframe to browse the box’s Windows NTFS drive (previews for images, video, PDF, code, markdown, archives). Tailnet-only, same tailscale serve pattern as the top4 picker (:8443) and Frigate (:443).

For Agents

URL: https://telep-mainframe.taild4189d.ts.net:8445 — tailnet only. Container: filestash, bound to 127.0.0.1:8334, config in the filestash_data docker volume. Data: the Windows C: drive mounted read-only on the host at /mnt/win, passed into the container at /mnt/data. First-run setup is NOT finished — admin password + “Local” backend still to be configured in the browser.

The Windows drive

PropertyValue
Physical diskthe 1.8T NVMe — device node varies, see warning below
Windows C: partitionthe ntfs partition on that disk (1.9T, ~886G used) — /dev/nvme0n1p2 as of 2026-07-21
Host mountpoint/mnt/win
Moderead-only
Driverin-kernel ntfs3 (ntfs-3g / FUSE available as fallback)

The device node is NOT stable across reboots

NVMe enumeration flips between boots. This doc originally said /dev/nvme1n1p2; on 2026-07-21 the same Windows partition came up as /dev/nvme0n1p2, and nvme1n1 was the 3.6T LUKS+LVM OS disk instead:

DiskRole
nvme0n1 (1.8T)Windows — nvme0n1p2 = NTFS C:
nvme1n1 (3.6T)OS — p1 /boot/efi, p2 /boot (ext4), p3 crypto_LUKS (LVM)

Always run lsblk -f first and pick the 1.8T ntfs partition. Never hardcode the path. This is also exactly why an fstab entry must use UUID=, not a device node — a hardcoded /dev/nvmeXn1p2 in fstab could mount (or fail on) the wrong disk after a reboot.

Mount procedure (verified 2026-07-21)

lsblk -f                       # find the 1.8T ntfs partition
sudo modprobe ntfs3
sudo mkdir -p /mnt/win
sudo mount -t ntfs3 -o ro /dev/nvme0n1p2 /mnt/win   # ← path per lsblk, not fixed
docker restart filebrowser     # REQUIRED — see gotcha below

Resulting mount options: ro,relatime,uid=0,gid=0,iocharset=utf8.

Read-only is deliberate — the Windows install is live

The Windows install is actively used. Its fast-startup / hibernation state would make a read-write mount corrupt the filesystem, so it is mounted -o ro. Do not mount RW while Windows can hibernate.

Gotcha: the file-browser container must be restarted after the mount

The filebrowser container bind-mounts /mnt/win → /srv (read-only). If the container was started while /mnt/win was still an empty, unmounted directory, it keeps the stale pre-mount view: /srv looks empty inside the container even though the host mount is perfectly fine — which reads like a broken mount and sends you debugging the wrong layer.

Fix: docker restart filebrowser.

Because the mount is not persisted, every reboot needs mount-then-restart, in that order.

Gap: the mount is manual, not in fstab

The modprobe + mount above are run by hand and will not survive a reboot. Fix properly with a systemd mount unit keyed on UUID=, ordered Before=docker.service — that removes the whole restart-the-container class of problem at once. An fstab UUID=... /mnt/win ntfs3 ro 0 0 line is the minimum.

Drive inventory (2026-07-21)

DeviceSizeContents
nvme0n11.8TWindows — p2 NTFS C:
nvme1n13.6TDebian OS — EFI / boot / LUKS+LVM
sda447.1Gessentially unused — one 16M partition, no filesystem
sdb115.5GUDF, label HBCD_PE_x64 — Hiren’s BootCD PE rescue USB stick

Container

docker run -d --name filestash --restart always \
  -p 127.0.0.1:8334:8334 \
  -e APPLICATION_URL=https://telep-mainframe.taild4189d.ts.net:8445/ \
  -v filestash_data:/app/data/state \
  -v /mnt/win:/mnt/data:ro \
  machines/filestash
  • Windows drive appears inside the container at /mnt/data (read-only).
  • Config / state persists in the filestash_data docker volume.
  • Bound to 127.0.0.1 only — nothing on the LAN; tailscale serve is the sole path in.

Exposure

Same pattern as the top4 picker and Frigate — tailscale serve terminates TLS with a real LE cert:

sudo tailscale serve --bg --https=8445 http://127.0.0.1:8334

https://telep-mainframe.taild4189d.ts.net:8445 (tailnet only).

telep-mainframe tailscale serve port map

PortServiceLocal target
:443Frigate UI127.0.0.1:8971
:8443top4 picker127.0.0.1:8090
:8445Filestash127.0.0.1:8334

First-run setup (unfinished)

Interactive, in the browser:

  1. Visit the URL.
  2. Set the admin password at /admin/setup.
  3. Enable the “Local” storage backend pointing at /mnt/data.
  4. Browse.

Left for the user

As of 2026-07-16 the admin password and the Local-backend config were not yet done — the container is up but Filestash still needs its first-run wizard completed.

Optional / not added

  • OnlyOffice container for inline Word / Excel / PowerPoint rendering — Filestash integrates via an ONLYOFFICE URL. Not deployed.

iOS: iCloud Private Relay breaks MagicDNS in Safari

Browsing from iPhone Safari can fail — Private Relay breaks tailnet MagicDNS, so *.ts.net won’t resolve. Known homelab gotcha, see Access.