Deploy Syncthing with Docker: Compose, Ports, and Volume Mapping Pitfalls

A practical guide to deploying Syncthing with Docker: start the container with Docker Compose or docker run, map configuration and sync directories correctly, and handle ports, firewalls, PUID/PGID permissions, and Web UI security.

Syncthing Series

Deploying Syncthing in Docker is a good fit for a NAS, a home server, or a VPS. It can act as an always-on sync node for photos, documents, Markdown notes, or download folders.

The important part of a Docker-based Syncthing setup is not merely whether the container starts. The real questions are:

  • whether the configuration directory is persistent;
  • whether the data folders you want to sync are mapped into the container;
  • whether ports and permissions are prepared in advance.

If these details are not handled well, a container update may wipe your configuration, the path you enter in the Web UI may not point to the real host folder, or sync tasks may fail with Permission denied.

Directory Planning

Start by creating a dedicated directory on the server or NAS, for example:

1
2
mkdir -p ~/syncthing
cd ~/syncthing

Put docker-compose.yml in this directory, and keep Syncthing’s configuration in a subdirectory:

1
2
3
syncthing/
├── docker-compose.yml
└── config/

The actual sync data can live in existing host paths, for example:

1
2
/volume1/downloads
/volume1/photos

Keep the configuration directory separate from the data directories. config stores Syncthing’s own configuration, keys, and index database. Folders such as downloads and photos are the actual data you want to sync.

Option 1: Docker Compose

Docker Compose is the recommended approach because updates, restarts, and migrations are easier to understand later.

Create ~/syncthing/docker-compose.yml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
version: "3"

services:
  syncthing:
    image: syncthing/syncthing:latest
    container_name: syncthing
    hostname: my-nas-syncthing
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Shanghai
    volumes:
      - ./config:/var/syncthing/config
      - /volume1/downloads:/var/syncthing/downloads
      - /volume1/photos:/var/syncthing/photos
    ports:
      - 8384:8384
      - 22000:22000/tcp
      - 22000:22000/udp
      - 21027:21027/udp
    restart: unless-stopped

Start it:

1
docker compose up -d

Check the status:

1
2
docker compose ps
docker logs -f syncthing

Open the Web UI:

1
http://server-ip:8384

After the first login, set a GUI username and password first.

Option 2: docker run

For quick testing, you can also start Syncthing directly with docker run:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
docker run -d \
  --name syncthing \
  --hostname my-nas-syncthing \
  -e PUID=1000 \
  -e PGID=1000 \
  -e TZ=Asia/Shanghai \
  -p 8384:8384 \
  -p 22000:22000/tcp \
  -p 22000:22000/udp \
  -p 21027:21027/udp \
  -v /path/to/config:/var/syncthing/config \
  -v /path/to/data1:/var/syncthing/data1 \
  --restart unless-stopped \
  syncthing/syncthing:latest

Replace /path/to/config and /path/to/data1 with real host paths.

For example:

1
2
-v /volume1/docker/syncthing/config:/var/syncthing/config
-v /volume1/photos:/var/syncthing/photos

For long-term use, convert this into a Compose file so you do not need to rebuild the full command every time the container is recreated.

Container Paths and Host Paths

Docker beginners often get confused by paths.

For example, this volume mapping:

1
2
volumes:
  - /volume1/photos:/var/syncthing/photos

The left side, /volume1/photos, is the host path. The right side, /var/syncthing/photos, is the path inside the container.

When adding a sync folder in the Syncthing Web UI, the folder path must be the container path:

1
/var/syncthing/photos

That way Syncthing is actually operating on this host directory:

1
/volume1/photos

If you enter /volume1/photos in the Web UI, that path usually does not exist inside the container. Syncthing may report an error, or it may create a new directory inside the container filesystem that you did not intend to use.

Persist the Configuration Directory

This line is critical:

1
- ./config:/var/syncthing/config

Syncthing stores its configuration files, device keys, and index database in the configuration directory. If this directory is not mounted to the host, deleting or recreating the container may change the device ID and invalidate existing device pairings.

Use a stable host path such as:

1
/volume1/docker/syncthing/config

Do not put the configuration directory in a temporary location, and do not mix it with the actual sync data directories.

Ports and Firewalls

Common ports are:

1
2
3
4
8384/TCP   Web UI administration
22000/TCP Device sync traffic
22000/UDP QUIC sync traffic
21027/UDP Local discovery

If Syncthing runs on a home NAS, usually check:

  • whether the NAS firewall allows these ports;
  • whether Docker bridge port mapping is correct;
  • whether the router isolates Wi-Fi from wired devices;
  • whether the phone and computer are on the same subnet.

If Syncthing runs on a cloud server, also check the cloud provider’s security group. In particular, if 22000/TCP and 22000/UDP are not allowed, other devices may only connect through a relay, and the speed will be much slower.

8384 is the administration port. Do not expose it directly to the public internet. If remote administration is necessary, at least set a strong password, and preferably combine it with a reverse proxy, HTTPS, access control, or a VPN.

