DockerでSyncthingを構築:HomeLab向けの分散型P2Pファイル同期

HomeLab tutorial - IT technology blog
HomeLab tutorial - IT technology blog

深夜2時、高負荷なストレージスクラブ処理中にメインNASがフリーズし、そこに保存されていたAnsibleプレイブックやSSHキーが今すぐ必要になった――そんな状況を想像してみてください。すべてのシステムが単一のハブに依存していると、一度のハードウェア障害でワークフロー全体が停止してしまいます。ピアツーピア(P2P)同期はこの問題を根本から解決します。各アクティブなエンドポイントにローカルコピーを保持することで、プライマリサーバーが停止した場合でもファイルへのアクセスを継続できます。

集中型ストレージ、クラウドドライブ、P2P同期の比較

Composeファイルを作成する前に、これら3つのストレージモデルがネットワーク分断やホスト障害にどのように対処するかを確認しましょう。

項目 集中型NAS(NFS / SMB / Nextcloud) 商用クラウド(Google Drive / Dropbox) 分散型P2P(Syncthing)
トポロジー クライアント・サーバー型(単一ハブ) 集中型サードパーティクラウド 分散型メッシュ(ノード間直接通信)
LANスループット 回線速度(1 Gbps / 10 Gbps) ISPの上り帯域に制限(多くは20〜50 Mbps) 回線速度(1GbE経由で110+ MB/s、TLS暗号化)
オフライン耐性 メインNASが停止すると利用不可(ゼロ) インターネット接続がないと利用不可(ゼロ) 高:接続中のLANデバイス間で同期を継続
データプライバシー セルフホスト型で完全なプライベート リモートの企業インフラに保存 エンドツーエンドTLS暗号化;データは自前のディスク内に保持
メモリ使用量 中〜大(PHP/DBスタックで500MB〜2GB以上) サーバー側は極小(専用デスクトップクライアント) 極めて軽量(Go言語製で通常50MB〜120MB RAM)

セルフホスト環境におけるメリットとデメリット

Syncthingは継続的なブロックレベルの同期エンジンであり、アーカイブ用のバックアップツールではありません。この違いを理解しておくことで、最適な用途で性能を最大限に引き出すことができます。

メリット

  • ストレージ課金なし:同期容量の制限はなく、各ノードで利用可能なディスク空き容量にのみ依存します。
  • 高速なローカル検出:同一サブネット上のノードはIPv4/IPv6ブロードキャストパケット(ポート21027/UDP)を利用し、WANリレーを経由することなく数秒で直接リンクを確立します。
  • ブロックレベルの差分更新:5GBの仮想ディスクイメージ内の数行を変更した場合でも、変更された128KB〜4MBのチャンクのみを転送します。
  • 組み込みのバージョン管理:段階的(Staggered)、ゴミ箱(Trash Can)、シンプル(Simple)の各バージョン管理ポリシーにより、誤ったファイル上書きやランサムウェアからディレクトリを保護します。

トレードオフ・注意点

  • Webベースのファイルエクスプローラー非搭載:SyncthingはRawファイルをディスクへ直接同期します。組み込みのドキュメントエディタやメディアプレーヤーは含まれていません。
  • ノードの同時稼働が必要:データはピア間で直接転送されます。転送を完了するには少なくとも2台のデバイスが同時にオンラインである必要があるため、常時稼働のミニPCやサーバーをアンカーノードとして配置するのが理想的です。
  • カーネルファイル監視数の枯渇:4万ファイル規模のnode_modulesディレクトリなど、大規模なフォルダ階層を追跡すると、Linuxのデフォルトのファイル監視ハンドル数を急速に消費する恐れがあります。

推奨ネットワークおよびポート構成

標準的なHomeLab構成では、低消費電力サーバーやNAS上でSyncthingコンテナを常時稼働させます。ノートPC、デスクトップ、モバイルデバイスをこのノードとペアリングすることで、常に利用可能な同期ブリッジとして機能させます。

高速なLAN内検出とネイティブなQUICプロトコルのパフォーマンスを確保するため、以下のコンテナポートを直接公開します:

  • 8384/tcp:Web管理GUI。
  • 22000/tcp & 22000/udp:コアTLS同期トラフィックおよびQUICデータ転送。
  • 21027/udp:ローカルブロードキャストおよびマルチキャスト検出。

Docker Composeによるデプロイ手順

ステップ1:権限の確認とストレージパスの作成

まず現在のユーザー権限を確認します。次に、設定状態および同期共有用の専用フォルダを作成します:

# 現在のアクティブなユーザーIDとグループIDを確認
id

# 永続ストレージディレクトリを作成
sudo mkdir -p /srv/syncthing/config /srv/syncthing/data
sudo chown -R $USER:$USER /srv/syncthing
chmod -R 755 /srv/syncthing

ステップ2:Docker Compose設定ファイルの作成

以下の設定を/srv/syncthing/docker-compose.ymlとして保存します:

services:
  syncthing:
    image: syncthing/syncthing:latest
    container_name: syncthing
    hostname: homelab-syncthing-node01
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
    volumes:
      - /srv/syncthing/config:/var/syncthing/config
      - /srv/syncthing/data:/var/syncthing/Sync
    ports:
      - "8384:8384"        # Web管理GUI
      - "22000:22000/tcp"  # TCP同期トラフィック
      - "22000:22000/udp"  # QUIC同期トラフィック
      - "21027:21027/udp"  # ローカル検出
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-fk", "http://localhost:8384/rest/noauth/health"]
      interval: 30s
      timeout: 10s
      retries: 3

ステップ3:カーネルのinotify上限の調整と起動

Linuxのデフォルトのinotify上限(多くは8,192監視数)は、大規模なコードベースにおいて同期遅延の原因となります。コンテナを起動する前にこの上限を引き上げます:

# inotifyのユーザー監視数上限を204,800に拡張
echo "fs.inotify.max_user_watches=204800" | sudo tee -a /etc/sysctl.d/90-syncthing.conf
sudo sysctl --system

# バックグラウンド(デタッチドモード)でSyncthingを起動
cd /srv/syncthing
docker compose up -d

# 起動ログをリアルタイムで確認
docker compose logs -f syncthing

ステップ4:初期セキュリティ設定とペアリング

  1. ブラウザを開き、http://<YOUR_SERVER_IP>:8384にアクセスします。
  2. Actions > Settings > GUIに移動します。管理者ユーザー名を入力し、16文字以上の強力なパスワードを設定して、Use HTTPS for GUIにチェックを入れます。
  3. Actions > Show IDをクリックし、ノードの56文字の暗号化デバイスフィンガープリント(デバイスID)をコピーします。
  4. ノートPC側のSyncthingを開き、Add Remote DeviceをクリックしてサーバーのIDを貼り付け、双方の画面でハンドシェイクプロンプトを承認します。
  5. 共有フォルダの設定でStaggered Versioning(段階的バージョン管理)を有効にします。これにより、初日は1時間ごと、1か月間は日次、それ以降は週次のスナップショットが自動的に保持されます。

ステップ5:トラブルシューティング用コマンド

# ピアが直接LAN接続ではなく「Relayed(中継)」と表示される場合:
# ファイアウォールルールで検出ポートおよび同期ポートが許可されていることを確認
sudo ufw allow 22000/tcp
sudo ufw allow 22000/udp
sudo ufw allow 21027/udp
sudo ufw reload

# フォルダ同期のパーミッションエラーが発生した場合:
# ホストディレクトリの所有権がPUID/PGID(1000:1000)と一致しているか確認
ls -ld /srv/syncthing/data
Share: