HOWTO · Docker
ホストから Docker コンテナにファイルをコピーする
このチュートリアルでは、ホストから Docker コンテナにファイルをコピーする方法を示します。
このページの内容
既存のコンテナへ一度だけファイルを転送するには、ローカルのコピー元とコンテナ内のコピー先を指定して docker cp を使います。
docker cp ./local-file CONTAINER:/existing-directory/
CONTAINER はコンテナ名または ID に置き換えます。docker cp は起動中だけでなく停止中のコンテナにも使えます。相対的なローカルパスはコマンドを実行したディレクトリから解決され、コンテナ内のパスは / を起点にします(先頭の / は省略可能です)。完全な規則は Docker の cp リファレンスで確認してください。
既存のコンテナへファイルをコピーする
次の例では、現在のホストディレクトリにある hello.txt を demo-app の /opt/ にコピーします。コピー先ディレクトリはあらかじめ存在している必要があります。
docker cp ./hello.txt demo-app:/opt/
/opt/ が存在すれば、コンテナには /opt/hello.txt が作られます。末尾のスラッシュは既存ディレクトリを指定する意図を明確にします。コピー先が既存のファイルなら内容が置き換わるため、問題になる場合は事前に確認してください。
実行中のコンテナでコピーを確認するには、対話シェルではなく直接コマンドを実行できます。
docker exec demo-app ls -l /opt/hello.txt
一覧に対象ファイルが表示されれば成功です。docker exec は実行中のコンテナを必要としますが、docker cp 自体は停止中のコンテナも対象にできます。
ディレクトリまたはその内容だけをコピーする
docker cp はディレクトリを再帰的にコピーします。コピー元の書き方によって、ディレクトリ本体を置くか内容だけを置くかが変わります。
# Creates /opt/host-files/ in the container.
docker cp ./host-files demo-app:/opt/
# Copies the contents of host-files into the existing /opt/incoming/ directory.
docker cp ./host-files/. demo-app:/opt/incoming/
2 番目のコマンドでは /opt/incoming/ が存在していなければなりません。/. を付けると、余分な host-files ディレクトリを作らずに内容だけをコピーできます。Docker は存在しない親ディレクトリを作成しません。末尾が / のコピー先は既存のディレクトリである必要があります。詳細は docker cp のコピー先規則を参照してください。
docker cp、Dockerfile の COPY、bind mount を使い分ける
| 必要なこと | 使用するもの | 理由 |
|---|---|---|
| 既存の 1 コンテナに今すぐファイルを追加する | docker cp |
そのコンテナのファイルシステムへ一回だけコピーします。 |
| すべてのイメージビルドにファイルを含める | Dockerfile の COPY |
ビルドコンテキスト内のファイルをイメージに追加します。 |
| 開発中にホストのディレクトリをコンテナと共有する | bind mount | 実行時にパスを共有し、別のコピーは作りません。 |
アプリケーションファイルをイメージに入れる場合は Dockerfile に書きます。
COPY ./config.yaml /app/config.yaml
COPY はビルド時の命令であり、既存コンテナを変更する手段ではありません。コピー元はビルドコンテキストから解決されるため、通常はその外側のパスを指定できません。Dockerfile COPY リファレンスも確認してください。
繰り返し共有するには、コンテナ作成時に bind mount を指定します。
docker run --mount type=bind,source=/absolute/host/path,target=/app/input,readonly IMAGE
bind mount はコピーではなく共有ストレージです。readonly を外すと、コンテナ内のプロセスはアクセスできるホストファイルを変更または削除できます。実際に必要なのがその共有であれば、ホストディレクトリをマウントしてファイルを共有するを参照してください。Docker のbind mount の共有と権限に関する注意点も確認できます。
また、docker cp をイメージ設定として使わないでください。コピーはそのコンテナの書き込み可能なファイルシステムに残るので、同じコンテナの停止・再起動後には残りますが、イメージから作り直した置換コンテナには入りません。
よくある docker cp の失敗を避ける
コピー前にパスを確認してください。ローカルのコピー元は存在する必要があります。ローカルファイルを末尾 / のない存在しないパスへコピーすると、Docker はその正確な名前のファイルを作成できますが、親ディレクトリは作成しません。コピー元がディレクトリの場合、親が存在すれば最後のコピー先ディレクトリを作成できますが、ファイルの上にディレクトリをコピーすることはできません。
既定では、コンテナへコピーしたファイルの所有者はコピー先のユーザーとグループ(通常は root:root)です。元の UID と GID を保存することがコンテナの利用者に適切な場合だけ -a を付けます。ローカルのシンボリックリンクは既定でリンクとしてコピーされるため、リンク先をコピーするには -L を使います。コピー先の権限も利用可能なコピーを妨げることがあります。
最後に、docker cp では /proc、/sys、/dev 配下のリソース、一時ファイルシステム、ユーザー作成のマウントなど、コンテナの一部のシステムパスをコピーできません。このような場合はコンテナに応じた方法を使い、文書化された制限を確認してください。