Docker VolumeとBittorrent Syncを組み合わせるとどうなるか

複数のデーターセンターにあるシステムのデータを同期する作業をコンテナ化しようと思って調べてみたところ、Bittorrent Syncについての記事を見つけました。基本的にはCenturyLink LabsのこのDockerfile([CenturyLinkLabs/ctlc-docker-btsync](https://github.com/CenturyLinkLabs/ctlc-docker-btsync))の使い方の説明になってしまいますが、この手順を試してみることで、Docker Volumeの使いどころのようなものがわかった気がします。

> **Note:** Bittorrent Syncはオープンソースではないですし、プロダクションで使うかについては[こういうブログ](http://2014.hackitoergosum.org/bittorrentsync-security-privacy-analysis-hackito-session-results/)に目を通してみてから検討してください。)

# `Dockerfile`とスクリプト`start-btsync`を作る

本当のところは`docker pull ctlc/btsync`としたいところなのですが、Bittorrent Syncのバージョンが古くて、[僕のプル・リクエスト](https://github.com/CenturyLinkLabs/ctlc-docker-btsync/pull/2)をマージしてくれるかちょっとわからないので、手元でビルドする手順で説明します。

まずは`Dockerfile`:

```
FROM ubuntu:14.04
RUN apt-get update && apt-get install -y curl && apt-get clean && \
    curl -o /usr/bin/btsync.tar.gz \
    https://download-cdn.getsync.com/stable/linux-x64/BitTorrent-Sync_x64.tar.gz && \
    cd /usr/bin && tar -xzvf btsync.tar.gz && rm btsync.tar.gz && \
    mkdir -p /btsync/.sync && \
    mkdir -p /var/run/btsync && \
    mkdir -p /data

ADD start-btsync /usr/bin/start-btsync
RUN chmod +x /usr/bin/start-btsync

VOLUME ["/data"]

EXPOSE 8888
EXPOSE 55555
ENTRYPOINT ["start-btsync"]
```

次に`start-btsync`:

```
#!/bin/bash
SECRET="${@}"
: ${SECRET:=`btsync --generate-secret`}

echo "Starting btsync with secret: $SECRET"

echo "{
    \"device_name\": \"Sync Server\",
    \"listening_port\": 55555,
    \"storage_path\": \"/btsync/.sync\",
    \"pid_file\": \"/var/run/btsync/btsync.pid\",
    \"check_for_updates\": false,
    \"use_upnp\": false,
    \"download_limit\": 0,
    \"upload_limit\": 0,
    \"shared_folders\": [
        {
            \"secret\": \"$SECRET\",
            \"dir\": \"/data\",
            \"use_relay_server\": true,
            \"use_tracker\": true,
            \"use_dht\": false,
            \"search_lan\": true,
            \"use_sync_trash\": false
        }
    ]
}" > /btsync/btsync.conf

btsync --config /btsync/btsync.conf --nodaemon
```

# Sync用のコンテナと通常のコンテナのセットを作る

```
#Bittorrent Syncのコンテナ(btsync1)を作る
$ docker build -t btsync .
$ docker run -d --name btsync1 btsync

# シークレットを確認する
$ docker exec -it btsync1 cat /btsync/btsync.conf

# btsync1のボリュームをアタッチして通常のコンテナを起動する
$ docker run -it --volumes-from btsync1 --name node1 ubuntu bash

# 確認のためにhello_worldというファイルを作っておく
root@bcf30af989c7:/# ls /data/
root@bcf30af989c7:/# touch /data/hello_world
root@bcf30af989c7:/# ls /data/
hello_world
```

# Sync先のホストにも同じようにコンテナのセットを作る

```
# btsync1のコンフィグにあったシークレットを指定してBittorrent Syncのコンテナ(btsync2)を作る
$ docker build -t btsync .
$ docker run -d --name btsync2 btsync A4YSBUHIDSWXJYNXGSFZUJIDCYNYC2T7A

# コンフィグを確認する
$ docker exec -it btsync2 cat /btsync/btsync.conf

# hello_worldがあることを確認する (* ファイルがSyncされるまで
# しばらく待たないといけないこともあります)
$ docker run -it --volumes-from btsync2 --name node2 ubuntu bash
root@3cb1888eb8ae:/# ls /data/
hello_world
```
> **Note:** 最初のSyncにはなぜか時間がかかることがありますが、最初のSyncが済むとそれ以降のファイルの更新や追加へのレスポンスは速やかです。

# 所見

Bittorrent Syncを別のコンテナとして切り分けてVolumeとしてアタッチするというやり方がDocker的でとても面白いです。同じ考え方でrsync、[Unison](https://www.cis.upenn.edu/~bcpierce/unison/)、[Syncthing](https://syncthing.net/)を別のコンテナにするのも良さそうですね。

## 参考にしたリンク
- [Persistent Distributed Filesystems in Docker without NFS or Gluster](https://www.ctl.io/developers/blog/post/persistent-distributed-filesystems-in-docker-without-nfs-or-gluster/)