Sync Mobile Photos to TrueNAS — 2025 Practical Guide (SCALE & CORE)

Sync Mobile Photos to TrueNAS — 2025 Practical Guide (SCALE & CORE)

Parable of the Lanterns: A traveler lit one lantern and walked in peace; when the wind rose, the road vanished. With a second lantern, the path dimmed but endured. With a third kept at a friend's house, the storm passed and the journey continued. Backups are lanterns for memory—keep more than one and keep one away.

Introduction


This guide is a clean, reproducible playbook for Syncthing, Nextcloud, Resilio Sync, and SMB/WebDAV to back up mobile photos to TrueNAS. It includes TrueNAS SCALE (Docker/containers) and TrueNAS CORE (jails) steps, plus Android/iOS notes.


Why not just use cloud storage?

It is great to lean on Google Photos, Amazon Photos, or the latest “unlimited” deals—until caps change, prices rise, or the library quietly outgrows the plan. If paying £50–£100/yr (even £10–£30) no longer makes sense, that same spend today can buy a 1 TB NVMe. With TrueNAS, the photos dataset doesn’t have to live inside the chassis: a USB 3.2 NVMe enclosure works well, and ZFS snapshots + replication can mirror the internal dataset to that external drive so there’s always an offline copy that can be unplugged and kept safe.

Who this helps

  • Anyone running TrueNAS SCALE (Linux, Kubernetes/Docker) or TrueNAS CORE (FreeBSD, jails) who wants automatic or manual photo backups from Android or iOS.
  • Preference for open-source, local-first, and ZFS-friendly workflows.

Quick chooser

Goal Best fit
Real‑time, battery‑friendly, LAN‑first sync Syncthing
Full cloud experience (sharing, galleries, remote) Nextcloud
Simple peer‑to‑peer with polished mobile UX Resilio Sync (freemium)
Manual uploads and edits, no background daemon SMB/WebDAV

Pre‑flight: ZFS dataset & permissions (both SCALE & CORE)

Create a dedicated dataset for photos and an appdata dataset for configs. Adjust pool/dataset names as needed.

# On the TrueNAS host shell (SCALE or CORE)
# Create datasets (replace POOL with your pool name)
zfs create -o compression=lz4 POOL/media
zfs create -o compression=lz4 POOL/media/photos
zfs create -o compression=lz4 POOL/appdata

# Optional: snapshots for safety (manual example)
zfs snapshot POOL/media/photos@bootstrap
Note on permissions/ACLs: For containers/jails, map the photos dataset read/write into the service with a consistent UID/GID (e.g., 1000:1000) or a service account. On SCALE, LinuxServer.io containers support PUID/PGID. On CORE jails, use a jail user that owns the mountpoint.

A) Syncthing (recommended for most)

Why Syncthing

  • Peer‑to‑peer, no central server
  • Fast LAN transfers, end‑to‑end encrypted
  • “Send Only” folder on the phone prevents accidental deletions from propagating back

A1) TrueNAS SCALE — Docker Compose

Create a folder for compose files, e.g. /mnt/POOL/appdata/compose/syncthing/compose.yaml.

services:
  syncthing:
    image: lscr.io/linuxserver/syncthing:latest
    container_name: syncthing
    restart: unless-stopped
    environment:
      - PUID=1000           # set to your desired user id
      - PGID=1000           # set to your desired group id
      - TZ=Europe/London
    ports:
      - 8384:8384           # Web UI
      - 22000:22000/tcp     # Sync TCP
      - 22000:22000/udp     # Sync QUIC/UDP
      - 21027:21027/udp     # Local discovery
    volumes:
      - /mnt/POOL/appdata/syncthing:/config
      - /mnt/POOL/media/photos:/data/Photos

Bring it up:

cd /mnt/POOL/appdata/compose/syncthing
docker compose up -d

Open the web UI at http://truenas:8384 (or the NAS IP) and set a GUI password.

