📚

Dockerfileの静的解析(lint)を行うhadolintを使ってみる

2022/12/18に公開

背景

先日、外部の勉強会に出ていたときにDockerfileのlintを行えるhadolintという存在を知り、使ってみました。Dockerfileのベストプラクティスに沿っているかチェックしてくれるみたいです。

https://github.com/hadolint/hadolint

環境

(そろそろOSのバージョン上げないとなぁ。。。)

機種 : MacBook Pro 2021(M1 Max)
キーボード : USキーボード
OS : Monterey(12.2.1)
hadolint version : Haskell Dockerfile Linter 2.12.0

インストール

brewで一撃インストールできます。

$ brew install hadolint

静的解析を実行する

以前作成していた以下のDockerfileで静的解析をやってみます。

https://github.com/katsuya-n/pub_laravel_spectator/blob/master/docker/php-apache/Dockerfile

Dockerfile
FROM php:8.1-apache

RUN apt-get update \
    && apt-get install -y git emacs \
    && docker-php-ext-install pdo_mysql \
    && less vim curl zip
RUN apt-get install -y unzip

COPY ./apache/apache2.conf /etc/apache2/apache2.conf
COPY ./apache/000-default.conf /etc/apache2/sites-available/000-default.conf

COPY --from=composer:2 /usr/bin/composer /usr/bin/composer

RUN a2enmod rewrite

WORKDIR /var/www/html/src

実行はhadolint Dockerfileで行えます。

$ hadolint Dockerfile

Dockerfile:3 DL3008 warning: Pin versions in apt get install. Instead of `apt-get install <package>` use `apt-get install <package>=<version>`
Dockerfile:3 DL3009 info: Delete the apt-get lists after installing something
Dockerfile:3 DL3015 info: Avoid additional packages by specifying `--no-install-recommends`
Dockerfile:7 DL3008 warning: Pin versions in apt get install. Instead of `apt-get install <package>` use `apt-get install <package>=<version>`
Dockerfile:7 DL3015 info: Avoid additional packages by specifying `--no-install-recommends`

色々と出てきました。出力されるものに関しては、READMEに記載あるので確認します。

https://github.com/hadolint/hadolint#rules

例えばDL3008だとバージョンを固定して、apt-get installせんかい!と言われています。詳細ページに飛ぶとどう直せば良いかも書いてくれているので、こりゃ良いですね。

https://github.com/hadolint/hadolint/wiki/DL3008

GitHub ActionsでCIに組み込んでみる

https://github.com/hadolint/hadolint-action

Pull Requestが投げられたときにGitHub Actionsが起動するようにしてみます。

.github/workflows/ci.yml
name: CI

on:
  pull_request:

jobs:
  CI:
    runs-on: ubuntu-latest
    timeout-minutes: 20

    steps:
      - uses: actions/checkout@v3

      - uses: hadolint/hadolint-action@v2.1.0
        with:
          dockerfile: docker/php-apache/Dockerfile

Pull Requestを出してみると、環境の違いの影響かDL3022が増えて、失敗になりました。

Error: docker/php-apache/Dockerfile:3 DL3009 info: Delete the apt-get lists after installing something
Error: docker/php-apache/Dockerfile:3 DL3015 info: Avoid additional packages by specifying `--no-install-recommends`
Error: docker/php-apache/Dockerfile:7 DL3008 warning: Pin versions in apt get install. Instead of `apt-get install <package>` use `apt-get install <package>=<version>`
Error: docker/php-apache/Dockerfile:7 DL3015 info: Avoid additional packages by specifying `--no-install-recommends`
Error: docker/php-apache/Dockerfile:12 DL3022 warning: `COPY --from` should reference a previously defined `FROM` alias

失敗になるレベルを調整してみます。error以上の場合だけGitHub Actionsが失敗するようにしてみます。GitHub ActionsのログではError: ...は表示されたままですが、GitHub Actions自体は成功します。

.github/workflows/ci.yml
      - uses: hadolint/hadolint-action@v2.1.0
        with:
          dockerfile: docker/php-apache/Dockerfile
+         failure-threshold: error

使ってみた感想

  • ベストプラクティスに沿っているかがわかるのでキレイに書ける、保守性は上がりそう
  • 修正対象がDockerfileだけなので、リファクタリング時でもCIに組み込める
株式会社ゆめみ

Discussion