rsyncやrcloneは、どかっとまとめてバックアップするのには適していますが、データベースファイルは別に除外し、本当に大事な画像ファイルや、テキストファイルなどをバックアップするだけなら、Syncthingなどの同期ツールのほうが適していそうです。
負荷や性質の違い
| 項目 | Syncthing (inotify監視) | rsync (差分スキャン) |
| 平常時 (待機中) | 中:メモリを常時消費し、OSのファイルシステム監視枠(inotify)を占有。 | ゼロ:実行していない間はリソースを一切使いません。 |
| 変更発生時 | 低:変更されたファイルのみを即座に処理するため、突発的な負荷が少ない。 | 高:全ファイルをなめて変更箇所を探すため、実行の瞬間にCPU/ディスクI/Oが跳ねる。 |
| スキャン負荷 | 初回のみ重い:起動時にハッシュ計算を行うが、後は監視メイン。 | 毎回重い:ファイル数が多いほど、実行時のインデックス作成に時間がかかる。 |
別サーバをもう1台用意出来るのであれば、LAN内でサーバ内のデータをSyncthingでリアルタイム同期し、定期的にrcloneにクラウド保存するのが良さそうです。そして、たまにデータベースも含めたバックアップを行うというのがベストではないでしょうか。
インストール
以下をコピペして貼り付ければインストール完了です。
#!/bin/bash
# =============================================================================
# Syncthing ホスト直インストールスクリプト
# 使い方: bash install-syncthing.sh (sudo不要)
# =============================================================================
set -euo pipefail
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
info() { echo -e "${BLUE}[INFO]${NC} $*"; }
success() { echo -e "${GREEN}[OK]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }
# ── 実行ユーザー確認 ───────────────────────────────────────
[[ $EUID -eq 0 ]] && error "このスクリプトは一般ユーザーで実行してください(sudo不要)"
CURRENT_USER=$(whoami)
# ── config.xml パスを解決する関数 ─────────────────────────
find_config() {
local candidates=(
"$HOME/.local/state/syncthing/config.xml"
"$HOME/.local/share/syncthing/config.xml"
"$HOME/.config/syncthing/config.xml"
)
for p in "${candidates[@]}"; do
[[ -f "$p" ]] && echo "$p" && return
done
# 見つからなければ find で探す
find "$HOME" -name "config.xml" -path "*/syncthing/*" 2>/dev/null | head -1
}
# ── apt リポジトリ追加 & インストール ─────────────────────
info "Syncthing 公式リポジトリを追加します..."
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://syncthing.net/release-key.gpg \
| sudo tee /etc/apt/keyrings/syncthing-archive-keyring.gpg > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/syncthing-archive-keyring.gpg] https://apt.syncthing.net/ syncthing stable" \
| sudo tee /etc/apt/sources.list.d/syncthing.list > /dev/null
sudo apt-get update -q || true # 無関係なリポジトリのエラーは無視
sudo apt-get install -y syncthing || error "Syncthing のインストールに失敗しました。"
success "Syncthing をインストールしました。"
# ── systemd サービス登録 ───────────────────────────────────
info "systemd サービスを登録します(ユーザー: $CURRENT_USER)..."
sudo systemctl enable syncthing@$CURRENT_USER
sudo systemctl start syncthing@$CURRENT_USER
success "Syncthing サービスを起動しました。"
# ── config.xml 生成待機(最大60秒)────────────────────────
info "config.xml の生成を待機中..."
CONFIG_FILE=""
for i in $(seq 1 30); do
CONFIG_FILE=$(find_config)
[[ -n "$CONFIG_FILE" ]] && break
sleep 2
done
[[ -z "$CONFIG_FILE" ]] && error "config.xml が見つかりませんでした。\n → find \$HOME -name config.xml -path '*/syncthing/*' で確認してください。"
success "config.xml を検出しました: $CONFIG_FILE"
# ── GUI をリモートアクセス可能に変更 ──────────────────────
info "GUI をリモートアクセス可能に設定します..."
sudo systemctl stop syncthing@$CURRENT_USER
python3 - "$CONFIG_FILE" << 'PYEOF'
import xml.etree.ElementTree as ET, sys
tree = ET.parse(sys.argv[1])
root = tree.getroot()
gui = root.find('gui')
def set_or_create(parent, tag, text):
el = parent.find(tag)
if el is None:
el = ET.SubElement(parent, tag)
el.text = text
set_or_create(gui, 'address', '0.0.0.0:8384')
tree.write(sys.argv[1], encoding='unicode', xml_declaration=True)
print("GUIアドレスを 0.0.0.0:8384 に変更しました。")
PYEOF
sudo systemctl start syncthing@$CURRENT_USER
sleep 3
# ── Device ID 取得 ─────────────────────────────────────────
DEVICE_ID=$(syncthing --device-id 2>/dev/null || echo "(GUIの「情報」から確認してください)")
HOST_IP=$(hostname -I | awk '{print $1}')
# ── 完了メッセージ ─────────────────────────────────────────
echo ""
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${GREEN} ✅ Syncthing インストール完了!${NC}"
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
echo -e " 📡 Web UI : ${BLUE}http://$HOST_IP:8384${NC}"
echo -e " 📁 設定ファイル : $CONFIG_FILE"
echo -e " 👤 実行ユーザー : $CURRENT_USER"
echo ""
echo -e " 🖥️ Device ID(バックアップPCへの接続時に使用):"
echo -e " ${YELLOW}$DEVICE_ID${NC}"
echo ""
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e " 📌 次のステップ:"
echo -e " 1. Web UI にアクセスしてパスワードを設定"
echo -e " (右上メニュー → Settings → GUI → GUI Authentication)"
echo -e " 2. フォルダを追加(ホストの絶対パスをそのまま入力)"
echo -e " 例: /opt/docker/immich/library/library/admin"
echo -e " /opt/docker/notediscovery/data"
echo -e " /opt/docker/nextcloud/data/data/user/files"
echo -e " 3. 各フォルダのタイプを ${YELLOW}Send Only${NC} に設定"
echo -e " 4. バックアップPCと Device ID を交換して接続"
echo -e " 5. バックアップPC側を ${YELLOW}Receive Only${NC} + ${YELLOW}階段状バージョニング${NC} に設定"
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
# ── UFW 案内 ───────────────────────────────────────────────
if command -v ufw &>/dev/null && sudo ufw status | grep -q "Status: active"; then
echo -e "${YELLOW}🔥 UFW が有効です。以下でポートを開放してください:${NC}"
echo ""
echo " sudo ufw allow 8384/tcp # Web UI"
echo " sudo ufw allow 22000/tcp # Sync (TCP)"
echo " sudo ufw allow 22000/udp # Sync (QUIC)"
echo " sudo ufw allow 21027/udp # ローカル探索"
echo ""
fi
Webから設定出来ます。