Add the Photos folder in Syncthing UI:

  • Folder Path: /data/Photos
  • Folder Type (on phone): Send Only (prevents NAS → phone deletes)
  • Versioning on NAS: Staggered File Versioning can be enabled for safety.

A2) TrueNAS CORE — Jail

# Create jail with VNET and IP (adjust values)
iocage create -n syncthing \
  ip4_addr="vnet0|192.168.1.50/24" \
  defaultrouter=192.168.1.1 vnet=on boot=on bpf=yes \
  allow_mlock=1 allow_raw_sockets=1

# Install packages
iocage exec syncthing pkg update
iocage exec syncthing pkg install -y syncthing ca_root_nss

# Create service user (optional but clean)
iocage exec syncthing pw useradd syncthing -m -s /usr/sbin/nologin -c "Syncthing"

# Mount ZFS dataset into the jail (read/write)
iocage fstab -a syncthing /mnt/POOL/media/photos /photos nullfs rw 0 0

# Enable & configure the service
iocage exec syncthing sysrc syncthing_enable=YES
# GUI listen on all, store state under /var/db/syncthing
iocage exec syncthing sysrc syncthing_args='-home=/var/db/syncthing -gui-address=0.0.0.0:8384'

# Start
iocage exec syncthing service syncthing start

Browse to http://192.168.1.50:8384 to finish setup. Add folder /photos in the UI; device‑pair the phone.

A3) Android & iOS

  • Android: Install Syncthing app (F‑Droid or Play). Add Camera folder as Send Only. Share device ID with NAS UI; accept on NAS.
  • iOS: Use Möbius Sync (Syncthing for iOS). Add the Recents/Camera Roll as a shared folder. Pair with NAS and choose Send Only on iPhone/iPad.
Tip: On mobile, exclude temporary edits or exported media subfolders if storage is tight.

B) Nextcloud (self‑hosted cloud + auto‑upload)

Why Nextcloud

  • Familiar cloud drive UX, sharing/links
  • Mobile apps support automatic camera uploads
  • Web galleries and rich ecosystem (onlyoffice/collabora, etc.)

B1) TrueNAS SCALE — Docker Compose (simple stack)

Create /mnt/POOL/appdata/compose/nextcloud/compose.yaml:

services:
  db:
    image: mariadb:11
    container_name: nc-db
    restart: unless-stopped
    environment:
      - MYSQL_ROOT_PASSWORD=supersecretroot
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=supersecret
    volumes:
      - /mnt/POOL/appdata/nextcloud/db:/var/lib/mysql

  nextcloud:
    image: nextcloud:apache
    container_name: nextcloud
    restart: unless-stopped
    depends_on:
      - db
    environment:
      - MYSQL_HOST=db
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=supersecret
    ports:
      - 8080:80
    volumes:
      - /mnt/POOL/appdata/nextcloud/html:/var/www/html
      - /mnt/POOL/media/photos:/photos   # optional: mount photos dataset for external storage

Bring it up:

cd /mnt/POOL/appdata/compose/nextcloud
docker compose up -d

Finish the wizard at http://truenas:8080. After first login, optionally map the ZFS dataset as external storage:

  1. Apps → enable External storage support.
  2. Settings → External storages → Add Local → Folder name Photos → Configuration path /photos → Save (green dot appears).

B2) TrueNAS CORE — Plugin or Jail

  • Use the Nextcloud plugin (UI) for quickest path, or
  • Create a jail and deploy nextcloud-php + database manually (advanced). The plugin is preferred for repeatability.

B3) Android & iOS

  • Install official Nextcloud app.
  • Enable Auto Upload → choose Camera (and Videos if desired). Set Wi‑Fi‑only if needed.
Optional: Put Nextcloud behind a reverse proxy with TLS (e.g., Caddy or Traefik) and a real DNS name for smooth mobile access off‑LAN.

C) Resilio Sync (freemium, polished mobile UX)

Why Resilio Sync

  • Fast P2P, selective sync, straightforward mobile clients
  • Proprietary; some features gated behind paid plans

