Address
304 North Cardinal St.
Dorchester Center, MA 02124

Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM

DockerのDockerfileのCOPYの使い方と注意点、エラー「No such file or directory」と出た場合の解決法について

DockerfileでCOPYを使うときの間違いやすい注意点について。

今回は私がうっかりハマってしまったDockerfileの書き方、特にCOPYの使い方とその注意点についての記事です。

ハマったエラーの内容

Dockerfileにおいて、Pythonの様々なモジュールやライブラリをまとめてインストールするときに、requirements.txtを使って、

RUN pip install -r requirements.txt

とすることが多いでしょう。しかしそのDockerfileを実行すると、

No such file or directory: ‘requirements.txt’

ファイルやディレクトリが存在しないというエラーが毎回出て困っていました。

エラーの原因

私は、上のようなフォルダ/ディレクトリ構成にしていて、それをふまえてDockerfileのCOPYの記述を次のようにしていました。

COPY ../python/requirements.txt コピー先パス

こうすると上述のように期待したような動作にならずエラーとなります。

DockerfileのCOPYのルール

このCOPYについては、公式ドキュメントでは次のように書かれています。

COPY は以下のルールに従います。

  • <コピー元> のパスは、構築コンテクスト内にある必要があります。つまり、 COPY .../どこか /どこか のように指定できません。これは、 docker build の第一段階が、コンテクスト対象のディレクトリ(とサブディレクトリ)を docker デーモンに対して送信するからです。
  • <コピー元> がディレクトリであれば、ファイルシステムのメタデータも含む、ディレクトリの内容すべてがコピーされます。

Dockerfileの構築コンテクストとは?

ここで使われている用語「構築コンテクスト内」がわかりにくく説明もしにくいのですが、乱暴にいえばDockerfileの場所を基準として、

  • そのDockerfileと同じフォルダ/ディレクトリ。(これを仮にAという名前のフォルダにします)
  • そのAというフォルダ/ディレクトリの内部にある下部フォルダ

これらの2つの場所をことを構築コンテクストだと思ってください。それらの場所にあるファイルしか、COPYのコピー元ファイルとして扱えないということです。

解決方法

さてもう上の説明で解決方法は書いてしまいましたが、今回悩まされたエラーは、つまり、Dockerfileが直接属しているフォルダ/ディレクトリの内部にrequirements.txtが存在していないことでした。

というわけでたとえば下のようなフォルダ/ディレクトリ構成にすれば解決します。

そしてこのときのCOPYの記述は、

COPY requirements.txt コピー先パス

というようにすれば問題なく動作します。なおDocker初心者には次のような動画講座がおすすめです。