Featured image of post Syncthing:本当の意味で無料でプライバシーも守れる Dropbox 代替

Syncthing:本当の意味で無料でプライバシーも守れる Dropbox 代替

無料で容量無制限のファイル同期ソリューションをお探しですか?Syncthing で Dropbox を置き換えた方法を紹介します——オープンソース、P2P 同期でデータは自分のデバイスだけに。プライバシーを自分で管理できる環境の作り方。Docker と ZeroTier の設定ガイド付き。

前回の記事 「Karpathy の LLM-Wiki メソドロジー:Obsidian での実践」 で、データ同期の話に少し触れた。LLM-Wiki のデータ層はマルチデバイス同期が前提になっていて、それを支えているのが Syncthing。当時は「ZeroTier で組んで Syncthing で同期」と一言で済ませた。今日は一から丁寧に全部書く。

なぜ Syncthing か

いくつかの同期方法を試したけれど、どれもしっくりこなかった:

クラウド型のファイル共有サービス——プライバシーがどうにも引っかかるし、大きいファイルを上げたりダウンロードしたりする時間もバカにならない。iCloud も容量にお金がかかるし、Markdown の同期時に .icloud 形式のゴミファイルが残ったりすることがある。Git はコードには良いけれど、Obsidian の添付ファイルや画像を突っ込むと、毎回コミットが膨大になる。

そこで Syncthing に出会った。

やっていることはシンプル:自分のマシン同士でフォルダを同期するだけ。P2P 通信でサーバーは通さない。オープンソース、無料、容量制限なし。データは自分のデバイスにしか置かない。

僕にとって大事なのは二つだけ。お金をかけないことと、他の誰にも見られないこと。

僕の環境

デバイスは3台:

  • MacBook Pro(主力機) —— 日常の開発、Obsidian、LLM-Wiki。持ち歩く方のマシン。
  • MacBook Pro(予備機) —— 自宅用に置いてある。同じディレクトリ構成。
  • Linux サーバー(Debian) —— 24時間稼働、Docker コンテナ内に Syncthing を配置。

3台の間に ZeroTier で仮想 LAN を張る。VPS を借りて Moon ノードを自分で立てておくと、この小さなネットワークの安定感が全然違う。どちらの Mac が職場のネットワークにあろうが自宅の Wi-Fi にいようが、確実にサーバーと繋がる。

同期の関係は「3台がお互いに全接続」ではなく、直列的なやり方にしている:

まず主力 Mac と Linux サーバー間で双方向共有を設定しておく。そのうえで、Linux サーバーから同じ知識ベースフォルダを予備 Mac にも共有する。主力 Mac での変更はまずサーバーに同期され、そこから予備 Mac へプッシュされる。逆もしかり——予備 Mac の変更はサーバーに集まり、そこから主力 Mac に戻ってくる。

Linux サーバーが知識ベースのハブ役。2台の Mac でそれぞれ書かれた Obsidian ノートや LLM-Wiki データが、最終的にサーバー上の同じ知識ベースに集約される。

重要な使い方ルール

セットアップ手順に入る前に、LLM-Wiki の運用で一度ハマった話をしておく:

LLM 複数台が同時に知識ベースのファイルを編集しないこと。

LLM が /my-wiki-src/my-wiki-talk のようなワークフローを実行するとき、数十ファイルにわたってページを一括更新・追加・削除することがある。2台の Mac が同時にワークフローを走らせると、両方が同じフォルダ内のファイルを書き換えることになり、Syncthing が競合を検出して大量の .sync-conflict ファイルを生成してしまう。

僕のやり方:LLM ワークフローを走らせるのは 1台のマシンだけ。もう1台は閲覧と手動編集に留める。両方で AI ワークフローを回したいなら、順番を守る——片方が終わって同期が完了してから、もう片方を走らせる。

セットアップ手順

1. ZeroTier で組む

まずネットワークから。ZeroTier で離れた3台のマシンを同じ仮想 LAN に放り込む。物理的なネットワークの境目がなくなるので、どこにいてもマシン同士が直接やりとりできる。

1
2
3
4
5
6
7
8
# Mac(2台とも)
brew install zerotier-one

# Linux サーバー(Debian)
sudo apt install zerotier-one

# 3台とも実行
sudo zerotier-cli join <ネットワークID>

同じネットワークに参加すると、ZeroTier が各マシンに仮想 IP を振ってくれる。10.147.20.x のようなアドレス。お互いに ping を打って通れば OK。

Moon ノードは VPS 上に自分で構築した。ZeroTier 公式の中継サーバーは遅いことがあるので、自分の Moon ノードを経由する形にしたら、ネットワークを切り替えるときの接続安定性がかなり上がっている。Moon ノードの作り方はネットにたくさんあるので割愛。

2. Syncthing のインストール

ネットワークが通ったら Syncthing を入れる。

Mac(Homebrew)

1
brew install syncthing

GUI 版が良ければ brew install --cask syncthing。僕はコマンドライン版で十分で、ローカルの http://127.0.0.1:8384 をブラウザで開けば管理画面に入れる。

Linux サーバー(Docker)

1
2
3
4
5
6
7
8
docker run -d \
  --name syncthing \
  --hostname syncthing \
  -p 8384:8384 -p 22000:22000/tcp -p 22000:22000/udp -p 21027:21027/udp \
  -v /srv/syncthing/config:/var/syncthing/config \
  -v /srv/syncthing/data:/var/syncthing \
  --restart unless-stopped \
  syncthing/syncthing:latest

パスは自分の環境に合わせて変える。config ボリュームをマウントしておけば、あとでイメージをアップグレードしてコンテナを作り直しても設定が消えない。--restart unless-stopped が入っておけば、サーバーの再起動後も勝手に立ち上がる。

