1. 序章

より多くのアプリケーションがクラウド環境にデプロイされるにつれて、Dockerでの作業は開発者にとって必要なスキルになりつつあります。 多くの場合、アプリケーションをデバッグするときは、DockerコンテナーにファイルをコピーしたりDockerコンテナーからファイルをコピーしたりすると便利です。

このチュートリアルでは、Dockerコンテナとの間でファイルをコピーするさまざまな方法を見ていきます。

2. Docker cpコマンド

Dockerコンテナーとの間でファイルをコピーする最も簡単な方法は、dockercpコマンドを使用することです。 このコマンドはUnixcpコマンドを厳密に模倣しており、構文は次のとおりです。

docker cp

このコマンドの例をいくつか見る前に、次のDockerコンテナーが実行されていると仮定します。

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
1477326feb62        grafana/grafana     "/run.sh"                2 months ago        Up 3 days           0.0.0.0:3000->3000/tcp   grafana
8c45029d15e8        prom/prometheus     "/bin/prometheus --c…"   2 months ago        Up 3 days           0.0.0.0:9090->9090/tcp   prometheus

最初の例では、ホストマシンの /tmpディレクトリからgrafanaコンテナのGrafanaインストールディレクトリにファイルをコピーします。

docker cp /tmp/config.ini grafana:/usr/share/grafana/conf/

名前の代わりにコンテナIDを使用することもできます。

docker cp /tmp/config.ini 1477326feb62:/usr/share/grafana/conf/

grafanaコンテナからホストマシンの/tmp ディレクトリにファイルをコピーするには、パラメータの順序を切り替えるだけです。

docker cp grafana:/usr/share/grafana/conf/defaults.ini /tmp

単一のファイルではなく、ディレクトリ全体をコピーすることもできます。 この例では、confディレクトリ全体をgrafanaコンテナからホストマシンの/tmpディレクトリにコピーします。

docker cp grafana:/usr/share/grafana/conf /tmp

dockercpコマンドにはいくつかの制限があります。 まず、2つのコンテナ間でのコピーには使用できません。 ホストシステムと単一のコンテナ間でファイルをコピーするためにのみ使用できます。

次に、 Unix cpコマンドと同じ構文を持っていますが、同じフラグをサポートしていません。 実際、サポートしているのは2つだけです。

-a :コピーされるファイルのすべてのuid/gid情報を保持するアーカイブモード-L:常にSRCのシンボリックリンクをたどる

3. ボリュームマウント

Dockerコンテナーとの間でファイルをコピーする別の方法は、ボリュームマウントを使用することです。 これは、ホストシステムのディレクトリをコンテナ内で利用できるようにすることを意味します。

ボリュームマウントを使用するには、 -vフラグを指定してコンテナを実行する必要があります:

docker run -d --name=grafana -p 3000:3000 grafana/grafana -v /tmp:/transfer

上記のコマンドは、 grafana コンテナを実行し、 /tmpディレクトリをホストマシンから/transferという名前のコンテナ内の新しいディレクトリとしてマウントします。 必要に応じて、複数の-vフラグを提供して、コンテナー内に複数のボリュームマウントを作成できます。

このアプローチにはいくつかの利点があります。 まず、 Unix cpコマンドを使用できます。このコマンドには、 dockercpコマンドよりも多くのフラグとオプションがあります。

2番目の利点は、すべてのDockerコンテナに対して単一の共有ディレクトリを作成できることです。 これは、すべてのコンテナが同じボリュームマウントを持っている限り、コンテナ間で直接コピーできることを意味します。

このアプローチには、すべてのファイルがボリュームマウントを通過する必要があるという欠点があることに注意してください。 これは、1つのコマンドでファイルをコピーできないことを意味します。 代わりに、最初にファイルをマウントされたディレクトリにコピーし、次に最終的な目的の場所にコピーします。

このアプローチのもう1つの欠点は、ファイルの所有権に問題がある可能性があることです。 Dockerコンテナには通常rootユーザーしかありません。つまり、コンテナ内に作成されたファイルはデフォルトでroot所有権を持ちます Unix chownコマンドを使用して、ホストマシンで必要に応じてファイルの所有権を復元できます。

4. Dockerfile

Dockerfiles は、Dockerイメージを構築するために使用され、DockerイメージはDockerコンテナーにインスタンス化されます。 Dockerfileには、いくつかの異なる命令を含めることができます。そのうちの1つはCOPYです。

COPY 命令を使用すると、1つまたは複数のファイルをホストシステムからイメージにコピーできます。 これは、ファイルがそのイメージから作成されるすべてのコンテナの一部になることを意味します。

COPY 命令の構文は、上記で見た他のコピーコマンドと同様です。

COPY <SRC> <DEST>

他のコピーコマンドと同様に、 SRC は、単一のファイルまたはホストマシン上のディレクトリのいずれかになります。 複数のファイルに一致するワイルドカード文字を含めることもできます。

いくつかの例を見てみましょう。

これにより、現在のDockerビルドコンテキストからイメージにシングルがコピーされます。

COPY properties.ini /config/

そして、これによりすべてのXMLファイルがDockerイメージにコピーされます。

COPY *.xml /config/

このアプローチの主な欠点は、Dockerコンテナの実行に使用できないことです DockerイメージはDockerコンテナーではないため、このアプローチは、イメージ内で必要なファイルのセットが事前にわかっている場合にのみ使用するのが理にかなっています。

5. 結論

このチュートリアルでは、Dockerコンテナとの間でファイルをコピーする方法を見てきました。 それぞれに長所と短所があるため、ニーズに最適なアプローチを選択する必要があります。