Docker パーサーディレクティブ
Parser directive
Parser directiveの実体はDockerfileの先頭行に記述する特殊なコメントで、Dockerfileの後続行の処理方法に影響する。
syntaxとescapeの2種類のパーサーディレクティブが存在する。
syntax
実はDockerfile 内で使用される構文は交換可能で、syntaxで構文の処理方法を指定することができる。例えば、以下のように先頭行に# syntax=docker/dockerfile:1と記述することで、Dockerfile内でヒアドキュメントを使用できるようになる。
# syntax=docker/dockerfile:1
FROM golang:1.21 as build
WORKDIR /src
COPY <<-EOF /src/main.go
package main
import "fmt"
func main() {
fmt.Println("hello, world")
}
EOF
RUN go build -o /bin/hello ./main.go
docker/dockerfileイメージにより、BuildKitを使用してイメージをビルドできるようになる。ちなみにBuildKitとは、コンテナをビルドするためのデーモンらしい。
BuildKit とは、コンテナをビルドするためのツールキットであり、 buildkitdというデーモンとbuildctlコマンドで構成されています。 Dockerの標準のビルドと比べて、BuildKitでビルドした場合には以下のようなメリットがあります。
また、BuildKitの一部機能はDocker 18.06以降のDocker Engineに統合されており、 Docker単体でもBuildKitの一部機能を利用することができます。
syntaxはDockerfile Frontendとも呼ばれる。syntaxで外部のDockerfile frontend(dockerfileというDockerイメージ)を指定することで、構文処理の方法を変更することができる。BuildKitやDocker Engineをアップグレードしなくても、最新のDockerfile frontendを使用できる。
BuildKitは不使用のビルドステージを検知し、スキップする。例えば、次のようなDockerfileがあると、最終イメージはstage2になる。stage2はbaseステージから作成され、stage1は使われないステージになっている。このときBuildKitはbaseとstage2のみ処理し、依存関係のないstage1はスキップされる。一方、レガシーのビルダーでは、stage1も含め全てのステージが処理される。
# syntax=docker/dockerfile:1
FROM ubuntu AS base
RUN echo "base"
FROM base AS stage1
RUN echo "stage1"
FROM base AS stage2
RUN echo "stage2"
escape
escapeは、エスケープ文字を指定するために使用するパサーディレクティブ。デフォルトのエスケープ文字はバックスラッシュ\で、変更したい場合に使用するが、あまり用途はない気がする。
# escape=\