このエントリは はてなエンジニア Advent Calendar 2025 9日目の記事です。今日は
id:ymseがお届けします。
3行まとめ
- HadolintのようなDockerfileリンターがDockerにも組み込まれている
- Hadolintのほうがルール自体は多い
- それぞれ一長一短ある
目次
正しくDockerfileを書くのは難しい
大コンテナ時代においてみなさまDockerfileを書いているのではないでしょうか。
そんなDockerfileですが適当に書くとイメージサイズが大きくなったり、思わぬアタックサーフェスを増やしてしまったり、ビルド時にキャッシュが効きにくく時間がかかったりします。
そんなDockerfileを正しく書くためにHadolintに代表されるリンターがあります1。
実はdocker buildを叩くと呼ばれるDocker BuildxもDockerfileに関するリンターを組み込んでいます。2025年12月段階ではまだベータですが今日はこのリンターを使う方法について書きます。以後このリンターのことをbuild checksと言うことにします。
Docker組み込みのbuild checksを実行してみる
コマンド実行で検査する
ドキュメントにある通りです。
docker build --check .を実行することであらかじめ定義されたルールでチェックされます。
試しに以下のようなステージ名が重複したDockerfileに対してdocker build --check .を実行してみましょう。
FROM ubuntu:24 AS builder RUN echo "echo from builder" > /tmp/foo FROM ubuntu:24 AS builder COPY --from=builder /tmp/foo ./foo RUN cat ./foo ENTRYPOINT ["bash"]
実行した結果が以下の通りです。
$ docker build --check . [+] Building 0.0s (1/1) FINISHED => [internal] load build definition from Dockerfile => => transferring dockerfile: 202B Check complete, 1 warning has been found! WARNING: DuplicateStageName - https://docs.docker.com/go/dockerfile/rule/duplicate-stage-name/ Duplicate stage name "builder", stage names should be unique Dockerfile:4 -------------------- 2 | RUN echo "echo from builder" > /tmp/foo 3 | 4 | >>> FROM ubuntu:24 AS builder 5 | COPY --from=builder /tmp/foo ./foo 6 | RUN cat ./foo -------------------- ERROR: circular dependency detected on stage: builder Dockerfile:5 -------------------- 3 | 4 | FROM ubuntu:24 AS builder 5 | >>> COPY --from=builder /tmp/foo ./foo 6 | RUN cat ./foo 7 | --------------------
ステージ名が重複しているという警告と依存が循環しているというエラーが出ていますね。出力に行番号と周辺の文字列が表示されていて、人間が読むには優しい。
build 実行時に合わせて検査する
Dockerfileの冒頭に# check=error=trueを書くことにより--checkオプションを付けずとも検査できます。
危ないDockerfileを書いたときにはビルド実行前に異常終了してくれる。
別途CIワークフローなどを構築しなくて便利。
Hadolintの出力と比較する
同じDockerfileをHadolintに渡すと以下のように出力されます。
$ docker run --rm -i hadolint/hadolint < Dockerfile -:4 DL3024 error: FROM aliases (stage names) must be unique -:5 DL3023 error: `COPY --from` cannot reference its own `FROM` alias -:5 DL3045 warning: `COPY` to a relative destination without `WORKDIR` set.
報告されたエラー/警告の件数がこちらのほうが多いですね。増えたのはCOPY先がWORKDIRを指定していないのに相対パスを指定しているという DL3045 · hadolint/hadolint Wiki · GitHub のルールに対する指摘。
どちらがいいの
build checksとHadolintを比較するとルール自体はHadolintのほうが充実しています。build checksは21件のルールを定義しているのに対してHadolintが66件のルールを提供しています。
またルールに対するignoreなどもbuild checksはファイルに直接指定するほかありませんがHadolintはコンフィグファイルで独自に設定することができます。
一方で別途CIワークフローを構築せずとも導入できるbuild checksは導入がお手軽そう。
このように一長一短あるので状況によってHadolintとbuild checksを使いわければよいと思います。
個人的にはDockerfileにコメント追加するだけでお手軽導入できるという点で build checks を採用するかな。