185 lines
6.5 KiB
Markdown
185 lines
6.5 KiB
Markdown
# Storage Mounts — Homelab
|
||
|
||
Centralised reference for all remote shares mounted across the homelab. Every host with shares exports them via SMB (CIFS), except where NFS is noted.
|
||
|
||
---
|
||
|
||
## Architecture Overview
|
||
|
||
```
|
||
homelab-vm (192.168.0.210)
|
||
/mnt/...
|
||
/
|
||
Atlantis ─── LAN ─── 8× CIFS + 1× NFS
|
||
pi-5 ─── LAN ─── 1× CIFS
|
||
Calypso ─ Tailscale ─ 6× CIFS
|
||
Setillo ─ Tailscale ─ 4× CIFS
|
||
Guava ─ Tailscale ─ 7× CIFS
|
||
```
|
||
|
||
---
|
||
|
||
## Share Inventory
|
||
|
||
### Atlantis (192.168.0.200) — Synology 1823xs+
|
||
|
||
| Share | Mount point | Protocol | Notes |
|
||
|-------|-------------|----------|-------|
|
||
| `archive` | `/mnt/repo_atlantis` | NFS v3 | Git/archive storage |
|
||
| `data` | `/mnt/atlantis_data` | CIFS | Primary data (media/torrents/usenet subdirs) |
|
||
| `docker` | `/mnt/atlantis_docker` | CIFS | Docker volumes/configs |
|
||
| `downloads` | `/mnt/atlantis_downloads` | CIFS | Download staging |
|
||
| `games` | `/mnt/atlantis_games` | CIFS | Game files |
|
||
| `torrents` | `/mnt/atlantis_torrents` | CIFS | Torrent data (885G, separate volume) |
|
||
| `usenet` | `/mnt/atlantis_usenet` | CIFS | Usenet downloads (348G, separate volume) |
|
||
| `website` | `/mnt/atlantis_website` | CIFS | Web content |
|
||
| `documents` | `/mnt/atlantis_documents` | CIFS | Documents |
|
||
|
||
> **Note:** Only `archive` and `data` are NFS-exported by DSM to this host. All other shares use CIFS. The old `atlantis_docker` NFS entry in fstab was replaced with CIFS as the NFS export was not configured in DSM.
|
||
|
||
### Calypso (100.103.48.78) — Synology DS723+, via Tailscale
|
||
|
||
| Share | Mount point | Protocol |
|
||
|-------|-------------|----------|
|
||
| `data` | `/mnt/calypso_data` | CIFS |
|
||
| `docker` | `/mnt/calypso_docker` | CIFS |
|
||
| `docker2` | `/mnt/calypso_docker2` | CIFS |
|
||
| `dropboxsync` | `/mnt/calypso_dropboxsync` | CIFS |
|
||
| `Files` | `/mnt/calypso_files` | CIFS |
|
||
| `netshare` | `/mnt/calypso_netshare` | CIFS |
|
||
|
||
### Setillo (100.125.0.20) — Synology DS223j, via Tailscale
|
||
|
||
| Share | Mount point | Protocol |
|
||
|-------|-------------|----------|
|
||
| `backups` | `/mnt/setillo_backups` | CIFS |
|
||
| `docker` | `/mnt/setillo_docker` | CIFS |
|
||
| `PlexMediaServer` | `/mnt/setillo_plex` | CIFS |
|
||
| `syncthing` | `/mnt/setillo_syncthing` | CIFS |
|
||
|
||
### Guava (100.75.252.64) — TrueNAS SCALE, via Tailscale
|
||
|
||
| Share | Mount point | Notes |
|
||
|-------|-------------|-------|
|
||
| `photos` | `/mnt/guava_photos` | 1.6T |
|
||
| `data` | `/mnt/guava_data` | passionfruit user home data |
|
||
| `guava_turquoise` | `/mnt/guava_turquoise` | 4.5T, 68% used — large archive |
|
||
| `website` | `/mnt/guava_website` | |
|
||
| `jellyfin` | `/mnt/guava_jellyfin` | Jellyfin media |
|
||
| `truenas-exporters` | `/mnt/guava_exporters` | Prometheus exporters config |
|
||
| `iso` | `/mnt/guava_iso` | ISO images |
|
||
|
||
> **TrueNAS password quirk:** TrueNAS SCALE escapes `!` as `\!` when storing SMB passwords internally. If your password ends in `!`, the credentials file must append a backslash: `password="REDACTED_PASSWORD"\!`. Setting the password is done via `sudo python3 -c "import subprocess,json; subprocess.run(['midclt','call','user.update','USER_ID',json.dumps({'password':'PASS'})], capture_output=True, text=True)"` — then restart SMB with `sudo midclt call service.restart cifs`.
|
||
|
||
### pi-5 / rpi5-vish (192.168.0.66) — Raspberry Pi 5
|
||
|
||
| Share | Mount point | Protocol | Notes |
|
||
|-------|-------------|----------|-------|
|
||
| `storagepool` | `/mnt/pi5_storagepool` | CIFS | 457G NVMe btrfs |
|
||
|
||
> pi-5 also mounts `atlantis:/volume1/data` → `/mnt/atlantis_data` via NFS.
|
||
|
||
---
|
||
|
||
## Setup from Scratch
|
||
|
||
### 1. Install dependencies
|
||
|
||
```bash
|
||
sudo apt-get install -y cifs-utils nfs-common
|
||
```
|
||
|
||
### 2. Create credentials files
|
||
|
||
All files go in `/etc/samba/`, owned root, mode 0600.
|
||
|
||
```bash
|
||
# Atlantis & Setillo share the same credentials
|
||
sudo bash -c 'cat > /etc/samba/.atlantis_credentials << EOF
|
||
username=vish
|
||
password=REDACTED_PASSWORD
|
||
EOF
|
||
chmod 600 /etc/samba/.atlantis_credentials'
|
||
|
||
sudo bash -c 'cat > /etc/samba/.calypso_credentials << EOF
|
||
username=Vish
|
||
password=REDACTED_PASSWORD
|
||
EOF
|
||
chmod 600 /etc/samba/.calypso_credentials'
|
||
|
||
sudo bash -c 'cat > /etc/samba/.setillo_credentials << EOF
|
||
username=vish
|
||
password=REDACTED_PASSWORD
|
||
EOF
|
||
chmod 600 /etc/samba/.setillo_credentials'
|
||
|
||
sudo bash -c 'cat > /etc/samba/.pi5_credentials << EOF
|
||
username=vish
|
||
password=REDACTED_PASSWORD
|
||
EOF
|
||
chmod 600 /etc/samba/.pi5_credentials'
|
||
```
|
||
|
||
### 3. Create mount points
|
||
|
||
```bash
|
||
sudo mkdir -p \
|
||
/mnt/repo_atlantis \
|
||
/mnt/atlantis_{data,docker,downloads,games,torrents,usenet,website,documents} \
|
||
/mnt/calypso_{data,docker,docker2,dropboxsync,files,netshare} \
|
||
/mnt/setillo_{backups,docker,plex,syncthing} \
|
||
/mnt/pi5_storagepool
|
||
```
|
||
|
||
### 4. Apply fstab
|
||
|
||
Copy the entries from `hosts/vms/homelab-vm/fstab.mounts` into `/etc/fstab`, then:
|
||
|
||
```bash
|
||
sudo mount -a
|
||
```
|
||
|
||
### 5. Verify
|
||
|
||
```bash
|
||
df -h | grep -E 'atlantis|calypso|setillo|pi5'
|
||
```
|
||
|
||
---
|
||
|
||
## Troubleshooting
|
||
|
||
### Mount fails with "Permission denied" (CIFS)
|
||
- Credentials file has wrong username or password
|
||
- On Synology, the SMB user password is the DSM account password — separate from SSH key auth
|
||
- Test a single mount manually: `sudo mount -t cifs //HOST/SHARE /tmp/test -o credentials=/etc/samba/.CREDS,vers=3.0`
|
||
|
||
### Mount fails with "No route to host" (Calypso/Setillo)
|
||
- These are Tailscale-only — ensure Tailscale is up: `tailscale status`
|
||
- Calypso and Setillo are not reachable over the LAN directly
|
||
|
||
### Guava LAN shares unreachable despite SMB running
|
||
|
||
Calypso advertises `192.168.0.0/24` as a Tailscale subnet route. Any node with `accept_routes: true` will install that route in Tailscale's policy routing table (table 52), causing replies to LAN clients to be sent back via the Tailscale tunnel instead of the LAN — the connection silently times out.
|
||
|
||
**Check for rogue routes:**
|
||
```bash
|
||
ssh guava "ip route show table 52 | grep 192.168"
|
||
```
|
||
|
||
**Fix — remove stale routes immediately:**
|
||
```bash
|
||
ssh guava "sudo ip route del 192.168.0.0/24 dev tailscale0 table 52"
|
||
```
|
||
|
||
**Fix — permanent (survives reboot):**
|
||
Set `accept_routes: false` in the TrueNAS Tailscale app config via `midclt call app.update` or the web UI. See `docs/troubleshooting/guava-smb-incident-2026-03-14.md` for full details.
|
||
|
||
### NFS mount hangs at boot
|
||
- Ensure `_netdev` and `nofail` options are set in fstab
|
||
- NFS requires the network to be up; `_netdev` defers the mount until after networking
|
||
|
||
### atlantis_docker was previously NFS but not mounting
|
||
- DSM's NFS export for `docker` was not configured for this host's IP
|
||
- Switched to CIFS — works without any DSM NFS permission changes
|