Dockerfile自信持って書けてますか？おすすめlintツール 「hadolint」について紹介

# はじめに
Dockerfile、サッと書こうと思ったのに、書き始めたら意外と時間かかったりしますよね。
突き詰めるとすごく奥が深いなと思います。

公式のドキュメントでも、[Dockerfileのベスト・プラクティス](https://docs.docker.jp/develop/develop-images/dockerfile_best-practices.html)という形で公開してくれていますが、
これを毎回意識するのは大変です。
また、意識できていたとしても、複数人で管理していると、各個人のスキルレベルによって差が出てしまいます。

そんなときにおすすめのツールを見つけたので紹介します。

[hadolint](https://github.com/hadolint/hadolint)というツールです。

`Haskell Dockerfile Linter`の略だそうで、Dockerfileの静的解析を行ってくれるlintツールです。

hadolintを使うとこんな利点があります。
* **build前にシンタックスエラーなどに気付ける** (地味にトライアンドエラーしてると時間食うんですよね...)
* **自然とベストプラクティスに則ったDockerfileが書ける**

## 導入方法
では早速使ってみましょう。

+ インストール
  + macの場合 `brew install hadolint`
  + linuxの場合
      + `curl -L https://github.com/hadolint/hadolint/releases/download/v2.8.0/hadolint-Linux-x86_64 -o /usr/local/bin/hadolint`
    + `chmod 755 /usr/local/bin/hadolint`
+ installしたら `hadolint Dockerfile`のようにファイル名を指定するだけ


### CI/CDに組み込む場合
#### GitLab CIの場合
[hadolint](https://github.com/hadolint/hadolint/blob/master/docs/INTEGRATION.md)公式より引用
rulesの箇所のみ追記しています。毎回走らせる必要性は薄いと思うので、Dockerfileの変更時のみという条件を追加しています。

```yaml
lint_dockerfile:
  image: hadolint/hadolint:latest-debian
  # image: ghcr.io/hadolint/hadolint:latest-debian
  script:
    - hadolint Dockerfile
  rules:
    - changes:
        - Dockerfile
```

#### GitHub Actionsの場合
同じく[hadolint](https://github.com/hadolint/hadolint/blob/master/docs/INTEGRATION.md)公式より引用
pathsのみ追記しています。

```yaml
name: Lint Dockerfile

on: push

jobs:
  linter:
    runs-on: ubuntu-latest
    steps:

      - uses: actions/checkout@v2

      - name: Lint Dockerfile
        uses: hadolint/hadolint-action@master
        with:
          dockerfile: "Dockerfile"
    paths:
      - 'Dockerfile'
```

### vscodeで使用する場合
※hadolintのインストールは済ませておく必要があります

下記をvscodeから取得してください。

https://marketplace.visualstudio.com/items?itemName=exiasr.hadolint


↓こんな感じで表示してくれるのでとても便利です。
![スクリーンショット 2023-02-21 22.49.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224825/9a9ac023-6f3b-f9eb-0b77-c50a66373e6a.png)


## 触ってみる

では試しに下記のrubyのイメージに実行してみます。

```Dockerfile
FROM ruby:3.2.1
RUN apt-get update -qq && apt-get install -y build-essential nodejs
RUN mkdir /app
WORKDIR /app
ADD Gemfile /app/Gemfile
ADD Gemfile.lock /app/Gemfile.lock
RUN bundle install
ADD . /app
```

`hadolint Dockerfile`を実行すると、下記のように色分けして出力されました！

![スクリーンショット 2023-02-21 22.28.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224825/5fa783ca-5fe8-71de-b215-d89939163d61.png)

[hadolint wiki](https://github.com/hadolint/hadolint/wiki)があるので、参照すると理由ともに修正方法を教えてくれます。
↓のような形でwikiが記載されているのでとても見やすいです。

![スクリーンショット 2023-02-21 22.34.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224825/ba6cb7ce-c844-b15f-d054-64392405c978.png)

試しに直してみましょう。 ADDをCOPYに変更すると↓errorの文字は消えています！

![スクリーンショット 2023-02-21 22.35.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224825/ce946018-a11a-bf8f-32d8-376b222e10fc.png)

また、ignoreをコマンドで実行することもできます。
`hadolint --ignore DL3008 Dockerfile` warningが消えてますね。
![スクリーンショット 2023-02-21 22.37.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224825/2c49dad8-6eb6-cc71-9df5-b2b460a0f6bc.png)

ただ、ignoreを毎回コマンドで打つということは基本的にあまりしないと思うので、ignore用のファイルを作ることができます。

### hadolintのオプション
基本的には[hadolint](https://github.com/hadolint/hadolint)の公式を見てもらうのがいいと思いますが、
よく使いそうなものを説明します。

#### 特定のlintエラーを表示したくない場合
* hadolintコマンド実行時にignoreオプションを指定する
    * ex) `hadolint --ignore DL3008 Dockerfile`
* .hadolint.yamlで記載する
* Dockerfileにインラインコメントで記載する

.hadolint.yamlの例。　以下のようにignoredで一つ一つルールを指定する。

```yaml
ignored:
  - DL3008
```

Dockerfileにインラインコメントで記載する例。 
globalを付けると、ファイル全体で無視。global付けない場合は次の行だけを無視する.

```Dockerfile
# hadolint global ignore=DL3008
FROM ruby:3.2.1
# hadolint ignore=DL3008
RUN apt-get update -qq && apt-get install -y build-essential nodejs
RUN mkdir /app
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
COPY . /app
```


# 終わりに

以上、hadolintの使い方について説明しました！
lintに慣れてくると、自然とベストプラクティスに沿った書き方ができるようになっていると思います。
理由もwikiに記載してくれているので、合わせて確認すると、なぜこの書き方にしないといけないか？も分かるのでチェックしましょう！

hadolintで、皆さんもDockerfileのベスト・プラクティスを実践していきましょう！

最後までお読みいただきありがとうございました。