๐ Chapter 10 โ The Build
The complete configuration in one place. The chapter you reference when you forget how a piece works.
Learning Objectives
- Reference the exact configuration of TK's pool from one place
- Reproduce the configuration on your own hardware
- Understand the order of operations for the initial build
Introduction
This is the chapter to come back to. The previous nine chapters explain why. This one is just what. The dataset tree, the users, the shares, the snapshot policies, the apps, the maintenance schedule. Print it, bookmark it, refer to it whenever you forget "wait, did we put a quota on the PhoneUploads dataset or not?"
If you're building your own NAS, this is the chapter that walks through the actual setup in the right order.
Hardware baseline
For TK's setup, the conversation converged on this hardware profile. Yours may differ; the structure below is what to aim for.
| Component | Spec | Why |
|---|---|---|
| CPU | Modern multi-core (Intel i5/i7 or AMD Ryzen 5/7) | ZFS loves RAM and CPU for ARC + scrubs |
| RAM | 32 GB minimum, 64 GB recommended | ZFS uses RAM for read cache (ARC); 1 GB per TB of storage is a good rule |
| Boot drive | Dedicated SSD (mirror recommended) | TrueNAS lives here; pool lives on HDDs |
| Data drives | 6 ร 12 TB (or similar) NAS-rated | RAIDZ2 gives ~44 TB usable with 2-drive fault tolerance |
| Network | 1 GbE minimum, 10 GbE if budget allows | 1 GbE = 125 MB/s; 10 GbE = 1.25 GB/s |
| Case | Hot-swap bays, good cooling | Drives run 24/7; airflow matters |
| UPS | At least 1000 VA | Survives brownouts; protects the pool from dirty shutdowns |
The dataset tree
This is the entire filesystem layout for TK's NAS. The conversation went through several revisions; this is the v2.2 final:
Dataset properties
The compression, quota, and encryption settings per dataset:
| Dataset | Compression | Quota | Encryption | Notes |
|---|---|---|---|---|
| Family | lz4 | โ | โ | |
| Photos | lz4 | โ | โ | Already-compressed, but lz4 doesn't hurt |
| Videos | lz4 | โ | โ | Same |
| Documents | lz4 | โ | โ | Compresses well |
| Private | lz4 | โ | โ | Top-level for TK+Mimi |
| Private/Tom | lz4 | 500 GB | Yes | Per-user, encrypted |
| Private/Mimi | lz4 | 500 GB | Yes | Per-user, encrypted |
| Private/Lai | lz4 | 500 GB | Yes | Per-user, encrypted |
| PhoneUploads | lz4 | 200 GB | โ | Staging area, low retention |
| Apps | lz4 | โ | โ | App data, automatic |
| Media | lz4 | โ | โ | Video production |
| Media/Active | lz4 | 2 TB | โ | Fast SSD-backed if possible |
| Media/Archive | lz4 | โ | โ | Long-term, no limit |
| Lab | lz4 | โ | โ | TK only |
Permissions matrix
The full owner / group / mode for every dataset (from Chapter 07):
| Dataset | Owner | Group | Mode | ABSE |
|---|---|---|---|---|
| Family | tk | Family | 770 | โ |
| Photos | tk | Family | 770 | โ |
| Videos | tk | Family | 770 | โ |
| Documents | tk | Family | 770 | โ |
| Private | tk | tk | 770 | Yes |
| Private/Tom | Tom | Tom | 700 | โ |
| Private/Mimi | Mimi | Mimi | 700 | โ |
| Private/Lai | Lai | Lai | 700 | โ |
| PhoneUploads | tk | Family | 770 | โ |
| Apps | tk | Family | 770 | โ |
| Media | tk | Family | 770 | โ |
| Media/Active | tk | Family | 770 | โ |
| Media/Archive | tk | Family | 770 | โ |
| Lab | tk | tk | 700 | Yes |
Users and groups
The complete user list (from Chapter 06):
| Username | Role | Group | Admin | Shell |
|---|---|---|---|---|
| tk | Household admin | Family | Yes | /bin/bash |
| Mimi | Family member | Family | No | nologin |
| Lai | Family member | Family | No | nologin |
| root | Built-in superuser | root | โ | (reserved, don't use) |
When future family members or friends need access, add them to the Family group (for shared datasets) and create a Private/<name> subdataset for their personal data.
SMB shares
The complete share list (from Chapter 05). One share per top-level dataset; private subdatasets are not shared at the top level (they're accessed via the Private parent share or individually if needed).
| Share name | Path | ABSE | Allowed users |
|---|---|---|---|
| Family | /mnt/tank/Family | โ | Family group |
| Photos | /mnt/tank/Photos | โ | Family group |
| Videos | /mnt/tank/Videos | โ | Family group |
| Documents | /mnt/tank/Documents | โ | Family group |
| Private | /mnt/tank/Private | Yes | tk, Mimi, Lai (per their subdataset perms) |
| PhoneUploads | /mnt/tank/PhoneUploads | โ | Family group (drop files), tk (manage) |
| Apps | /mnt/tank/Apps | โ | tk (apps have their own accounts) |
| Media | /mnt/tank/Media | โ | Family group (read), tk (write) |
| Lab | /mnt/tank/Lab | Yes | tk only |
Snapshot policies
The full schedule (from Chapter 09):
| Dataset | Hourly | Daily | Weekly | Monthly | Yearly |
|---|---|---|---|---|---|
| Family / Photos / Videos / Documents | 48h | 30d | 12w | 12mo | 5y |
| PhoneUploads | 24h | โ | โ | โ | โ |
| Private/* | โ | 7d | 4w | โ | โ |
| Apps/* | on app update (manual or auto) | ||||
| Media/Active | โ | 30d | โ | โ | โ |
| Media/Archive | โ | โ | โ | โ | after each major edit |
| Lab | โ | 7d | โ | โ | โ |
Maintenance schedule
The automation that runs on TK's pool (from Chapter 09):
| Task | Frequency | When | Where to monitor |
|---|---|---|---|
| Pool scrub | Monthly | 2nd Sunday, 2 AM | Storage โ Snapshots; email alerts |
| SMART short test | Weekly | Saturday, 4 AM | Data Protection โ SMART Tests |
| SMART long test | Monthly | 1st Sunday, 2 AM | Data Protection โ SMART Tests |
| App updates | Monthly | When you choose | Apps โ Discover โ Update |
| TrueNAS updates | Quarterly | When you choose | System โ Update |
| Backup verification | Monthly | Same day as scrub | See Volume 6 |
Apps (the install order)
The order in which to install apps (from Chapter 08):
- Tailscale โ for remote access (install first; you need it for everything else)
- Immich โ for the family photo library (highest-value data)
- Jellyfin โ for media streaming (the "wow" app)
- Vaultwarden โ for password management (when the family is ready)
- Paperless-ngx โ for document scanning (when the family trusts the system)
Network access
- Local access: SMB at
\\<nas-name>\<share-name>orsmb://<nas-name>/<share-name>. No VPN needed. - Remote access: Tailscale. From any device signed into the same Tailscale account, use the Tailscale IP (e.g.
100.x.y.z) exactly like a local IP. - No public SMB. Port 445 is closed to the internet. Period.
- Apps accessed remotely go through the same Tailscale network. The Immich web UI is at
http://100.x.y.z:3001, for example.
The order of operations for the initial build
Don't try to do everything at once. This is the recommended order. Take a break between major steps.
Day 1: Hardware and base install
- Assemble the hardware. Drives in the case, motherboard in the case, cables connected.
- Connect to a monitor and keyboard. Boot from the TrueNAS installer USB.
- Install TrueNAS to the boot SSD (or mirror).
- Reboot. The system comes up with a web UI on a known IP (DHCP) or with a console prompt for static IP setup.
- From a laptop, browse to the TrueNAS web UI. Complete the initial setup wizard.
Day 2: Pool and datasets
- Storage โ Create Pool. Name it
tank. Choose RAIDZ2. Select all 6 drives. Confirm. Wait for the resilver to complete (15-30 minutes for an empty pool). - Storage โ Create Dataset. Create each dataset in the tree above. Set the compression, quota, and encryption per the table.
- Storage โ Create Dataset (Child) for Private/<name> for each family member.
- Verify the tree matches the diagram above.
Day 3: Users and groups
- Credentials โ Local Groups โ Add. Create the
Familygroup. - Credentials โ Local Users โ Add. Create
tkwith admin privileges, Samba auth, /bin/bash shell. - Create Mimi, Lai. No admin, Samba auth, nologin shell.
- Add each user to the Family group.
- From a laptop, try
\\<nas-name>\in File Explorer. Verify you can log in as tk and see the empty top-level shares.
Day 4: Shares and permissions
- Shares โ SMB โ Add for each dataset in the share table above.
- Set the dataset permissions per the matrix above (owner, group, mode, ABSE).
- Test: log in as Mimi from a different laptop. Verify she can see Family/Photos/Videos/Documents/PhoneUploads/Apps/Media but NOT Private or Lab.
Day 5: Snapshot and scrub schedules
- Data Protection โ Periodic Snapshot Tasks โ Add for each schedule in the snapshot table.
- Data Protection โ Scrub Tasks โ Add. Pool = tank. Schedule = monthly.
- Data Protection โ S.M.A.R.T. Tests โ Add. All data drives. Schedule = weekly short, monthly long.
- Set up email alerts: System โ Email. Add your address. Enable alerts for SMART failures, scrub errors, and snapshot failures.
Day 6+: Tailscale and the first app
- Install Tailscale from the Apps catalog. Sign in. Install Tailscale on your laptop and phone.
- Verify: from your phone on cellular, you can reach the NAS at its Tailscale IP.
- Install Immich. Set up family users. Install the mobile app. Enable auto-upload.
- Wait a week. Make sure Immich is working. Then move to the next app.
Week 2+: Jellyfin
- Install Jellyfin. Set up the Media library. Stream something.
- Wait. Make sure Jellyfin is working.
Week 3+: Vaultwarden and Paperless-ngx
- Install Vaultwarden. Import passwords. Install browser extension.
- Install Paperless-ngx. Start scanning.
That's a 3-week build. The discipline is what makes it feel stable. Don't skip the wait periods.
Verification checklist (before you trust it)
Before you put irreplaceable data on this NAS, run through this checklist:
- โฌ All 6 drives are showing in Storage โ Disks with healthy SMART status
- โฌ The pool shows as "ONLINE" with no errors
- โฌ The dataset tree matches the diagram above
- โฌ All 4 family users can log in via SMB
- โฌ Each user can see only the shares they're supposed to see
- โฌ A test file dropped into Photos is visible to all family members
- โฌ A test file in Private/Tom is visible only to Tom (and tk, the admin)
- โฌ A snapshot is being created (check Storage โ Snapshots tomorrow)
- โฌ A scrub is scheduled (Data Protection โ Scrub Tasks)
- โฌ SMART tests are scheduled
- โฌ Email alerts are working (send a test)
- โฌ Tailscale is installed and you can reach the NAS from your phone on cellular
- โฌ SMB is NOT exposed to the internet (no port forwarding for 445 on the router)
Engineering Note
This is the build you'll live with for years. Once the dataset tree is set, once the permissions are configured, once the apps are deployed, you'll stop thinking about it. The whole point of the long planning conversation in the original chat was to get to this configuration without regret.
Resist the urge to "just add one more app" right away. Add apps only when there's a real need driving them. The discipline is what turns a NAS into a reliable system instead of a science project.
Summary
One pool, one vdev, RAIDZ2, 6 ร 12TB, ~44TB usable. Family group + per-user private subdatasets. One SMB share per top-level dataset. LZ4 compression everywhere, encryption on private subdatasets. Hourly/daily/weekly/monthly/yearly snapshot policies per dataset. Monthly scrubs, weekly SMART tests. Five apps in install order: Tailscale, Immich, Jellyfin, Vaultwarden, Paperless-ngx. Tailscale for remote access, no public SMB. Email alerts on SMART failures and scrub errors.
Checklist
- โฌ Print this chapter. It's the reference you'll come back to.
- โฌ Save the configuration tables somewhere safe (a separate file in the Lab dataset, a printout in the server room)
- โฌ When you make changes later, update this chapter and bump the version number
Looking Ahead
Volume 1 is complete. Volume 2 โ Family NAS โ goes deeper into the apps and the family-facing experience: how to make Immich work for everyone, how to share albums, how to handle the family's media library, and how to add a friend or extended family member to the access list. The next volume turns the foundation into a household service.