Permission Issues: PUID and PGID

If Syncthing starts and the Web UI is accessible, but a sync folder reports:

1
Permission denied

the container process usually does not have read/write permission on the host directory.

Check the UID and GID of the current user on the host:

1
id

The output may look like this:

1
uid=1000(user) gid=1000(user) groups=1000(user)

Then set the corresponding values in Compose:

1
2
3
environment:
  - PUID=1000
  - PGID=1000

Also confirm that the host directory itself allows this user to read and write:

1
ls -ld /volume1/photos

If necessary, adjust the owner or permissions:

1
sudo chown -R 1000:1000 /volume1/photos

On a NAS, do not blindly run recursive permission changes on an entire shared directory, especially if it is shared by multiple users. A safer approach is to prepare a dedicated sync directory for Syncthing, or grant the corresponding user access from the NAS permission management interface.

First-Time Web UI Security

After the container starts, visit:

1
http://server-ip:8384

On the first visit, Syncthing usually prompts you to set a GUI username and password. Do not skip this step.

Recommended practice:

  • set a GUI username and strong password immediately;
  • do not expose 8384 to the public internet;
  • use a VPN, SSH tunnel, or controlled reverse proxy for remote access;
  • if using a reverse proxy, proxy only the Web UI and do not accidentally expose unnecessary ports.

If someone else controls the administration interface, they may be able to add devices, modify shared folders, and change sync relationships. Syncthing encrypts data in transit, but the administration entry point still needs protection.

Add Sync Folders in the Web UI

Take a photo directory as an example. The Compose file already mounts:

1
- /volume1/photos:/var/syncthing/photos

When adding the folder in the Web UI:

  • Folder Label: you can use Photos;
  • Folder ID: use a stable English ID such as photos;
  • Folder Path: enter /var/syncthing/photos;
  • Sharing: choose the devices that should receive this folder;
  • Folder Type: choose Send & Receive, Send Only, or Receive Only based on the data flow.

If this Docker node is the central NAS node, common choices are:

  • regular documents: Send & Receive;
  • phone photo collection: Receive Only on the NAS;
  • outbound distribution folder: Send Only on the NAS.

Choose based on the intended direction of the data. Do not set every folder to bidirectional sync without thinking.

Update the Container

With Compose, updates are usually:

1
2
docker compose pull
docker compose up -d

As long as the configuration directory and data directories are mounted correctly, updating the container will not lose the device ID, pairings, or sync folder configuration.

Before updating, you can back up the configuration directory:

1
tar -czf syncthing-config-backup.tar.gz ./config

The configuration directory contains device private keys. Do not upload the backup casually to a public location.

Common Issues

Web UI Does Not Open

First check whether the container is running:

1
2
docker ps
docker logs syncthing

Then check port mappings:

1
docker port syncthing

If the container is healthy but the page still does not open, check the host firewall, NAS firewall, or cloud security group.

Folder Does Not Exist After Adding It

Check whether the path entered in the Web UI is the container path.

For example, if the host path is:

1
/volume1/downloads

and the container path is:

1
/var/syncthing/downloads

the Web UI should use the latter.

Only Relay Connections, Very Slow

Check first:

  • whether 22000/TCP is allowed;
  • whether 22000/UDP is allowed;
  • whether router port forwarding is correct;
  • whether the cloud security group allows both TCP and UDP;
  • whether the local firewall blocks Docker’s mapped ports.

Relays improve reachability, but they are not suitable for long-term heavy sync traffic.

File Permissions Are Wrong After Sync

First confirm that the container user is correct, then check the host directory permissions. Linux, NAS, and Windows shared folders have different permission models. Do not treat Syncthing as a permission repair tool.

For cross-system sync, try to sync ordinary files and directories. Avoid syncing system folders that depend on complex ACLs, ownership, or extended attributes.

A More Stable Setup

If your goal is to use a NAS or server as the central node, design it like this:

  1. Run Syncthing with Docker on the NAS.
  2. Mount the configuration directory to /volume1/docker/syncthing/config.
  3. Mount each data category separately, for example /volume1/photos and /volume1/notes.
  4. Add the NAS device ID from phones and computers.
  5. Enable file versioning on important folders on the NAS side.
  6. Keep the Web UI accessible only on the LAN or through a VPN.
  7. Back up the NAS independently. Do not treat sync as the only backup.

In this setup, Syncthing handles device-to-device synchronization, the NAS provides always-on availability and version buffering, and real backup is still handled by snapshots, external disks, or off-site backups.

Summary

The key to deploying Syncthing with Docker is separating the container lifecycle from the sync data lifecycle.

The container can be updated, recreated, or migrated at any time. The configuration directory and data directories, however, must remain stable on the host. Use container paths in the Web UI, handle host permissions with PUID, PGID, and directory access rules, and open ports according to the actual network environment.

Once these pieces are clear, Syncthing works very well as a lightweight sync layer between a NAS, a server, and personal devices.

记录并分享
Built with Hugo
Theme Stack designed by Jimmy