C1) TrueNAS SCALE — Docker Compose

Create /mnt/POOL/appdata/compose/resilio/compose.yaml:

services:
  resilio:
    image: lscr.io/linuxserver/resiliosync:latest
    container_name: resilio
    restart: unless-stopped
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/London
    ports:
      - 8888:8888     # Web UI
      - 55555:55555   # Listening/sync port
    volumes:
      - /mnt/POOL/appdata/resilio:/config
      - /mnt/POOL/media/photos:/sync/Photos

Run it:

cd /mnt/POOL/appdata/compose/resilio
docker compose up -d

Open UI at http://truenas:8888 and configure the Photos folder.

C2) TrueNAS CORE — Service package

# Inside a new jail named 'resilio' (create similarly to the Syncthing jail)
iocage exec resilio pkg update
iocage exec resilio pkg install -y rslsync ca_root_nss

# Mount your dataset inside the jail
iocage fstab -a resilio /mnt/POOL/media/photos /photos nullfs rw 0 0

# Enable service and start
iocage exec resilio sysrc rslsync_enable=YES
# Optional: custom config path can be set via rslsync_config in rc.conf
iocage exec resilio service rslsync start

Mobile: install Resilio Sync (Android/iOS), pair with the NAS folder.


D) Manual: SMB/WebDAV

Why manual

  • Minimal moving parts
  • Good for one‑off bulk copies or curated uploads

D1) TrueNAS — SMB share (UI‑driven)

  1. Sharing → Windows (SMB) Shares → Add
  2. Path: /mnt/POOL/media/photos, Name: photos
  3. Set purpose: Multi‑user time machine / default (or as needed)
  4. Save → Enable Service if prompted

Android: Use a file manager (e.g., Solid Explorer) → SMB → add server → upload.

iOS: Files app → Connect to Serversmb://nas.local/photos → upload.

D2) TrueNAS — WebDAV (UI‑driven)

  1. Sharing → WebDAV → Add
  2. Path: /mnt/POOL/media/photos → Read/Write
  3. Turn WebDAV Service on (consider TLS for off‑LAN).

Android/iOS: Use a WebDAV‑capable app or mount via Files (iOS supports WebDAV via some third‑party clients).


  • WireGuard/Tailscale to reach the NAS privately from outside.
  • Restrict Syncthing/Resilio web UIs to LAN only; add admin passwords.
  • Use ZFS snapshots and, if possible, replication to another pool or backup target.

Manual snapshot/replication examples:

# Ad‑hoc snapshot before changes
zfs snapshot POOL/media/photos@pre-change

# One‑shot local clone (for recovery testing)
zfs clone POOL/media/photos@pre-change POOL/media/photos_clone

# Push to another pool or backup host (example: local target)
zfs send -v POOL/media/photos@pre-change | zfs recv BACKUPPOOL/media/photos
In the TrueNAS UI, also create Periodic Snapshot Tasks (daily/weekly) and a Replication Task to another pool or system.

Battery & data plan notes

  • Prefer LAN‑only syncing by default; allow cellular only if required.
  • On mobile, enable charging‑only upload if background power use is a concern.

Troubleshooting quick wins

  • Permissions: if containers/jails can’t write to the dataset, align PUID/PGID (SCALE) or file ownership (CORE jail user). Test with a small file creation.
  • Discovery: if devices don’t see each other, open the listed ports on any upstream firewall and ensure local discovery UDP is not blocked.
  • Disk space: enable ZFS compression (lz4) and prune failed edits/exports. Consider a separate dataset for “raw originals”.

Wrap‑up

Pick one path and complete it end‑to‑end. For most homes and studios, Syncthing hits the sweet spot of speed, privacy, and simplicity. Nextcloud suits those wanting sharing, links, and a classic cloud feel. Resilio is a friendly polished P2P. SMB/WebDAV remains the leanest manual option.

If this guide helped, subscribe below to receive new practical walk‑throughs and build notes — no noise, just working patterns.