目的
docker cp
コマンドの挙動について理解する。
結論
ディレクトリのコピー
例えば、コンテナ内の Go 環境をホストマシンにコピーしたいときを考える。
※ MyApp-web-1
はコンテナ名です。
(1) 推奨されるコマンド
$ sudo docker cp MyApp-web-1:/usr/local/go/. ~/usr/local/go/
(2) 少し危険なコマンド
$ sudo docker cp MyApp-web-1:/usr/local/go/ ~/usr/local/
(3) 非常に危険なコマンド
$ sudo docker cp MyApp-web-1:/usr/local/go/ ~/usr/local/go/
ファイルのコピー
ファイルのコピーは単純。
$ sudo docker cp MyApp-web-1:/MyApp/web/go.sum web/go.sum
説明
ディレクトリのコピー
公式ドキュメントを確認
公式ドキュメントはこちら
$ docker cp [オプション] CONTAINER:SRC_PATH DEST_PATH
具体例
(1) 推奨されるコマンド
$ sudo docker cp MyApp-web-1:/usr/local/go/. ~/usr/local/go/
公式ドキュメントを見ると、この方法であれば、常に、コピー元ディレクトリ(MyApp-web-1:/usr/local/go/
)の中身が、コピー先のディレクトリの中に展開される。
前提として、コピー先の親ディレクトリ(~/usr/local/
)が存在しなければエラーを吐いてくれる。
(2) 少し危険なコマンド
$ sudo docker cp MyApp-web-1:/usr/local/go/ ~/usr/local/
公式ドキュメントを見ると、この方法を使うと、コピー先のディレクトリ(~/usr/local/
)が存在する場合に限り、意図通りのコピーが実施される。
このコマンドが少し危険な理由は、コピー先のディレクトリ(~/usr/local/
)が存在しないで、コピー先の親ディレクトリ(~/usr/
)のみが存在する場合、コピー先のディレクトリ(~/usr/local/
)の中に、コピー元ディレクトリ(MyApp-web-1:/usr/local/go/
)の中身が展開されてしまうからである。
このコマンドの前に、常に、$ mkdir -p ~/usr/local/
を実行するようにすれば問題ない。
(3) 非常に危険なコマンド
$ sudo docker cp MyApp-web-1:/usr/local/go/ ~/usr/local/go/
コピー先のディレクトリ(~/usr/local/go/
)が存在せずに、コピー先の親ディレクトリ(~/usr/local/
)が存在する場合は、意図通りの挙動となる。
しかし、コピー先のディレクトリ(~/usr/local/go/
)が存在する場合は、コピー元のディレクトリ(MyApp-web-1:/usr/local/go/
)が、コピー先のディレクトリ(~/usr/local/go/
)にコピーされてしまう。
コピー先のディレクトリ(~/usr/local/go/
)が存在せず、コピー先の親ディレクトリ(~/usr/local/
)のみが存在する状態で、上記のコマンドを二回実行したら、一回目は意図通りの挙動だが、二回目は~/usr/local/go/go/
ディレクトリを作成してしまう。
おまけ
Dockerfile の COPY
の挙動(リンクはこちら)とは異なるので注意。
参考