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 -