ksaitoの日記

日々試したことの覚え書き

コンテナとファイルのやりとり

docker cpコマンドでも良いのですが、ディレクトリごと出し入れしたい場合には、tarコマンドを使った方が便利です。

tar-Cオプオションは、tarを実行する前に指定されたディレクトリに移動します。 tar -C /tmp -cf - logは、(cd /tmp; tar cf - log)と同じ意味になりますがdockerコマンドで実行した場合、tar-Cオプションを使ったほがシンプルにかけます。

これを使って、コンテナとファイルをやりとりするパターンを考えます。

コンテナからホスト

ubuntuのログディレクトリを丸ごと、取り出したい場合は、次のようにします。

$ find
.
$ docker run --rm ubuntu:17.04 tar -C /var -cf - log | tar xf -
$ find
.
./log
./log/wtmp
./log/faillog
./log/dpkg.log
./log/alternatives.log
./log/apt
./log/apt/history.log
./log/apt/eipp.log.xz
./log/bootstrap.log
./log/btmp
./log/lastlog
$ 

すでに起動しているコンテナであればdocker execを使います。

$ docker exec コンテナ名 tar -C /var -cf - log | tar xf -

ホストからコンテナ

ホストのtarの結果をリダイレクトしてdocker execに処理させます。 -iオプションを忘れると標準入力が割り当てられず、ずーっと入力待ちになってしまいます。

$ tar cf - log | docker exec -i target tar -C /tmp -xf -

コンテナからコンテナへ

上記の2つを応用して、コンテナ間で一時ファイルを作らずにデータをやり取りできます。

srcコンテナの/var/logをtargetコンテナの/tmpディレクトリにコピーするには次のようにします。

$ docker exec target ls /tmp
$ docker exec src tar -C /var -cf - log | docker exec -i target tar -C /tmp -xf -
$ docker exec target ls /tmp
log
$

おまけ

tar-Cオプションが使えない場合、下記のようにすると同じことができます。

$ docker run --rm ubuntu:17.04 bash -c "(cd /var; tar cf - log)" | tar xf -