はじめに
業務でDockerを使う場面が多く、コンテナとホスト間でファイルをやり取りしたいケースは意外と頻繁に発生します。ボリュームマウントを最初から設定していれば解決できますが、設計段階で想定していなかったファイルを後から取り出したい場合などに docker cp が役立ちます。
今回は docker cp の使い方と、他の方法では対応しにくい実務上のシナリオをまとめます。
docker cpとは
docker cp はホストとコンテナ間でファイルやディレクトリをコピーするコマンドです。docker run -v(ボリュームマウント)や docker exec(コンテナ内シェル)と似た用途に見えますが、それぞれ使いどころが異なります。
| 方法 | できること | できないこと |
|---|---|---|
docker run -v |
起動前からホストとコンテナのディレクトリを同期 | 起動済みコンテナへの後付けマウント |
docker exec |
実行中コンテナ内でコマンドを実行 | 停止中コンテナの操作 |
docker cp |
実行中・停止中コンテナとホスト間のファイルコピー | リアルタイムの同期 |
docker cp の最大の特徴はコンテナが停止していても使える点です。
簡単な使い方
コンテナ → ホスト
docker cp <コンテナ名 or ID>:<コンテナ内パス> <ホストのパス>例:
docker cp my-container:/app/output.txt ./output.txtホスト → コンテナ
docker cp <ホストのパス> <コンテナ名 or ID>:<コンテナ内パス>例:
docker cp ./config.json my-container:/app/config.jsonディレクトリごとコピーするときも同じ構文で問題ありません。
# ディレクトリをまるごとコンテナへコピー
docker cp ./src/ my-container:/app/src/よく使うシチュエーション
コンテナ内の成果物を抜き取りたいとき
ビルドコンテナなど、ボリュームをマウントせずに起動したコンテナの中に成果物が出力されることがあります。そのような場合でも docker cp を使えばコンテナを停止させずにファイルを取り出せます。
# 成果物をホストへ取り出す
docker cp build-container:/app/dist ./distdocker run -v でマウントしておけば最初からホスト側に出力できますが、既存のDockerfileやdocker-compose.ymlを変更せずにすぐに取り出したいときは docker cp が手軽です。
コンテナ内でデバッグするとき
docker exec でコンテナ内に入ってデバッグする際、コンテナ内のファイルを編集していろいろと試したいことがあります。しかし、コンテナ内にはエディタが入っていないことが多いため、直接編集するのは難しいです。そんなときは一度ファイルをホストにコピーして編集し、再度コンテナに送り返すという流れが便利です。
- コンテナからファイルをホストへコピー
- ホスト上で普段使いのエディタで編集
- 編集したファイルをコンテナへ送り返す
# 1. ファイルをホストへ取り出す
docker cp my-container:/app/config.yaml ./config.yaml
# 2. ホスト上で編集(省略)
# 3. 編集済みファイルをコンテナへ送り返す
docker cp ./config.yaml my-container:/app/config.yamlなお、このやり方はデバッグ・検証目的の一時的な変更に向いています。本番環境への恒久的な反映はDockerfileやdocker-compose.ymlを修正してイメージを作り直す方法を取るべきです。
停止中のコンテナからログを回収したいとき
docker cp はコンテナが停止していても使えるため、コンテナが落ちてしまった後にログファイルや設定ファイルを回収したいときにも便利です。
docker cp stopped-container:/var/log/app.log ./app.logdocker logs コマンドで取得できるのは標準出力・標準エラーだけですが、アプリがファイルにログを書き出している場合はそのファイルを docker cp で取り出す必要があります。コンテナが異常終了した直後でも、コンテナが削除されていなければこの方法でログを救出できます。
まとめ
docker cp はシンプルながらも、ボリュームマウントを事前に設定していなかった場面や停止コンテナからファイルを回収したい場面で実力を発揮します。
実際に業務で使ってみると、既存のコンテナ設定を変えずにすぐファイルをやり取りできる手軽さが便利でした。docker run -v や docker exec と使い分けるポイントは「後付けで使いたいか」「コンテナが停止しているか」の2点を意識しておくと判断しやすくなります。


コメント