Key points
- A Bash script that installs Syncthing, creates a dedicated low-privileged user, sets up its folders and service, and prints the status and API key.
- The script now creates the configuration with
syncthing generate, the form Syncthing 2 (August 2025) requires, and sets the GUI login fromGUI_USERandGUI_PASSWORD. - The script expects your own
config.xmlbeside it; without one, the GUI listens on127.0.0.1:8384.
Simplify Syncthing Installation with This Bash Script
Updated October 2026: Syncthing 2.0 came out in August 2025 (2.1.6 is current), and the official repository at apt.syncthing.net carries it. Read these points before you run the Syncthing setup script:
- It copies a
config.xmlfrom the folder you run it in, and that file is not part of this post: the GUI user and password at the top of the script are applied bysyncthing generate, but the addresses are only printed, not applied. Without your ownconfig.xml, Syncthing creates a default one with the GUI on 127.0.0.1:8384, not on port 5612. - Syncthing 2 no longer accepts single-dash options, so the script’s two
syncthing -generatelines failed (and the quoted~in them was never expanded). The script below now runs this line instead, which also sets the GUI login fromGUI_USERandGUI_PASSWORD: - Remove the
net.ipv4.ip_unprivileged_port_start=0line the script adds to/etc/sysctl.conf: it lets every local user open ports below 1024, and ports 5612 and 22222 do not need it.sysctl -w net.ipv4.ip_unprivileged_port_start=1024restores the default. - Running the script again deletes
/home/syncthing/.config/syncthing, including the device keys, so the server gets a new device ID. - The status check needs jq (
apt install jq), and the service starts on boot only aftersystemctl enable syncthing@syncthing.
sudo -u syncthing syncthing generate --home=/home/syncthing/.config/syncthing --gui-user="$GUI_USER" --gui-password="$GUI_PASSWORD"
Setting up Syncthing on a Debian-based system can be time-consuming. This Bash script automates the entire process, making secure file synchronization effortless and efficient.
What Is Syncthing?
Syncthing is an open-source tool for secure, decentralized file synchronization across multiple devices. It keeps your data private and under your control, avoiding reliance on third-party servers.
Key Features of the Script
- Root Privileges Check: Ensures the script runs with necessary permissions.
- User Management: Creates a dedicated Syncthing user for enhanced security.
- Installation: Installs Syncthing if it’s not already present.
- Configuration: Sets up configuration directories, permissions, and necessary services.
- Service Management: Configures Syncthing to run under a low-privileged user and manages service restarts.
- Status Check: Retrieves and displays Syncthing status, API keys, and connected devices.
How It Works
- Prepares the System:
- Removes any previous Syncthing configurations.
- Creates a dedicated
syncthinguser to enhance security.
- Installs Syncthing: Installs Syncthing from Debian repositories if it is not already present.
- Configures Syncthing:
- Sets up configuration files, directories, and permissions.
- Copies your own
config.xml(from the folder you run the script in) with your GUI and networking settings.
- Manages the Service:
- Disables root-level services and ensures Syncthing runs under the correct user.
- Restarts the service to apply changes. To start it on boot, run
systemctl enable syncthing@syncthing.
- Displays Status and Next Steps:
- Outputs API keys, GUI credentials, and connection details.
- Provides instructions for pairing devices and managing shared folders.
Quick Start with the Syncthing Setup Script
- Save and Make Executable: copy the full script at the end of this post into a file named
syncthing-setup.sh, put yourconfig.xmlin the same folder, then run:
chmod +x syncthing-setup.sh
- Run the Script:
sudo ./syncthing-setup.sh
- Let It Run: Let the script install Syncthing, copy your configuration and set up the service.
- Access Syncthing:
- Open the web interface at
http://<your-server-ip>:5612. - Use the provided credentials to log in and configure synchronization.
- Open the web interface at
Benefits
- Time-Saving: Automates the installation and configuration process.
- Enhanced Security: Runs Syncthing under a dedicated user with restricted permissions.
- Decentralized Control: Ensures your data remains private and accessible only to authorized devices.
- Ease of Use: Simplifies complex configurations with a streamlined script.
Conclusion
This Bash script makes setting up Syncthing on Debian-based systems a breeze. By automating every step, it ensures a secure and efficient synchronization setup. Take control of your data and simplify file sharing across devices today with this powerful tool! For one-way, real-time sync between servers, see my Lsyncd setup script.
#!/bin/bash
# =========================================
# Syncthing Setup
# =========================================
#
# Version: 1.0.4
# Script written by Warith AL Maawali
#
# Discord channel: https://discord.gg/KEFErEx
# Twitter: https://x.com/warith2020
# Linkedin: https://www.linkedin.com/in/warith1977
# Website: https://www.digi77.com
# (c) 2024
#
# Description:
# This script installs and configures Syncthing on a Debian-based system.
# It ensures root privileges, removes old configurations, creates a Syncthing user,
# installs Syncthing if not already installed, prepares the configuration directory,
# and sets up necessary permissions and services.
#
# This software is dual-licensed:
#
# Personal, non-commercial use: Apache License 2.0
# Commercial, corporate, or organizational use: Separate commercial license required.
# Contact me for licensing inquiries.
#
# Usage: ./syncthing-setup.sh
#
# Usage Examples:
# Run this script as root to set up Syncthing:
# ./syncthing-setup.sh
# =========================================
# Global Variables
FOLDER_PATH="/var/www/html/vps-cards"
GUI_USER="x_your_username_x"
GUI_PASSWORD='x_your_password_x'
ENCRYPTION_PASSWORD="x_your_password_x"
GUI_ADDRESS="0.0.0.0:5612"
LISTEN_TCP="tcp://0.0.0.0:22222"
LISTEN_TCP6="tcp6://[::]:22222"
LISTEN_QUIC="quic://0.0.0.0:22222"
LISTEN_QUIC6="quic6://[::]:22221"
# Configuration File Path
CONFIG_DIR="/home/syncthing/.config/syncthing"
CONFIG_FILE="$CONFIG_DIR/config.xml"
USER="syncthing"
# Function to install and configure Syncthing on Debian
setup_syncthing() {
# Ensure root privileges
if [ "$EUID" -ne 0 ]; then
echo "Please run as root"
exit 1
fi
# Remove old configuration directory
rm -rf "$CONFIG_DIR"
# Create Syncthing user if it doesn't exist
if ! id -u $USER &>/dev/null; then
useradd -r -m -d /home/syncthing -s /usr/sbin/nologin $USER
echo "User $USER created."
fi
# Install Syncthing if not already installed
if ! command -v syncthing &>/dev/null; then
apt update && apt install -y syncthing
fi
# Prepare the configuration directory and permissions
mkdir -p "$CONFIG_DIR"
chown -R $USER:$USER "$CONFIG_DIR"
# Disable root service for Syncthing and configure for $USER
systemctl stop syncthing@root && systemctl disable syncthing@root && systemctl mask syncthing@root
systemctl stop syncthing@$USER
setcap 'cap_net_bind_service=+ep' /usr/bin/syncthing
# Ensure low privileged port binding is allowed
if ! grep -q 'net.ipv4.ip_unprivileged_port_start=0' /etc/sysctl.conf; then
echo 'net.ipv4.ip_unprivileged_port_start=0' | sudo tee -a /etc/sysctl.conf && sysctl -p
fi
# Start Syncthing service for user
systemctl restart syncthing@$USER
# Copy the provided config.xml to the Syncthing configuration directory
cp -f config.xml "$CONFIG_FILE"
chown $USER:$USER "$CONFIG_FILE"
sudo -u "$USER" syncthing generate --home="$CONFIG_DIR" --gui-user="$GUI_USER" --gui-password="$GUI_PASSWORD"
# Ensure CONFIG_FILE exists, create if missing
if [ ! -f "$CONFIG_FILE" ]; then
sudo -u "$USER" syncthing generate --home="$CONFIG_DIR" --gui-user="$GUI_USER" --gui-password="$GUI_PASSWORD"
while [ ! -f "$CONFIG_FILE" ]; do sleep 1; done
fi
# Final restart to apply configurations
systemctl restart syncthing@$USER
# Display next steps
echo "====================================================="
echo "Syncthing is configured. Access the web interface at https://<your-vps-ip>:${GUI_ADDRESS##*:}"
echo "The configuration file has been copied. You might want to change those values later."
echo "Current configuration values:"
echo "FOLDER_PATH: $FOLDER_PATH"
echo "GUI_USER: $GUI_USER"
echo "GUI_PASSWORD: $GUI_PASSWORD"
echo "ENCRYPTION_PASSWORD: $ENCRYPTION_PASSWORD"
echo "GUI_ADDRESS: $GUI_ADDRESS"
echo "LISTEN_TCP: $LISTEN_TCP"
echo "LISTEN_TCP6: $LISTEN_TCP6"
echo "LISTEN_QUIC: $LISTEN_QUIC"
echo "LISTEN_QUIC6: $LISTEN_QUIC6"
echo "Next steps:"
echo "1. Pair this device with others via the Syncthing web interface."
echo "2. Configure shared folders on other nodes and approve sync requests."
echo "3. Path to configuration file: $CONFIG_FILE"
echo "====================================================="
}
# Function to show Syncthing status
show_syncthing_status() {
# Check if xmlstarlet is installed, if not, install it
if ! command -v xmlstarlet &>/dev/null; then
echo "xmlstarlet not found, installing..."
sudo apt-get update && sudo apt-get install -y xmlstarlet
fi
# Extract API key from the Syncthing config
API_KEY=$(xmlstarlet sel -t -v "//apikey" "$CONFIG_FILE")
if [ -z "$API_KEY" ]; then
echo "API key not found in the Syncthing config."
exit 1
fi
echo "API Key: $API_KEY"
# Set your Syncthing API key and base URL
BASE_URL="https://localhost:5612"
FOLDER_ID="unvv4-ddta3" # Replace with your actual folder ID
# Get the list of pending folders and devices
PENDING_FOLDERS=$(curl -k -s -X GET -H "X-API-Key: $API_KEY" "$BASE_URL/rest/cluster/pending/folders")
PENDING_DEVICES=$(curl -k -s -X GET -H "X-API-Key: $API_KEY" "$BASE_URL/rest/cluster/pending/devices")
ACTIVE_DEVICES=$(curl -k -s -X GET -H "X-API-Key: $API_KEY" "$BASE_URL/rest/config/devices")
# Extract and show only device id and ip for active and pending devices
echo "Pending Devices:"
echo "$PENDING_DEVICES" | jq -r 'to_entries[] | "Device ID: \(.key), IP: \(.value.address)"'
echo "Active Devices:"
echo "$ACTIVE_DEVICES" | jq -r '.[] | "Device ID: \(.deviceID), IP: \(.addresses[])"'
echo "Pending Folders:"
echo "$PENDING_FOLDERS" | jq -r 'to_entries[] | "Folder ID: \(.key), Folder Name: \([.value.offeredBy[].label] | first)"'
}
# Main script execution
setup_syncthing
show_syncthing_statusShellScript