Syncthing是一个开源的、去中心化的、跨平台的文件同步工具。它使用点对点技术直接在设备之间同步文件,不需要中央服务器,所有数据传输都是加密的,确保了隐私和安全。
P2P架构,无需中央服务器
所有数据传输都加密保护
文件变化立即同步
保留文件历史版本
Linux, Windows, macOS, Android
MIT许可证,完全免费
Syncthing采用去中心化架构,设备之间直接通信,通过发现服务器找到彼此:
# 主要组件:
1. Syncthing核心 - 文件同步引擎
2. Web UI - 基于Web的管理界面(默认8384端口)
3. 发现服务器 - 帮助设备找到彼此(可选)
4. 中继服务器 - 帮助NAT后的设备连接(可选)
# 数据流向:
设备A ↔ 发现服务器 ↔ 设备B
设备A ↔ 中继服务器 ↔ 设备B(如果直连失败)
设备A ↔ 设备B(直接连接,最优路径)
# 方法1:通过apt安装
sudo apt update
sudo apt install syncthing
# 方法2:使用官方仓库
sudo curl -o /usr/share/keyrings/syncthing-archive-keyring.gpg \
https://syncthing.net/release-key.gpg
echo "deb [signed-by=/usr/share/keyrings/syncthing-archive-keyring.gpg] \
https://apt.syncthing.net/ syncthing stable" | \
sudo tee /etc/apt/sources.list.d/syncthing.list
sudo apt update
sudo apt install syncthing
# 方法1:通过yum安装
sudo yum install syncthing
# 方法2:使用官方仓库
sudo tee /etc/yum.repos.d/syncthing.repo << EOF
[syncthing]
name=Syncthing Repository
baseurl=https://syncthing.net/repo/redhat
enabled=1
gpgcheck=1
gpgkey=https://syncthing.net/release-key.gpg
EOF
sudo yum install syncthing
sudo pacman -S syncthing
# 使用Homebrew
brew install syncthing
# 或下载DMG安装包
# https://syncthing.net/downloads/
sudo systemctl start syncthing@username
systemctl --user start syncthing
syncthing serve
nohup syncthing serve &
| 命令 | 描述 | 示例 |
|---|---|---|
syncthing serve |
启动Syncthing服务(前台运行) | syncthing serve |
syncthing --help |
显示帮助信息 | syncthing --help |
syncthing --version |
显示版本信息 | syncthing --version |
syncthing --home |
指定配置文件目录 | syncthing --home ~/.config/syncthing |
syncthing --gui-address |
指定Web UI地址 | syncthing --gui-address 127.0.0.1:8384 |
syncthing --no-browser |
启动时不打开浏览器 | syncthing --no-browser |
syncthing --logfile |
指定日志文件 | syncthing --logfile /var/log/syncthing.log |
syncthing --device-id |
显示设备ID | syncthing --device-id |
syncthing --generate |
生成配置文件和证书 | syncthing --generate ~/.syncthing |
# 1. 启动Syncthing后,访问Web界面
# 默认地址:http://localhost:8384
# 2. 如果远程访问,需要修改配置
# 编辑配置文件 ~/.config/syncthing/config.xml
# 修改gui address为0.0.0.0:8384
# 3. 使用命令行参数指定地址
syncthing --gui-address="0.0.0.0:8384"
# 4. 设置用户名密码(通过Web界面)
# 设置 -> GUI -> 认证
# 或直接编辑配置文件:
# <gui enabled="true" tls="false" debugging="false">
# <address>0.0.0.0:8384</address>
# <user>admin</user>
# <password>password</password>
# </gui>
# 5. 启用TLS(推荐)
syncthing --gui-apikey="your-api-key" --gui-tls-cert=/path/to/cert --gui-tls-key=/path/to/key
# 1. 获取设备ID
syncthing --device-id
# 输出类似:7CFNTQM-IMTIOHY-6UZ5DV5-4B2H7R7-MFPUVQ5-H3RWRUZ-P4P5J5Q-BD5BWAQ
# 2. 通过配置文件添加设备
# 编辑 ~/.config/syncthing/config.xml
# 在 <device> 部分添加新设备
# 3. 设备配置示例
<device id="7CFNTQM-IMTIOHY-6UZ5DV5-4B2H7R7-MFPUVQ5-H3RWRUZ-P4P5J5Q-BD5BWAQ" name="My Laptop" compression="metadata" introducer="false" skipIntroductionRemovals="false" introducedBy="">
<address>dynamic</address>
<paused>false</paused>
<autoAcceptFolders>false</autoAcceptFolders>
<maxSendKbps>0</maxSendKbps>
<maxRecvKbps>0</maxRecvKbps>
<maxRequestKiB>0</maxRequestKiB>
</device>
# 4. 使用STCLI工具(第三方命令行工具)
# 安装:go get github.com/syncthing/syncthing/cmd/stcli
stcli --gui-apikey=your-api-key devices add --device-id=ID --name="Device Name"
# 5. 设备连接状态检查
# Web界面查看或通过API
curl -s -H "X-API-Key: your-api-key" http://localhost:8384/rest/system/connections | jq .
# 1. 通过Web界面添加文件夹
# Web界面 -> 添加文件夹
# 2. 通过配置文件添加
# 编辑 ~/.config/syncthing/config.xml
# 在 <folder> 部分添加
# 3. 文件夹配置示例
<folder id="documents" label="Documents" path="~/Documents" type="sendreceive" rescanIntervalS="3600" fsWatcherEnabled="true" fsWatcherDelayS="10" ignorePerms="false" autoNormalize="true">
<device id="device-id-here"></device>
<minDiskFree unit="%">1</minDiskFree>
<versioning type="simple">
<param value="10"></param>
</versioning>
<copiers>0</copiers>
<pullerMaxPendingKiB>0</pullerMaxPendingKiB>
<hashers>0</hashers>
<order>random</order>
<ignoreDelete>false</ignoreDelete>
<scanProgressIntervalS>0</scanProgressIntervalS>
<pullerPauseS>0</pullerPauseS>
<maxConflicts>10</maxConflicts>
<disableSparseFiles>false</disableSparseFiles>
<disableTempIndexes>false</disableTempIndexes>
<paused>false</paused>
<weakHashThresholdPct>25</weakHashThresholdPct>
<markerName>.stfolder</markerName>
<copyOwnershipFromParent>false</copyOwnershipFromParent>
<modTimeWindowS>0</modTimeWindowS>
<maxConcurrentWrites>2</maxConcurrentWrites>
<disableFsync>false</disableFsync>
<blockPullOrder>standard</blockPullOrder>
<copyRangeMethod>standard</copyRangeMethod>
<caseSensitiveFS>false</caseSensitiveFS>
<junctionsAsDirs>false</junctionsAsDirs>
</folder>
# 4. 使用API添加文件夹
curl -X POST -H "X-API-Key: your-api-key" -H "Content-Type: application/json" \
-d '{"id":"test","label":"Test Folder","path":"/home/user/test","type":"sendreceive","devices":[{"deviceID":"device-id"}]}' \
http://localhost:8384/rest/config/folders
# 1. 在同步文件夹中创建 .stignore 文件
# 语法类似.gitignore,支持通配符和正则表达式
# 2. .stignore 示例
# 忽略临时文件
*.tmp
*.temp
*.swp
*.swo
# 忽略目录
.cache/
.temp/
node_modules/
vendor/
# 忽略特定文件
secret.txt
passwords.txt
# 注释以 # 开头
# 忽略日志文件
*.log
# 使用正则表达式
(?d).*\.bak$ # 忽略所有.bak文件
# 取消忽略(使用!)
!important.log
# 3. 刷新忽略规则
# 通过Web界面:文件夹 -> 编辑 -> 重新扫描
# 或通过API
curl -X POST -H "X-API-Key: your-api-key" \
http://localhost:8384/rest/db/scan?folder=folder-id
# 4. 检查忽略状态
curl -H "X-API-Key: your-api-key" \
http://localhost:8384/rest/db/ignores?folder=folder-id
# 1. 版本控制类型
# - simple: 简单版本控制(保留N个版本)
# - staggered: 阶梯式版本控制(不同时间段的版本)
# - external: 外部版本控制(调用外部命令)
# - trashcan: 回收站模式
# 2. 简单版本控制配置(在folder配置中)
<versioning type="simple">
<param value="10"></param> # 保留10个版本
</versioning>
# 3. 阶梯式版本控制配置
<versioning type="staggered">
<param value="maxAge">31536000</param> # 1年
<param value="versionsPath">/path/to/versions</param>
</versioning>
# 4. 外部版本控制(调用脚本)
<versioning type="external">
<param value="/path/to/versioning-script"></param>
</versioning>
# 5. 版本控制脚本示例
#!/bin/bash
# versioning-script.sh
# 参数:1=文件路径,2=版本路径,3=版本ID
FILE_PATH="$1"
VERSION_PATH="$2"
VERSION_ID="$3"
# 创建版本目录
mkdir -p "$VERSION_PATH"
# 复制文件到版本目录
cp "$FILE_PATH" "$VERSION_PATH/$VERSION_ID"
# 限制版本数量为20
ls -t "$VERSION_PATH" | tail -n +21 | xargs -I {} rm "$VERSION_PATH/{}"
# 1. 获取API Key
# 从配置文件获取
cat ~/.config/syncthing/config.xml | grep apikey | sed 's/.*apikey>\(.*\)<.*/\1/'
# 2. 常用API端点
# 系统信息
curl -H "X-API-Key: your-api-key" http://localhost:8384/rest/system/status
# 连接状态
curl -H "X-API-Key: your-api-key" http://localhost:8384/rest/system/connections
# 设备列表
curl -H "X-API-Key: your-api-key" http://localhost:8384/rest/config/devices
# 文件夹列表
curl -H "X-API-Key: your-api-key" http://localhost:8384/rest/config/folders
# 文件夹状态
curl -H "X-API-Key: your-api-key" http://localhost:8384/rest/db/status?folder=folder-id
# 扫描文件夹
curl -X POST -H "X-API-Key: your-api-key" http://localhost:8384/rest/db/scan?folder=folder-id
# 暂停/恢复文件夹
curl -X POST -H "X-API-Key: your-api-key" \
-d '{"paused":true}' \
http://localhost:8384/rest/config/folders/folder-id
# 获取事件(长轮询)
curl -H "X-API-Key: your-api-key" "http://localhost:8384/rest/events?since=0&timeout=60"
# 3. API使用示例脚本
#!/bin/bash
API_KEY="your-api-key"
API_URL="http://localhost:8384"
# 检查系统状态
check_status() {
curl -s -H "X-API-Key: $API_KEY" "$API_URL/rest/system/status" | jq .
}
# 获取所有设备
list_devices() {
curl -s -H "X-API-Key: $API_KEY" "$API_URL/rest/config/devices" | jq .
}
# 获取文件夹同步进度
folder_progress() {
curl -s -H "X-API-Key: $API_KEY" "$API_URL/rest/db/status?folder=$1" | jq .
}
# 1. 全局带宽限制
# 编辑配置文件,在options部分添加
<options>
<listenAddress>default</listenAddress>
<globalAnnounceServer>default</globalAnnounceServer>
<globalAnnounceEnabled>true</globalAnnounceEnabled>
<localAnnounceEnabled>true</localAnnounceEnabled>
<maxSendKbps>1000</maxSendKbps> # 最大发送速度 1Mbps
<maxRecvKbps>2000</maxRecvKbps> # 最大接收速度 2Mbps
<reconnectionIntervalS>60</reconnectionIntervalS>
<relaysEnabled>true</relaysEnabled>
<relayReconnectIntervalM>10</relayReconnectIntervalM>
<startBrowser>true</startBrowser>
<natEnabled>true</natEnabled>
<natLeaseMinutes>60</natLeaseMinutes>
<natRenewalMinutes>30</natRenewalMinutes>
<natTimeoutSeconds>10</natTimeoutSeconds>
<urAccepted>-1</urAccepted>
<urUniqueID></urUniqueID>
<urURL>https://data.syncthing.net/newdata</urURL>
<urPostInsecurely>false</urPostInsecurely>
<urInitialDelayS>1800</urInitialDelayS>
<restartOnWakeup>true</restartOnWakeup>
<autoUpgradeIntervalH>12</autoUpgradeIntervalH>
<upgradeToPreReleases>false</upgradeToPreReleases>
<keepTemporariesH>24</keepTemporariesH>
<cacheIgnoredFiles>false</cacheIgnoredFiles>
<progressUpdateIntervalS>5</progressUpdateIntervalS>
<limitBandwidthInLan>false</limitBandwidthInLan>
<minHomeDiskFree unit="%">1</minHomeDiskFree>
<releasesURL>https://upgrades.syncthing.net/meta.json</releasesURL>
<overwriteRemoteDeviceNamesOnConnect>false</overwriteRemoteDeviceNamesOnConnect>
<tempIndexMinBlocks>10</tempIndexMinBlocks>
<unackedNotificationIDs></unackedNotificationIDs>
</options>
# 2. 设备级带宽限制
# 在device配置中
<device id="device-id">
<maxSendKbps>500</maxSendKbps>
<maxRecvKbps>1000</maxRecvKbps>
</device>
# 3. 文件夹级并发设置
# 在folder配置中
<folder id="folder-id">
<copiers>2</copiers> # 同时复制文件数
<hashers>1</hashers> # 同时哈希计算数
<pullerMaxPendingKiB>1024</pullerMaxPendingKiB>
<maxConcurrentWrites>2</maxConcurrentWrites>
</folder>
# 1. 自定义发现服务器
# 在options部分修改
<globalAnnounceServer>default</globalAnnounceServer>
# 或指定多个
<globalAnnounceServer>https://discovery.syncthing.net/v2/</globalAnnounceServer>
<globalAnnounceServer>https://discovery-v4.syncthing.net/v2/</globalAnnounceServer>
<globalAnnounceServer>https://discovery-v6.syncthing.net/v2/</globalAnnounceServer>
# 2. 自定义中继服务器
# 默认使用公共中继池,也可指定
<relaysEnabled>true</relaysEnabled>
<relayReconnectIntervalM>10</relayReconnectIntervalM>
# 如果需要,可以添加特定中继
<relay>relay://relay.syncthing.net:22067</relay>
<relay>relay://relay://192.168.1.100:22067</relay>
# 3. 局域网发现(mDNS/Bonjour)
<localAnnounceEnabled>true</localAnnounceEnabled>
<localAnnouncePort>21027</localAnnouncePort>
<localAnnounceMCAddr>[ff12::8384]:21027</localAnnounceMCAddr>
# 设备无法连接
# 解决方案:
# 1. 检查防火墙
sudo ufw allow 22000/tcp # 同步端口
sudo ufw allow 8384/tcp # Web UI端口
# 2. 检查发现服务器
# Web界面 -> 操作 -> 连接
# 查看设备连接状态
# 3. 启用中继
# 设置 -> 连接 -> 中继服务器 -> 启用
# 4. 检查网络配置
# 设置 -> 连接 -> 监听地址
# 确保有正确的监听地址
# 文件不同步
# 解决方案:
# 1. 检查文件夹权限
ls -la /path/to/folder
chmod 755 /path/to/folder
# 2. 检查忽略规则
cat /path/to/folder/.stignore
# 3. 强制重新扫描
# Web界面 -> 文件夹 -> 重新扫描
# 或通过API
curl -X POST -H "X-API-Key: api-key" \
http://localhost:8384/rest/db/scan?folder=folder-id
# 4. 检查版本冲突
# Web界面查看文件状态
# 同步速度慢
# 解决方案:
# 1. 调整带宽限制
# 设置 -> 连接 -> 限制带宽
# 2. 调整并发设置
# 文件夹 -> 编辑 -> 高级
# 调整"同时复制文件数"和"同时哈希计算数"
# 3. 减少同步文件数量
# 使用.ignore文件排除不需要的文件
# 4. 检查磁盘性能
hdparm -Tt /dev/sda
iotop
# 配置错误
# 解决方案:
# 1. 验证配置文件
syncthing --audit
# 2. 重置配置(谨慎操作)
# 停止syncthing
systemctl stop syncthing@user
# 备份配置
mv ~/.config/syncthing ~/.config/syncthing.backup
# 重新启动生成新配置
systemctl start syncthing@user
# 3. 查看日志
journalctl -u syncthing@user -f
# 或查看日志文件
tail -f ~/.config/syncthing/syncthing.log
#!/bin/bash
# syncthing-monitor.sh - 监控Syncthing状态
API_KEY="your-api-key"
API_URL="http://localhost:8384"
LOG_FILE="/var/log/syncthing-monitor.log"
ALERT_EMAIL="admin@example.com"
# 检查Syncthing状态
check_syncthing() {
local status=$(curl -s -o /dev/null -w "%{http_code}" -H "X-API-Key: $API_KEY" "$API_URL/rest/system/ping")
if [ "$status" != "200" ]; then
echo "[$(date)] Syncthing服务异常,HTTP状态码: $status" >> "$LOG_FILE"
systemctl restart syncthing@$(whoami)
send_alert "Syncthing服务重启"
else
echo "[$(date)] Syncthing服务正常" >> "$LOG_FILE"
fi
}
# 检查设备连接
check_connections() {
local connections=$(curl -s -H "X-API-Key: $API_KEY" "$API_URL/rest/system/connections" | jq '.connections | length')
if [ "$connections" -lt 1 ]; then
echo "[$(date)] 没有活动的设备连接" >> "$LOG_FILE"
else
echo "[$(date)] 有 $connections 个设备连接" >> "$LOG_FILE"
fi
}
# 检查文件夹同步状态
check_folders() {
local folders=$(curl -s -H "X-API-Key: $API_KEY" "$API_URL/rest/config/folders" | jq -r '.[].id')
for folder in $folders; do
local status=$(curl -s -H "X-API-Key: $API_KEY" "$API_URL/rest/db/status?folder=$folder" | jq '.state')
if [ "$status" != "\"idle\"" ]; then
echo "[$(date)] 文件夹 $folder 状态: $status" >> "$LOG_FILE"
fi
done
}
# 发送警报
send_alert() {
local message="$1"
if command -v mail &> /dev/null; then
echo "$message" | mail -s "Syncthing监控警报" "$ALERT_EMAIL"
fi
# 也可以发送到Slack、Telegram等
}
# 主监控循环
while true; do
check_syncthing
check_connections
check_folders
sleep 300 # 5分钟检查一次
done
| 特性对比 | Syncthing | Resilio Sync | Nextcloud |
|---|---|---|---|
| 架构 | 去中心化P2P | 去中心化P2P | 客户端-服务器 |
| 开源 | 是(MIT) | 否(商业) | 是(AGPL) |
| 加密 | 端到端加密 | 端到端加密 | 传输加密 |
| 实时同步 | 支持 | 支持 | 支持 |
| 版本控制 | 内置 | 有限 | 内置 |
| 选择性同步 | 支持 | 支持 | 支持 |
| Web界面 | 内置 | 内置 | 内置 |
| 适用场景 | 多设备直接同步、隐私保护 | 商业环境、跨平台同步 | 团队协作、云存储替代 |
~/.config/syncthing).stignore文件排除不需要同步的文件#!/bin/bash
# backup-syncthing-config.sh
CONFIG_DIR="$HOME/.config/syncthing"
BACKUP_DIR="/mnt/backup/syncthing"
DATE=$(date +%Y%m%d_%H%M%S)
# 停止Syncthing服务
systemctl --user stop syncthing
# 创建备份
mkdir -p "$BACKUP_DIR/$DATE"
cp -r "$CONFIG_DIR"/* "$BACKUP_DIR/$DATE/"
# 压缩备份
tar -czf "$BACKUP_DIR/syncthing-config-$DATE.tar.gz" -C "$BACKUP_DIR/$DATE" .
# 清理临时文件
rm -rf "$BACKUP_DIR/$DATE"
# 保留最近7天的备份
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +7 -delete
# 启动Syncthing服务
systemctl --user start syncthing
echo "Syncthing配置备份完成:$BACKUP_DIR/syncthing-config-$DATE.tar.gz"
#!/bin/bash
# add-devices-batch.sh
API_KEY="your-api-key"
API_URL="http://localhost:8384"
# 设备列表(ID:名称)
declare -A devices=(
["ID1"]="Laptop"
["ID2"]="Desktop"
["ID3"]="Server"
["ID4"]="Phone"
)
# 为每个设备添加配置
for device_id in "${!devices[@]}"; do
device_name="${devices[$device_id]}"
echo "添加设备: $device_name ($device_id)"
curl -X POST -H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d "{
\"deviceID\": \"$device_id\",
\"name\": \"$device_name\",
\"addresses\": [\"dynamic\"],
\"compression\": \"metadata\",
\"introducer\": false,
\"skipIntroductionRemovals\": false,
\"introducedBy\": \"\",
\"paused\": false,
\"allowedNetworks\": [],
\"autoAcceptFolders\": false,
\"maxSendKbps\": 0,
\"maxRecvKbps\": 0,
\"maxRequestKiB\": 0,
\"ignoredFolders\": [],
\"pendingFolders\": []
}" \
"$API_URL/rest/config/devices"
echo ""
done
echo "批量添加设备完成"