.dockerignoreが効かない?.gitignoreとは書き方が違うよ!


この記事は

.dockerignoreと.gitignore、名前が似ているし書き方も似ているので同じように書けばよいと思っていましたが、違いました。この記事では違いを紹介します。

対象読者

.gitignoreは書いたことがあるけれど、.dockerignoreはあまり書いたことがない人

ポイント

.gitignoreの仕様は 公式ページのgitignoreのページ に記載されています。
日本語だとQiitaの .gitignoreの仕様詳解 が分かりやすいです。

.dockerignoreの仕様は 公式ページのdocker build#dockerignore に記載されています。

主なルールは3つです。

  • パターンマッチングには Go 言語の filepath.Match ルールが用いられています。 
  • 特別なワイルドカード文字列 ** をサポートしています。 これは複数のディレクトリ(ゼロ個を含む)にマッチします。
  • 行頭を感嘆符 ! で書き始めると、それは除外に対しての例外を指定するものとなります。

.dockerignoreとは

.dockerignoreと.gitignoreの違いを説明する前に、docker build時のファイル転送と.dockerignoreの役割を説明します。

docker build時のファイル転送

Dockerfileをビルドする際、dockerはビルドコンテキスト以下をtarでまとめています。これは対象のディレクトリをdockerデーモンに転送するためです。
このtarの中には、COPYやADDされないファイルも含まれます。ビルドコンテキスト以下の全てのファイルが含まれるのです。

.dockerignore

dockerビルドに必要ない(tarの中に入れたくない)ファイルは.dockerignoreに記載します。
.dockerignoreを作成することで、ビルド時間の短縮、docker imageサイズの最適化、機密情報(パスワードなど)の不本意な漏洩の防止、等の効果があります。

ビルドコンテキストルート

ビルドコンテキストルートは、docker buildで使用するパスです。(Dockerfileの場所ではありません)

docker build -f path/to/Dockerfile myprj
                                   -----
                              ↑ docker buildの引数に指定しているパスがビルドコンテキストルート ↑

上の例だと、myprjがビルドコンテキストルートです。上記の例の場合、.dockerignoreはmyprjディレクトリに配置します。

.dockerignoreと.gitignoreの違い

さて本題です。.dockerignoreと.gitignore、目的も書き方も似ていますが、実装は同じではありません。仕様も違っています。

パスの指定の仕方

.gitignore

.gitignoreでは書かれたファイルorディレクトリ名は.gitignoreファイル以下の階層であれば、どの階層であっても無視されます。

例えば、

.gitignore
target

と記載すると、

target
src/target
path/a/b/target

などが無視されます。

.dockerignore

.dockerignoreでは、パスはすべて.dockerignoreが置かれているパスからの相対パスで記載します。1

例えば、

.dockerignore
target

と記載すると、

target

のみが無視され、

src/target
path/a/b/target

は無視されません。

.gitignoreのように任意の階層を対象にしたい場合は

dockerignore
**/target

と記載します。

サブディレクトリにあるignorefile

.gitignore

.gitignoreの場合、.gitignoreをサブディレクトリにも配置することができます。その場合は対象ファイルに近い方のルールが優先されます。

.dockerignore

.dockerignoreはビルドコンテキストルートにある.dockerignoreしか読み込まれません。サブディレクトリにある.dcokerignoreファイルは読み込まれません。

Dockerfileのディレクトリとビルドコンテキストが異なる場合に注意が必要です。Dockerfileと同じ場所に.gitignoreを置くのではなく、ビルドコンテキストに.dockerignoreを配置します。

あとがき

もしかしてもう少し違いがあるかもしれませんが、今のところ見つけた違いはこのくらいでした。
快適なdockerライフを。

環境

  • Docker: 19.03.12
  • Docker for Mac: 2.3.0.5

参考資料リンク


  1. .gitignoreと同様にパスの先頭に / を付けることも可能です。