先日、リモートで動作しているdockerホスト上のコンテナから手元にファイルをコピーしようとした時のことです。
docker cp
コマンドはdockerホストとコンテナ間の転送しか使えないので、こういう場合はcat
コマンドやtar
コマンドを利用してパイプで繋ぐことになります。
今回はディレクトリを丸ごと転送したかったので、こんなコマンドを実行しました。
docker -H $DOCKER_HOST exec -it $CONTAINER tar -cf - -C $PARENT $DIRECTORY | tar -xf -
なお、リモートのdockerホストはUbuntuで、クライアントはWindowsでした。
勘のいい方はもう分かったと思いますが――というかタイトルに書いてあるので勿体ぶっても意味がないのですが、これはうまく行きません。
何故かと言うと、Ubuntu側のターミナルの改行コードはLF
で、Windows側はCRLF
なので、-t
オプションを付けてしまうとdockerクライアントがLF
をCRLF
に変換してしまうからです。
したがって、LFを含むファイルをちゃんと転送するには、
docker -H $DOCKER_HOST exec -i $CONTAINER tar -cf - -C $PARENT $DIRECTORY | tar -xf -
としなければいけません。
気づいてしまえば当たり前のことなのですが、だいぶハマったので自戒を込めて記事にしました。
みなさんはこんな間抜けなミスをしないようご注意ください。
Usage: exec [options] [-e KEY=VAL...] SERVICE COMMAND [ARGS...]
Options:
-d, --detach Detached mode: Run command in the background.
--privileged Give extended privileges to the process.
-u, --user USER Run the command as this user.
-T Disable pseudo-tty allocation. By default `docker-compose exec`
allocates a TTY.
--index=index index of the container if there are multiple
instances of a service [default: 1]
-e, --env KEY=VAL Set environment variables (can be used multiple times,
not supported in API < 1.25)
-w, --workdir DIR Path to workdir directory for this command.