ゆるふわDocker部: リモートDockerコンテナとのファイル転送で-tオプションを使ってはいけない

先日、リモートで動作している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クライアントがLFCRLFに変換してしまうからです。

したがって、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.

関連記事

【ゆるふわDocker部】気軽にDockerを使うのもいいじゃない

【ゆるふわDocker部】任意バージョンのPostgreSQLコマンドを実行して外部DBに接続する

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

yoshi

平成元年生まれのC++er。Qiitaで誰が得するのか分からないような重箱の隅をつつく黒魔術を書いていたが、2016年8月からBPSに入社。

yoshiの書いた記事

開発
echoコマンドをC++に移植する

2018年01月18日

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