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 -