コンテナが起動したら http://ZeroTier仮想IP:8384 で Web の管理画面に入れる。

3. お互いをデバイスとして追加する

ここが意外とハマりポイントだったりする。

Syncthing にはローカルネットワーク内で自動的にデバイスを発見してくれる機能があって、Web GUI の下部に「新しいデバイスを検出しました」というポップアップが出る。そのままクリックして追加すればいい——デバイス ID を手入力する手間が省ける。

ただし大事な点が一つある:自動検出したあとにアドレスを確認すること

デフォルトで検出されるアドレスはローカルの LAN IP、つまり 192.168.x.x になっていることが多い。ZeroTier の仮想ネットワーク経由で通信させたい場合は、ここを ZeroTier の仮想 IP に手動で書き換える。tcp://10.147.20.x:22000 のような形式。ローカルの IP のままにしておくと、Mac のネットワーク環境が変わった(会社から家に帰った、など)ときに接続が途切れてしまう。

両方で追加作業が必要。Mac で発見ポップアップから追加、サーバーでも逆に Mac の発見ポップアップから追加。双方向で承認して初めて接続が確立される。

デバイス追加画面

4. フォルダの共有

ここには順番がある:まず主力 Mac とサーバー間で共有を設定し、次にサーバーから予備 Mac へ共有する。

ステップ1:主力 Mac → サーバー

主力 Mac の Web GUI で「フォルダ」→「フォルダを追加」。my-wiki のパスを選び、ラベル名をつけ、「共有」の欄で Linux サーバーにチェックを入れる。

「暗号化」には必ずチェックを入れる。 有効にすると、サーバー側はファイル名も中身も暗号化された状態しか見えない。復号鍵は共有を開始した Mac 側だけが持っている。万が一サーバーが乗っ取られたとしても、中身は抜かれない。

サーバー側は共有リクエストが届くので、承認して保存先のローカルパスを選べばいい。

ステップ2:サーバー → 予備 Mac

サーバーの Web GUI で、同じフォルダに対して予備 Mac のデバイスを追加選択する。予備 Mac 側に共有リクエストが届くので、承認してローカルの保存先パスを選べばいい。

これで2台の Mac のデータがサーバー上の同じ知識ベースに集約される。主力 Mac で編集すればサーバーが受け取り、予備 Mac にプッシュする。予備 Mac で編集すればサーバーが受け取り、主力 Mac に戻ってくる。サーバーが仲介の糸役だ。

フォルダ共有設定

.stignore ファイル

同期ディレクトリのルートに .stignore を置いておくと、Syncthing に「このファイルは同期しなくていいよ」と伝えられる。

最初は設定せずに裸で走らせていた。しばらくそのままでも特に問題はなかったが、使っているうちに明らかに同期しなくていいファイルがあることに気づいて、以下のように書いた:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
// Obsidian のローカル状態。デバイスごとに独立している
.obsidian/workspace
.obsidian/workspace-mobile.json
.obsidian/app.json
.obsidian/appearance.json

// macOS のシステムファイル
.DS_Store
.AppleDouble
.LSOverride
._*

// 一時ファイルとコードの依存関係
*.tmp
*.log
node_modules/
.git/

// Syncthing 自身のもの
.stfolder

コメントは // で書く。ワイルドカードが使える。変更は即時反映されるので再起動不要。

僕のアドバイスはとりあえず動かしてみること。走らせてみて同期してほしくないファイルが見つかったら、あとから追記すればいい。

セキュリティ

Syncthing の Web GUI はデフォルトでパスワードがない。ZeroTier の仮想 IP にバインドしているとはいえ、同じネットワークセグメント内の他のマシンからはそのままアクセスできてしまう。最低限これだけはやる:

Web GUI → Actions → Settings → GUI → 「Enable GUI Authentication」にチェック → ユーザー名とパスワードを設定。

10 秒で終わる話だけど、意外と忘れがち。

よくあるトラブル

問題 確認ポイント
デバイスが繋がらない ZeroTier の IP で ping は通る?ポート 22000 はファイアウォールが空いている?
同期が止まっている GUI の「Recent Changes」を見る。大きいファイルの転送中かもしれない
.sync-conflict ファイルが大量に出ている 両方で同じファイルを編集した。どっちを残すか手動で判断して残りを消すだけ。LLM ワークフロー(/my-wiki-src/my-wiki-talk)を走らせる場合は、両方の Mac で同時に実行しないこと。片方が終わって同期が完了してから、もう片方を走らせる
再起動後に繋がらない ZeroTier の IP が変わっていない?ネットワーク設定で静的 IP を振っておく
Web GUI が開かない Mac: brew services restart syncthing。Docker: docker restart syncthing

おわり

全部セットアップしてからの一番の変化:「このファイルどっちにあったっけ」を考えなくてよくなったこと

主力 Mac で編集したものがサーバーに届き、そこから予備 Mac に届く。予備 Mac で編集したものがサーバーに集まり、そこから主力 Mac に戻ってくる。どちらの Mac で Obsidian を開いても、同じ知識ベースが見える。ZeroTier がネットワークを開通させ、Syncthing がファイルを運ぶ。どっちのマシンに何が置いてあるか、外の人には見えない。

一つだけ注意:LLM のワークフローを走らせるときは、片方のマシンだけでやる。両方で AI が同時に知識ベースを並列で書き換えると、.sync-conflict ファイルの山が待っている。

同期の手段はいろいろ試したけれど、Syncthing がいちばん楽だった。お金もかからない、容量を気にしなくていい、プライバシーポリシーを読む必要もない。一度セットアップすればあとは存在を忘れられる——良いインフラってそういうものだと思う。