SyncWings lets you sync files between multiple devices and manage them easily through a web-based file manager. It combines Syncthing for secure, peer-to-peer file synchronization with FileStash for convenient file browsing, downloading, renaming, and deleting—all from your browser.
Whether for a single user or multiple users, SyncWings gives each user their own isolated Syncthing (and optional FileStash) instance, managed automatically via Docker Compose for easy deployment and strong separation between users.
Demo: https://demo.syncwings.com
Feel free to use the demo to try things out. The demo instance is reset every hour.
Demo login details:
Admin user:
Username: admin
Password: R2r63&^NqgEPTSf4#5pj
Regular user:
Username: user
Password: jR7balz*Bczs9#^FNSY3
- Can be used for both single-user and multi-user setups. Even for single users, SyncWings is useful as it hosts both Syncthing and FileStash in one place.
- FileStash integration allows downloading individual files (which is not possible with Syncthing alone).
- FileStash also enables file management features such as renaming, deleting, and organizing files directly from the web interface. These changes are then propagated to other devices via Syncthing.
- User registration and login (file-based, no database required)
- Each user is linked to a unique Syncthing instance
- Admin can add or remove users
- Optional FileStash integration for file management
- AMD64 and ARM64 support
- Docker and Docker Compose installed on your server
- A Linux environment (the project is designed for Linux hosts)
services:
syncwings:
image: loosetooth/syncwings:latest
environment:
# Set the data directory inside the container
- DATA_DIR=/data
# Set the external data directory (adjust this path as needed)
# This has to be equal to the bind mount for the DATA_DIR in the volumes section below
- DATA_DIR_EXTERNAL=/path/to/large/disk/syncwings/data
# Optionally set the port for the Next.js app (default: 3000)
- PORT=3001
# Set the session secret from the .env file
- SESSION_SECRET=${SESSION_SECRET}
# The ./data directory must be created and owned by the same UID:GID as set below
volumes:
# The host path should be the same as DATA_DIR_EXTERNAL
- /path/to/large/disk/syncwings/data:/data
# Mount the Docker socket to allow spawning Syncthing and FileStash containers
- /var/run/docker.sock:/var/run/docker.sock
# Set to UID:GID where GID matches the docker group on your host
# UID HAS TO BE "1000" because FileStash uses this UID internally
user: "1000:131"
restart: unless-stopped
network_mode: host
Place the above docker-compose.yml
in a directory on your server.
Adjust /path/to/large/disk/syncwings/data
to a suitable location on your host with enough space for user data.
Currently, all user data, including Syncthing's config
folder and database files, are stored in this directory.
Generate a strong session secret for signing cookies:
openssl rand -base64 64 | tr -d '\n'; echo
Create a .env
file next to your docker-compose.yml
and add the generated secret:
SESSION_SECRET=your-very-secret-string
Replace your-very-secret-string
with the output from the command above.
Make sure to keep this secret safe and do not share it publicly.
From the directory containing your docker-compose.yml
and .env
file, run:
docker compose up -d
The app will be available at http://localhost:3000
(or the port you specified in the PORT
environment variable).
The first user to register will be an administrator by default.
- Set up a reverse proxy on your webserver (e.g., Nginx, Apache, Caddy) to handle HTTPS and domain routing.
- Configure firewall rules and/or Port Forwarding to allow:
- accessing the SyncWings UI
- allow Syncthing instances to create direct connections
In order to allow multiple instances of Syncthing to run on the same host, each instance is configured to use a unique port range based on the user's ID. Depending on the number of users, you need to open the following ports in your firewall and/or router:
- TCP/UDP ports:
22003-22053
(for Syncthing device connections)
If these ports are not opened, Syncthing connections will still work via relays, but direct connections will not be possible. This might result in slower sync speeds.
-
SESSION_SECRET
(required):- Secret key used to sign and verify session cookies (JWTs). Must be set to a long, random string in production.
- Generate with
openssl rand -base64 64
and remove the newline from the output.
-
DATA_DIR
(optional):- Set this to specify a custom directory for storing the
users.json
file (user database) and user's syncthing data. - If not set, the project root directory is used by default.
- Set this to specify a custom directory for storing the
-
DATA_DIR_EXTERNAL
(recommended for Docker Compose):- Set this to specify the absolute host path for user Syncthing data and config directories when generating Docker Compose files.
- Ensures that Syncthing containers mount user data/config from a fixed location on the host (e.g.,
/opt/syncwings-data
). - If not set, defaults to
DATA_DIR
if it is set, otherwise falls back to/data
.
-
SYNCTHING_CONTAINER_TAG
(optional):- Set this to specify the tag/version of the Syncthing container image used for each user instance (default:
2.0.1
). - The container used is
syncthing/syncthing
.
- Set this to specify the tag/version of the Syncthing container image used for each user instance (default:
-
PORT
(optional):- Set this to specify the port the Next.js app should listen on (default: 3000).
- Useful if port 3000 is already in use on your server.
-
NEXT_PUBLIC_ENABLE_FILE_STASH
(optional):- Set this to
true
to enable the File Stash integration, allowing users to upload and manage files through the web interface. - Defaults to
true
if not set.
- Set this to
-
FILESTASH_CONTAINER_TAG
(optional):- Set this to specify the tag/version of the File Stash container image used. If not set, the default
FILESTASH_CONTAINER_DIGEST
is used. (See below.) - The container used is
machines/filestash
.
- Set this to specify the tag/version of the File Stash container image used. If not set, the default
-
FILESTASH_CONTAINER_DIGEST
(optional):- Set this to specify the digest of the File Stash container image used. This ensures that a specific, immutable version of the image is used.
- If not set, defaults to
sha256:29b785d6c7a362581c2254dcafbe91d76a20a73871a520dc85d7d970113bc965
. - If both
FILESTASH_CONTAINER_TAG
andFILESTASH_CONTAINER_DIGEST
are set, the digest will be used. - Please include the
sha256:
prefix when setting this variable.
-
EXPLICITLY_LISTEN_TO_LOCAL_IP
(optional):- Set this to
true
to have Syncthing explicitly listen on the local IP address specified inLOCAL_IP_ADDRESS
. - This is useful for LAN discovery, which might not work properly when Syncthing is inside a Docker container. (See this github issue for more context.)
- Needs to be set in combination with the
LOCAL_IP_ADDRESS
variable. - Be aware that this pollutes the logs with periodic failure messages because the local ip cannot be bound to.
- Set this to
-
LOCAL_IP_ADDRESS
(optional):- Set this to the local IP address of your server (e.g.,
192.168.1.100
). - This needs to be set in combination with the above
EXPLICITLY_LISTEN_TO_LOCAL_IP
variable to ensure Syncthing listens on this IP address.
- Set this to the local IP address of your server (e.g.,
-
MAX_USERS
(optional):- Set this to limit the maximum number of users that can register. If not set, defaults to
10
.
- Set this to limit the maximum number of users that can register. If not set, defaults to
-
ENABLE_IPV6
(optional):- Set this to
true
to enable IPv6 support in the generated Docker Compose files. - Defaults to
false
. - For IPv6 support to work, it needs to be enabled for the default bridge network in Docker. To enable this, follow the official Docker documentation: Use IPv6 for the default bridge network.
- Set this to
- Install dependencies:
npm install
- Start the development server:
npm run dev
- The app will be available at
http://localhost:3000
by default.
To build the Docker image:
docker build -t syncwings .
To run the app using Docker Compose, use the provided docker-compose.yml
as an example:
docker compose up
Important Notes:
-
The Docker container must be run with a group that has permissions to access the Docker socket (usually the
docker
group on your host). Set theuser:
field in yourdocker-compose.yml
to use a group ID (GID) that matches the Docker group on your system. You can find the GID with:getent group docker
Then update the
user:
field, e.g.user: "1000:999"
if the Docker group GID is 999. -
The mounted
DATA_DIR
folder (e.g../data
) must be created in advance and owned by the user specified in thedocker-compose.yml
file. For example, if you useuser: "1000:999"
, run:mkdir -p ./data chown 1000:999 ./data
This ensures the app can write to the data directory without permission issues.
-
The provided user ID (UID) must be
1000
because FileStash uses this UID internally.
Adjust the compose file and permissions as needed for your environment.
- This project is intended for Linux environments.
- All user data is stored in a single JSON file for simplicity.