「hadolint」にシバかれながら美しいDockerfileを書き上げる
hadolintとは
hadolintはDockerfile用のLintツールだ。
たとえば、下記のようなDockerfileを作って、チェックしてみる。
FROM alpine RUN cd /tmp && echo 'hello'
すると、次のような警告をしてくれるようになる。
/dev/stdin:1 DL3006 Always tag the version of an image explicitly /dev/stdin:3 DL3003 Use WORKDIR to switch to a directory
Lintルール
雰囲気をつかむために、いくつかのルールを抜粋しよう。
- DL3002 - 最終ユーザをrootにしてはいけない
- DL3006 - イメージには常に明示的にタグを指定する
- DL3008 - バージョンを指定してapt-get installする
- DL4000 - MAINTAINER は非推奨なので使わない
これら以外に、どんなルールでチェックされるかは、公式のREADMEのRulesを確認しよう。
それでは、前置きはこのぐらいにして実際に使ってみよう。
インストール
公式でDockerイメージが提供されているので、それを使うのが簡単だ。筆者はDocker版を使っている。
$ docker pull hadolint/hadolint
macOSであれば、Homebrewでインストールしてもよい。
$ brew install hadolint
使い方
ベーシックな使い方
ここではDocker版をベースに紹介する。Dockerfileを標準入力として実行するだけだ。
$ docker run --rm -i hadolint/hadolint < Dockerfile
特定のルールを除外する
--ignore
オプションを使えば、特定のルールを除外できる。
$ docker run --rm -i hadolint/hadolint hadolint - --ignore DL3006 < Dockerfile
出力フォーマットの指定
--format
オプションで指定できる。
出力フォーマットは「tty、json、checkstyle、codeclimate、codacy」の中から選択できる。
tty
デフォルトはttyで、何も指定しない場合と同様の結果になる。
$ docker run --rm -i hadolint/hadolint hadolint - --format tty < Dockerfile /dev/stdin:1 DL3006 Always tag the version of an image explicitly /dev/stdin:3 DL3003 Use WORKDIR to switch to a directory
json
他のCLIツールと組み合わせるなら、json形式が役立つかもしれない。
$ docker run --rm -i hadolint/hadolint hadolint - --format json < Dockerfile | jq . [ { "line": 1, "code": "DL3006", "message": "Always tag the version of an image explicitly", "column": 1, "file": "/dev/stdin", "level": "warning" }, { "line": 3, "code": "DL3003", "message": "Use WORKDIR to switch to a directory", "column": 1, "file": "/dev/stdin", "level": "warning" } ]
checkstyle
CIでCheckStyleを使っている場合は、checkstyle形式で出力すると便利だろう。codeclimate、codacyも同様の用途と思われる。
$ docker run --rm -i hadolint/hadolint hadolint - --format checkstyle < Dockerfile <?xml version='1.0' encoding='UTF-8'?><checkstyle version='4.3'><file name='/dev/stdin' ><error line='1' column='1' severity='warning' message='Always tag the version of an image explicitly' source='DL3006' /><error line='3' column='1' severity='warning' message='Use WORKDIR to switch to a directory' source='DL3003' /></file></checkstyle>
ヘルプ
$ docker run --rm hadolint/hadolint hadolint --help hadolint - Dockerfile Linter written in Haskell Usage: hadolint [-v|--version] [-c|--config FILENAME] [-f|--format ARG] [DOCKERFILE...] [--ignore RULECODE] [--trusted-registry REGISTRY (e.g. docker.io)] Lint Dockerfile for errors and best practices Available options: -h,--help Show this help text -v,--version Show version -c,--config FILENAME Path to the configuration file -f,--format ARG The output format for the results [tty | json | checkstyle | codeclimate | codacy] (default: tty) --ignore RULECODE A rule to ignore. If present, the ignore list in the config file is ignored --trusted-registry REGISTRY (e.g. docker.io) A docker registry to allow to appear in FROM instructions
バージョン確認
$ docker run --rm -i hadolint/hadolint hadolint --version Haskell Dockerfile Linter v1.13.0-2-g8623159
設定ファイル
hadolintはYAMLフォーマットの設定ファイルをサポートしている。
ignored: - DL3006
これをDockerfileと同じディレクトリに .hadolint.yaml
という名前で保存しよう。実行するときは下記コマンドを叩く。
$ docker run --rm -v "$PWD:/work" -w /work hadolint/hadolint hadolint Dockerfile
.hadolint.yaml
以外の名前のファイル名にしたい場合は、--config
オプションで設定ファイルを指定すれば良い。
$ docker run --rm -v "$PWD:/work" -w /work hadolint/hadolint hadolint --config myconfig.yml Dockerfile
特定の行のチェックを除外する
特定の行を hadolint のチェック対象から除外する場合は、Dockerfileにその設定を直接記述することになる。
FROM alpine # hadolint ignore=DL3003 RUN cd /tmp && echo 'hello'
このように書くと、記事冒頭の例から、一つ警告を除外することができる。ただし、乱用は厳禁だ。
おわりに
Dockerfileには様々なベストプラクティスやアンチパターンが存在する。長い時間をかけて習得するのも悪くないが、hadolintがあれば、一気にショートカットして、あなたのDockerfileのクオリティを上げることができる。
最初はちょびっと小うるさいが、慣れてくるとhadolintなしでDockerfileを書くなんてとんでもない!という気持ちになってくるので、ぜひ試してみてほしい。