バックアップ先のPCでも導入
バックアップ先となるPCでも同様にSyncthingを導入します。macやWindowsでも対応しているのがポイントですね。クラウドの専用ツールを利用するなら、Windows上で行うと簡単そうです。その後、お互いのDevice IDをGUIの「デバイスを追加」で登録し、同期フォルダを設定するだけです。片方で指定すれば、少し待つともう一方に許可確認のメッセージが表示されます。
そして、immichやNextcloud のデータディレクトリをそのままフォルダとして追加できます。
同期設定のポイント
サーバ側(送信元)
フォルダタイプ:「送信のみ(Send Only)」
- サーバのファイルをバックアップPCへ一方向に同期
- バックアップPC側で誤って削除・変更してもサーバ側には影響しない
- GUIで各フォルダの編集 → 「フォルダタイプ」を
Send Onlyに設定するだけ
バックアップPC側(受信・保管)
フォルダタイプ:「受信のみ(Receive Only)」
- サーバからの変更のみ受け付け、手動で触っても上書きされない安全設計
バージョニング(世代管理)は3種類から選択:
| 種類 | 動作 | 向いている用途 |
|---|---|---|
| ゴミ箱(Trash Can) | 削除・上書き前ファイルを .stversions/ に移動、日数で自動削除 | シンプルに直近N日分だけ保持したい |
| 簡易(Simple) | 世代数を指定(例:5世代)して古いものから自動削除 | バージョン数を固定したい |
| 階段状(Staggered) | 直近は細かく・古いほど間引いて長期保存(最大365日など) | バックアップ用途に最もおすすめ |
階段状バージョニングの保持間隔(デフォルト)
1時間以内 → 毎変更を保持
1日以内 → 1時間ごと
30日以内 → 1日ごと
365日以内 → 1週間ごと
最大保存期間 → 任意設定(例:365日)
推奨構成まとめ
サーバ側 バックアップPC側
┌─────────────────┐ ┌──────────────────────────┐
│ フォルダタイプ │ ──→ │ フォルダタイプ │
│ Send Only │ 同期 │ Receive Only │
│ │ │ │
│ immich data │ │ バージョニング:階段状 │
│ nextcloud data │ │ 最大保存期間:365日 │
│ NoteDiscovery │ │ 保存先:.stversions/ │
└─────────────────┘ └──────────────────────────┘
注意点
- バックアップPC側で
Receive Onlyにしていても、サーバでファイルを削除すると同期されて消える。完全に残したい場合はバージョニングが唯一の保険になります - immichは内部DBも含めてバックアップするなら、immich側で定期的に
pg_dumpして、そのダンプファイルをSyncthingで同期するのが安全です
アプリの特性に合わせた設定など
それぞれのアプリの特性に合わせた除外設定を解説します。
Immich
同期するパス:
/opt/docker/immich/library/library/admin
Immichのlibrary配下は年/月/日のディレクトリ構造でオリジナルファイルが格納されています。サムネイル・エンコード済み動画・機械学習キャッシュは別ディレクトリなのでパスを絞るだけでOKです。
/opt/docker/immich/library/
├── library/admin/ ← ✅ ここだけ同期(オリジナル写真・動画)
├── thumbs/ ← ❌ サムネイル(再生成可能)
├── encoded-video/ ← ❌ トランスコード済み動画(再生成可能)
├── profile/ ← ❌ プロフィール画像
└── upload/ ← ❌ アップロード一時領域
Syncthing の除外パターン(フォルダ編集 → 「無視するパターン」):
(?d).trash
*.tmp
*.part
.DS_Store
/opt/docker/immich/library/library/admin をルートにすれば、それ以外のthumbsなどはそもそもパスに含まれないので除外設定はほぼ不要です。
NoteDiscovery
同期するパス:
/opt/docker/notediscovery/data
/opt/docker/notediscovery/data/
├── notes/ ← ✅ ノート本体
├── attachments/ ← ✅ 添付ファイル
├── *.db ← ⚠️ SQLiteはロック競合に注意(後述)
└── *.db-wal ← ❌ WALファイルは除外推奨
*.db-shm ← ❌ 共有メモリファイルは除外推奨
除外パターン:
*.db-wal
*.db-shm
*.db-journal
*.tmp
*.part
.DS_Store
(?d).trash
⚠️ SQLiteの注意点: アプリ稼働中は
.dbファイルが書き込みロックされます。Syncthingは読み取れても中途半端な状態でコピーされる可能性があるため、DBのバックアップは別途sqlite3 .backupコマンドや定期cronで dump してから同期するのが安全です。
Nextcloud
同期するパス:
/opt/docker/nextcloud/data/data/user/files
/opt/docker/nextcloud/data/data/user/
├── files/ ← ✅ ユーザーファイル本体
├── files_trashbin/ ← ❌ ゴミ箱
├── files_versions/ ← ❌ Nextcloud自身のバージョン履歴(Syncthing側で世代管理するので不要)
├── cache/ ← ❌ キャッシュ
└── thumbnails/ ← ❌ サムネイル
/files だけをフォルダとして追加すれば他は含まれませんが、files 配下に .ocdata などが混入する場合があるので除外パターンを設定:
.ocdata
.htaccess
.ncdata
*.tmp
*.part
uploads.ini
(?d).trash
.DS_Store
もし権限のエラーが出るようなら下記を実行。
# Syncthingを実行しているユーザーをdockerグループ経由で読めるように
sudo chmod o+rx /opt/docker/nextcloud
sudo chmod o+rx /opt/docker/nextcloud/data
sudo chmod o+rx /opt/docker/nextcloud/data/data
sudo chmod o+rx /opt/docker/nextcloud/data/data/user
sudo chmod -R o+rX /opt/docker/nextcloud/data/data/user/files
sudo chmod o+w /opt/docker/nextcloud/data/data/user/files
まとめ表
| アプリ | 同期パス | 主な除外 |
|---|---|---|
| Immich | .../library/admin | パス絞り込みで基本不要 |
| NoteDiscovery | .../notediscovery/data | *.db-wal *.db-shm |
| Nextcloud | .../files | .ocdata *.part |
共通の除外パターン(全フォルダに設定推奨)
(?d).trash
*.tmp
*.part
.DS_Store
~$*
(?d) は「そのディレクトリごと除外」するSyncthing独自の記法です。

