2018年1月6日土曜日

docker でコンテナ内にあるファイルをローカルにコピーするテクニック

概要

docker で起動したコンテナ内にあるファイルをコピーしたいケースはあると思います
いくつか方法があるのでユースケースを交えて紹介したいと思います

環境

  • macOS X 10.13.2
  • docker 17.12.0-ce-rc4

すでにコンテナが起動しているとき

これは簡単です
docker cp コマンドを使えば OK です
例えば nginx のイメージを使った場合は

  • docker run -d nginx
  • docker cp gracious_kepler:/root/.bashrc .

とすると nginx コンテナ内のファイルがコピーできます

run はできるがすぐにコンテナ停止してしまう場合

docker cp は残念ながら停止中のコンテナには使えません
例えば alpine イメージなどは普通に run しただけではすぐに停止してしまいます
そんな場合はコンテナをずっと起動させる工夫が必要です

  • docker run --rm alpine /bin/sh -c "while true; do date; sleep 1; done"

こうすることで docker ps が使えるようになるのでコンテナからファイルをコピーすることができます

ビルドした際にファイルをコピーする

例えば Dockerfile を使ってビルドする際にビルド後の成果物はイメージ内にあるというケースはあると思います
その場合は上記のように一旦 while で起動してから docker cp しても良いですが面倒くさいです

なので -v オプションでマウントすることでビルド後に成果物をローカルホストにコピーすることができます

  • vim Dockerfile
FROM alpine

RUN echo "created on a container" > /home/test

ファイルを作成しているだけのイメージです
これをビルドして

  • docker build -t hoge .

run するときにローカルホストをマウントしてそのマウントした先にファイルをコピーすることでローカルホストに同じファイルを転送することができます

  • docker run --rm -v $(pwd):/tmp hoge /bin/sh -c "cp /home/test /tmp/test2"

この方法だとわざわざコンテナを起動しておく必要がなくなるので 1 手順少なくなります
ただ、コンテナ内でコピーするべきファイルのパスを知っておく必要があるのとマウントするパスとコピーするパスは別にする必要があるので注意してください

上記の場合はローカルホストのカレントディレクトリ上に test2 というコンテナ内でコピーされたファイルがローカルにも残ります

最後に

コンテナにあるファイルをローカルにコピーする方法を紹介しました
docker を使ってコードをビルドする場合にはコンテナに残った成果物をホスト側に持ってくる必要があるので知っておくと便利な方法だと思います

0 件のコメント:

コメントを投稿