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 to127.0.0.1:8334, config in thefilestash_datadocker 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
| Property | Value |
|---|---|
| Physical disk | the 1.8T NVMe — device node varies, see warning below |
| Windows C: partition | the ntfs partition on that disk (1.9T, ~886G used) — /dev/nvme0n1p2 as of 2026-07-21 |
| Host mountpoint | /mnt/win |
| Mode | read-only |
| Driver | in-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, andnvme1n1was the 3.6T LUKS+LVM OS disk instead:
Disk Role nvme0n1(1.8T)Windows — nvme0n1p2= NTFS C:nvme1n1(3.6T)OS — p1/boot/efi,p2/boot (ext4),p3crypto_LUKS (LVM)Always run
lsblk -ffirst and pick the 1.8Tntfspartition. Never hardcode the path. This is also exactly why an fstab entry must useUUID=, not a device node — a hardcoded/dev/nvmeXn1p2in 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 belowResulting 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
filebrowsercontainer bind-mounts/mnt/win → /srv(read-only). If the container was started while/mnt/winwas still an empty, unmounted directory, it keeps the stale pre-mount view:/srvlooks 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+mountabove are run by hand and will not survive a reboot. Fix properly with a systemd mount unit keyed onUUID=, orderedBefore=docker.service— that removes the whole restart-the-container class of problem at once. An fstabUUID=... /mnt/win ntfs3 ro 0 0line is the minimum.
Drive inventory (2026-07-21)
| Device | Size | Contents |
|---|---|---|
nvme0n1 | 1.8T | Windows — p2 NTFS C: |
nvme1n1 | 3.6T | Debian OS — EFI / boot / LUKS+LVM |
sda | 447.1G | essentially unused — one 16M partition, no filesystem |
sdb | 115.5G | UDF, 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_datadocker volume. - Bound to
127.0.0.1only — nothing on the LAN;tailscale serveis 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
| Port | Service | Local target |
|---|---|---|
:443 | Frigate UI | 127.0.0.1:8971 |
:8443 | top4 picker | 127.0.0.1:8090 |
:8445 | Filestash | 127.0.0.1:8334 |
First-run setup (unfinished)
Interactive, in the browser:
- Visit the URL.
- Set the admin password at
/admin/setup. - Enable the “Local” storage backend pointing at
/mnt/data. - 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
ONLYOFFICEURL. Not deployed.
iOS: iCloud Private Relay breaks MagicDNS in Safari
Browsing from iPhone Safari can fail — Private Relay breaks tailnet MagicDNS, so
*.ts.netwon’t resolve. Known homelab gotcha, see Access.
Related
- telep-mainframe — the host; shares the
tailscale serveTLS pattern - homelab
- LOG
- TOPICS