おまけ1 – Dockerでインストール
Docker環境でインストールすることも出来ます。その場合、マウントするフォルダを設定するなどの必要があるかもしれません。まずフォルダを作成し、その中にセットアップ用のスクリプトファイルとdocker-compose.ymlを作成します。貼り付ける内容はそれぞれ下記になります。
sudo mkdir /opt/opt/docker/syncthing/ -p
cd /opt/opt/docker/syncthing/
sudo nano setup.sh
sudo nano docker-compose.yml
setup.sh
#!/bin/bash
# =============================================================================
# Syncthing セットアップスクリプト
# 使い方: sudo bash setup.sh
# =============================================================================
set -euo pipefail
INSTALL_DIR="/opt/docker/syncthing"
COMPOSE_FILE="$INSTALL_DIR/docker-compose.yml"
# ── カラー定義 ─────────────────────────────────────────────
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
info() { echo -e "${BLUE}[INFO]${NC} $*"; }
success() { echo -e "${GREEN}[OK]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }
# ── root チェック ──────────────────────────────────────────
[[ $EUID -ne 0 ]] && error "このスクリプトは sudo または root で実行してください。"
# ── インストールディレクトリ作成 ───────────────────────────
info "インストールディレクトリを作成: $INSTALL_DIR"
mkdir -p "$INSTALL_DIR"/{config,data}
# ── docker-compose.yml をコピー ────────────────────────────
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [[ -f "$SCRIPT_DIR/docker-compose.yml" ]]; then
cp "$SCRIPT_DIR/docker-compose.yml" "$COMPOSE_FILE"
success "docker-compose.yml をコピーしました。"
else
error "docker-compose.yml が見つかりません: $SCRIPT_DIR/docker-compose.yml"
fi
# ── パーミッション設定 ─────────────────────────────────────
PUID=1000
PGID=1000
chown -R "$PUID:$PGID" "$INSTALL_DIR/config" "$INSTALL_DIR/data" || true
success "ディレクトリのパーミッションを設定しました。"
# ── コンテナ起動(設定ファイル生成のため一時起動)─────────
info "Syncthing コンテナを一時起動して設定ファイルを生成します..."
cd "$INSTALL_DIR"
docker compose up -d
# 設定ファイルが生成されるまで待機
info "設定ファイルの生成を待機中..."
for i in $(seq 1 30); do
if [[ -f "$INSTALL_DIR/config/config.xml" ]]; then
success "設定ファイルを検出しました。"
break
fi
sleep 2
if [[ $i -eq 30 ]]; then
error "設定ファイルの生成がタイムアウトしました。ログを確認してください: docker logs syncthing"
fi
done
# ── GUI パスワードの設定 ───────────────────────────────────
echo ""
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${YELLOW} Syncthing GUI パスワード設定${NC}"
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
read -rp "GUIのユーザー名を入力してください [デフォルト: admin]: " GUI_USER
GUI_USER="${GUI_USER:-admin}"
while true; do
read -rsp "GUIのパスワードを入力してください: " GUI_PASS
echo ""
read -rsp "パスワードを再入力してください: " GUI_PASS2
echo ""
[[ "$GUI_PASS" == "$GUI_PASS2" ]] && break
warn "パスワードが一致しません。再入力してください。"
done
# bcrypt ハッシュ生成(Python3 を使用)
if command -v python3 &>/dev/null && python3 -c "import bcrypt" 2>/dev/null; then
HASHED_PASS=$(python3 -c "
import bcrypt
password = b'${GUI_PASS}'
hashed = bcrypt.hashpw(password, bcrypt.gensalt())
print(hashed.decode())
")
else
info "bcrypt (Python) が見つかりません。pip でインストールします..."
pip3 install bcrypt -q 2>/dev/null || apt-get install -y python3-bcrypt -q 2>/dev/null || true
HASHED_PASS=$(python3 -c "
import bcrypt
password = b'${GUI_PASS}'
hashed = bcrypt.hashpw(password, bcrypt.gensalt())
print(hashed.decode())
" 2>/dev/null) || true
fi
# config.xml に認証情報を書き込む
CONFIG_FILE="$INSTALL_DIR/config/config.xml"
if [[ -n "${HASHED_PASS:-}" ]]; then
# GUI アドレスを 0.0.0.0 にバインドし、認証を設定
python3 - <<PYEOF
import xml.etree.ElementTree as ET
import sys
tree = ET.parse('$CONFIG_FILE')
root = tree.getroot()
gui = root.find('gui')
if gui is None:
sys.exit(1)
# アドレス設定
addr = gui.find('address')
if addr is None:
addr = ET.SubElement(gui, 'address')
addr.text = '0.0.0.0:8384'
# ユーザー名
user = gui.find('user')
if user is None:
user = ET.SubElement(gui, 'user')
user.text = '$GUI_USER'
# ハッシュ済みパスワード
passwd = gui.find('password')
if passwd is None:
passwd = ET.SubElement(gui, 'password')
passwd.text = '$HASHED_PASS'
# 認証モード
authmode = gui.find('authMode')
if authmode is None:
authmode = ET.SubElement(gui, 'authMode')
authmode.text = 'static'
tree.write('$CONFIG_FILE', encoding='unicode', xml_declaration=True)
print("設定ファイルを更新しました。")
PYEOF
success "GUI認証情報を設定しました(ユーザー: $GUI_USER)"
else
warn "bcrypt が利用できなかったため、パスワードは後でGUI上で設定してください。"
fi
# ── コンテナ再起動 ─────────────────────────────────────────
info "設定を反映するためコンテナを再起動します..."
docker compose restart syncthing
sleep 3
# ── Device ID の取得と表示 ─────────────────────────────────
echo ""
info "Device ID を取得中..."
sleep 5
DEVICE_ID=$(docker exec syncthing syncthing --device-id 2>/dev/null || \
docker logs syncthing 2>&1 | grep -oP 'myID=\K[A-Z0-9-]{63}' | tail -1 || \
echo "(取得できませんでした。起動後にGUIで確認してください)")
# ── 完了メッセージ ─────────────────────────────────────────
HOST_IP=$(hostname -I | awk '{print $1}')
echo ""
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${GREEN} ✅ Syncthing セットアップ完了!${NC}"
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
echo -e " 📡 Web UI: ${BLUE}http://$HOST_IP:8384${NC}"
echo -e " 👤 ユーザー名: ${YELLOW}$GUI_USER${NC}"
echo -e " 🔑 パスワード: (設定済み)"
echo -e " 📁 設定ディレクトリ: ${INSTALL_DIR}/config"
echo -e " 📁 データディレクトリ: ${INSTALL_DIR}/data"
echo ""
echo -e " 🖥️ Device ID:"
echo -e " ${YELLOW}$DEVICE_ID${NC}"
echo ""
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e " 📌 次のステップ:"
echo -e " 1. Web UI にアクセスして動作を確認"
echo -e " 2. バックアップ先PC にも Syncthing を導入"
echo -e " 3. お互いの Device ID を「デバイスを追加」で登録"
echo -e " 4. 同期したいフォルダを「フォルダを追加」で設定"
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
# ── ファイアウォール案内 ───────────────────────────────────
if command -v ufw &>/dev/null && ufw status | grep -q "Status: active"; then
echo -e "${YELLOW}🔥 UFW が有効です。以下のコマンドでポートを開放してください:${NC}"
echo ""
echo " sudo ufw allow 8384/tcp # Web UI"
echo " sudo ufw allow 22000/tcp # Sync (TCP)"
echo " sudo ufw allow 22000/udp # Sync (QUIC)"
echo " sudo ufw allow 21027/udp # ローカル探索"
echo ""
fi
docker-compose.yml
services:
syncthing:
image: syncthing/syncthing:latest
container_name: syncthing
hostname: syncthing-server
restart: unless-stopped
environment:
- PUID=1000
- PGID=1000
volumes:
- ./config:/var/syncthing/config
- ./data:/var/syncthing
ports:
- "8384:8384" # Web UI
- "22000:22000/tcp" # Sync protocol (TCP)
- "22000:22000/udp" # Sync protocol (QUIC)
- "21027:21027/udp" # Local discovery
networks:
- syncthing_net
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:8384/rest/noauth/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
networks:
syncthing_net:
driver: bridge
作成が終了したらセットアップを実行します。
sudo bash setup.sh
セットアップの内容
setup.sh が自動で以下をすべて処理します:
- ディレクトリ作成 —
config/とdata/を自動生成 - コンテナ起動 —
docker compose up -dで初回起動し、config.xmlを自動生成 - GUI認証設定 — ユーザー名とパスワードを対話入力 → bcrypt ハッシュ化して
config.xmlに自己書き込み(シークレットキーの手動生成は不要) - 再起動 & Device ID 表示 — 設定反映後、接続用 Device ID をターミナルに表示
ポート構成
| ポート | 用途 |
|---|---|
8384 | Web UI |
22000/tcp | デバイス間同期(TCP) |
22000/udp | デバイス間同期(QUIC) |
21027/udp | LAN内自動探索 |
UFW が有効な場合は、スクリプト完了時に開放コマンドも案内されます。
マウント箇所を変更したり、rootで動かしたりするには。
sudo nano /opt/docker/syncthing/docker-compose.yml
services:
syncthing:
image: syncthing/syncthing:latest
container_name: syncthing
hostname: syncthing-server
restart: unless-stopped
user: root # ← この行を追加
environment:
- PUID=0
- PGID=0
volumes:
- ./config:/var/syncthing/config
- ./data:/var/syncthing
- /opt/docker/immich/library/library/admin:/sync/immich:ro # ← ro=読み取り専用
- /opt/docker/notediscovery/data:/sync/notediscovery:ro
- /opt/docker/nextcloud/data/data/user/files:/sync/nextcloud:ro
ports:
- "8384:8384"
- "22000:22000/tcp"
- "22000:22000/udp"
- "21027:21027/udp"
networks:
- syncthing_net
networks:
syncthing_net:
driver: bridge
おまけ2 – コピペ1回に
nano install.sh
sudo bash install.sh
install.sh
#!/bin/bash
# =============================================================================
# Syncthing ワンライナーインストールスクリプト
# 使い方: sudo bash install.sh
# =============================================================================
set -euo pipefail
INSTALL_DIR="/opt/docker/syncthing"
# ── カラー定義 ─────────────────────────────────────────────
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
info() { echo -e "${BLUE}[INFO]${NC} $*"; }
success() { echo -e "${GREEN}[OK]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }
# ── root チェック ──────────────────────────────────────────
[[ $EUID -ne 0 ]] && error "sudo または root で実行してください。"
# ── ディレクトリ作成 ───────────────────────────────────────
info "ディレクトリを作成: $INSTALL_DIR"
mkdir -p "$INSTALL_DIR"/{config,data}
# ── docker-compose.yml を生成 ──────────────────────────────
info "docker-compose.yml を生成中..."
cat > "$INSTALL_DIR/docker-compose.yml" << 'EOF'
services:
syncthing:
image: syncthing/syncthing:latest
container_name: syncthing
hostname: syncthing-server
restart: unless-stopped
environment:
- PUID=1000
- PGID=1000
volumes:
- ./config:/var/syncthing/config
- ./data:/var/syncthing
ports:
- "8384:8384" # Web UI
- "22000:22000/tcp" # Sync protocol (TCP)
- "22000:22000/udp" # Sync protocol (QUIC)
- "21027:21027/udp" # Local discovery
networks:
- syncthing_net
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:8384/rest/noauth/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
networks:
syncthing_net:
driver: bridge
EOF
success "docker-compose.yml を生成しました。"
# ── パーミッション設定 ─────────────────────────────────────
chown -R 1000:1000 "$INSTALL_DIR/config" "$INSTALL_DIR/data" || true
# ── コンテナ起動(config.xml 生成のため)─────────────────
info "Syncthing を起動して設定ファイルを生成します..."
cd "$INSTALL_DIR"
docker compose up -d
info "設定ファイルの生成を待機中..."
for i in $(seq 1 30); do
if [[ -f "$INSTALL_DIR/config/config.xml" ]]; then
success "config.xml を検出しました。"
break
fi
sleep 2
[[ $i -eq 30 ]] && error "設定ファイルの生成がタイムアウトしました。\n → docker logs syncthing で確認してください。"
done
# ── GUI 認証情報の入力 ─────────────────────────────────────
echo ""
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${YELLOW} Syncthing GUI パスワード設定${NC}"
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
read -rp "GUIユーザー名 [デフォルト: admin]: " GUI_USER
GUI_USER="${GUI_USER:-admin}"
while true; do
read -rsp "GUIパスワード: " GUI_PASS; echo ""
read -rsp "パスワード(確認): " GUI_PASS2; echo ""
[[ "$GUI_PASS" == "$GUI_PASS2" ]] && break
warn "パスワードが一致しません。再入力してください。"
done
# ── bcrypt ハッシュ生成 ────────────────────────────────────
if ! python3 -c "import bcrypt" 2>/dev/null; then
info "python3-bcrypt をインストールします..."
apt-get install -y python3-bcrypt -q 2>/dev/null || pip3 install bcrypt -q 2>/dev/null || true
fi
HASHED_PASS=$(python3 -c "
import bcrypt, sys
pw = sys.argv[1].encode()
print(bcrypt.hashpw(pw, bcrypt.gensalt()).decode())
" "$GUI_PASS" 2>/dev/null) || { warn "bcrypt が使えませんでした。パスワードはGUIで後から設定してください。"; HASHED_PASS=""; }
# ── config.xml を更新 ─────────────────────────────────────
if [[ -n "${HASHED_PASS:-}" ]]; then
python3 - "$GUI_USER" "$HASHED_PASS" "$INSTALL_DIR/config/config.xml" << 'PYEOF'
import xml.etree.ElementTree as ET, sys
gui_user, hashed_pass, config_path = sys.argv[1], sys.argv[2], sys.argv[3]
ET.register_namespace('', '')
tree = ET.parse(config_path)
root = tree.getroot()
gui = root.find('gui')
def set_or_create(parent, tag, text):
el = parent.find(tag)
if el is None:
el = ET.SubElement(parent, tag)
el.text = text
set_or_create(gui, 'address', '0.0.0.0:8384')
set_or_create(gui, 'user', gui_user)
set_or_create(gui, 'password', hashed_pass)
set_or_create(gui, 'authMode', 'static')
tree.write(config_path, encoding='unicode', xml_declaration=True)
print("config.xml を更新しました。")
PYEOF
success "GUI認証情報を設定しました(ユーザー: $GUI_USER)"
fi
# ── コンテナ再起動 ─────────────────────────────────────────
info "設定を反映するためコンテナを再起動します..."
docker compose restart syncthing
sleep 5
# ── Device ID 取得 ─────────────────────────────────────────
DEVICE_ID=$(docker exec syncthing syncthing --device-id 2>/dev/null \
|| grep -oP '(?<=device id=")[A-Z0-9-]{63}' "$INSTALL_DIR/config/config.xml" 2>/dev/null \
|| echo "(GUIの「情報」から確認してください)")
# ── 完了メッセージ ─────────────────────────────────────────
HOST_IP=$(hostname -I | awk '{print $1}')
echo ""
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${GREEN} ✅ Syncthing セットアップ完了!${NC}"
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
echo -e " 📡 Web UI : ${BLUE}http://$HOST_IP:8384${NC}"
echo -e " 👤 ユーザー名 : ${YELLOW}$GUI_USER${NC}"
echo -e " 📁 インストール先 : $INSTALL_DIR"
echo ""
echo -e " 🖥️ Device ID(バックアップPCへの接続時に使用):"
echo -e " ${YELLOW}$DEVICE_ID${NC}"
echo ""
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e " 📌 次のステップ:"
echo -e " 1. Web UI にアクセスして動作確認"
echo -e " 2. 各フォルダのタイプを ${YELLOW}Send Only${NC} に設定"
echo -e " 3. バックアップPC にも Syncthing を導入"
echo -e " 4. お互いの Device ID を「デバイスを追加」で登録"
echo -e " 5. バックアップPC側フォルダを ${YELLOW}Receive Only${NC} + ${YELLOW}階段状バージョニング${NC} に設定"
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
# ── UFW 案内 ───────────────────────────────────────────────
if command -v ufw &>/dev/null && ufw status | grep -q "Status: active"; then
echo -e "${YELLOW}🔥 UFW が有効です。以下でポートを開放してください:${NC}"
echo ""
echo " sudo ufw allow 8384/tcp # Web UI"
echo " sudo ufw allow 22000/tcp # Sync (TCP)"
echo " sudo ufw allow 22000/udp # Sync (QUIC)"
echo " sudo ufw allow 21027/udp # ローカル探索"
echo ""
fi
