NAS base setup¶
1. DSM¶
- Install the latest DSM available for the model. Create the storage pool: SHR, 3 disks → Btrfs volume
/volume1. - Control Panel → Network: set a static IP or a DHCP reservation (
<NAS_IP>) and the hostname. - Control Panel → Terminal & SNMP: enable SSH on a non-default port.
- Control Panel → Regional Options: set the time zone and NTP.
- Control Panel → Notification → Email: set up DSM's own alerts for drive health and RAID.
- Package Center: install Container Manager (called Docker on DSM 7.1), Snapshot Replication (this pulls in Replication Service automatically; installing it from the CLI first needs
ReplicationService) and Text Editor. - Turn off the admin account and use a named admin user. Enable 2FA for DSM logins.
2. Shared folders¶
| Share | Purpose | Snapshots |
|---|---|---|
data |
Everything torrents + media: one share, so hardlinks work | daily, short retention |
docker |
One folder per container's /config |
hourly |
Recycle bin off on data (the *arrs and qBittorrent delete a lot of files).
3. The TRaSH /data layout (hardlinks + atomic moves)¶
Everything that moves files sees the same /data mount. A completed download then becomes a library file through a
hardlink: instant, with no extra space used.
/volume1/data
├── torrents
│ ├── incomplete
│ ├── movies ← qBittorrent category "movies"
│ ├── tv ← qBittorrent category "tv"
│ └── watch
├── usenet (optional, for SABnzbd)
│ ├── incomplete
│ └── complete/{movies,tv}
└── media
├── movies ← Radarr root folder /data/media/movies
└── tv ← Sonarr root folder /data/media/tv
sudo mkdir -p /volume1/data/{torrents/{incomplete,movies,tv,watch},usenet/{incomplete,complete/{movies,tv}},media/{movies,tv}}
sudo chown -R <media_user>:users /volume1/data
sudo chmod -R a=,a+rX,u+w,g+w /volume1/data # 775 dirs / 664 files
| Container | Mount |
|---|---|
| qBittorrent | /volume1/data/torrents:/data/torrents |
| Sonarr, Radarr | /volume1/data:/data |
| Plex, Bazarr | /volume1/data/media:/data/media |
No remote path mappings
Because qBittorrent and the *arrs agree on /data/torrents/..., no remote path mappings are needed. In Sonarr and Radarr turn on
Settings → Media Management → Use Hardlinks instead of Copy. Check it with ls -li (the inode numbers match) or stat (Links: 2).
Migrating an old layout
On Btrfs, cp -a --reflink=always copies between shares almost for free (shared extents). That's how an older
/volume1/media + /volume1/downloads layout was moved into data. Keep the old copies for about a week, then delete them.
4. Users and PUID/PGID¶
Create DSM users with no admin rights and no app permissions except the shares they need:
| User | Used by | Shares (R/W) |
|---|---|---|
<media_user> |
qBittorrent, Sonarr, Radarr, Prowlarr, Bazarr, Tautulli | data, docker |
<plex_user> |
Plex | data (read is enough; R/W lets Plex delete) , docker |
Get the IDs over SSH with id <media_user>. The group users = 100. Put these in every stack as
PUID/PGID, with UMASK=002.
5. Docker / Container Manager¶
- Docker comes from the package. The CLI is
/usr/local/bin/docker, and the bundleddocker-composeis v1 (old). Don't rundocker-composein a stack's folder for stacks managed by Portainer. - If you enable DSM's firewall, make sure it allows the Docker bridge ranges, or containers lose connectivity.
6. Portainer¶
Portainer manages every media stack except itself. See Portainer.
Stacks keep secrets in stack environment variables. Compose files in this guide reference them as ${VAR}. See .env.example at the repo root.