【Docker修行③】静的解析ツール「hadolint」を利用して、効率的にベストプラクティスに基づいたDockerfile記述

- 1年にも満たないエンジニア生活のため、雲の上の存在だと思っていて距離を取っていた「Docker」の習得を目指す記事第三弾。
- 「波風や摩擦」との無縁化方法を塾考した結果、「そもそも」の結論に到り、塾考時間以上の硬直状態。
- 今回は、解析ツールを利用したDockerfileの最適化を図ることにしよう。

## 概要や特徴
- Haskell製のDockerfile静的解析ツール。
- 主な特徴としては下記がある。
    - Dockerfileを、公式ベストプラクティスに基づいて自動的に解析してくれる。
    - ライブラリとして「shellcheck」と呼ばれるシェル解析ツールを利用しているため、より高度な解析が可能。
    - Visual Studio Codeとの連携による記述の効率化。
    - 指定した最適化ルールを無視した解析

## 結果
- 下記のように、コマンド上でDockerfileを指定するだけで、多くの解析ルールにしたがった解析結果を教えてくれる。

<img width="951" alt="hado.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336499/8f20ac87-0ff9-4890-41bc-52c7e79744db.png">

- また、Visual Studio Codeでの連携をすることで、コマンド入力することなく、編集中の自動解析による効率的な記述が可能。

<img width="566" alt="hhd.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336499/c1520bb2-cf87-2eb3-ace3-0df36b692199.png">

- また、下記のようにコメントとして残すことで、膨大な解析ルールの特定のものを無視した解析も可能。

<img width="440" alt="jdhs.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336499/44fcb9e9-8d62-e75e-9c98-56d39571b098.png">

## 環境
- Mac OS X 10.13.4
- Homebrew 2.1.4
    - **※Homebrew未導入の場合、[こちら](https://brew.sh/index_ja)を参考にインストールする。**
- Docker version 18.09.2

## インストール

### Mac

- Macでのhadolintインストールは、下記のコマンドをうつ。

```bash
$ brew install hadolint
```

### Windows

- Windowsでのhadolintインストールは、下記のコマンドをうつ。
    - **※scoop未導入の場合、[こちら](https://qiita.com/rkbk60/items/12dc8fb14042888113d0)を参考にインストールする。**

```bash
$ scoop install hadolint
```

### その他環境

- その他環境(Linux等)でのインストールは、[こちら](https://github.com/hadolint/hadolint#install)を参考にする。

## 基本的な利用
- hadolint利用において、基本的なコマンドは下記。
    - **※解析においてhadolintが利用する膨大な解析ルール一覧は[こちら](https://github.com/hadolint/hadolint#rules)**
    - **※解析結果出力の際に、ルール詳細を確認する場合、上記を参照。**

|コマンド|内容|
|:---:|:---:|
|`hadolint Dockerfileパス`|Dockerfileの標準解析。<br>例: `hadolint ~work/Dockerfile`|
|`hadolint --ignore 解析ルール Dockerfileパス`|特定の解析ルールを無視した解析。<br>例: `hadolint --ignore DL3028 ~/Dockerfile`|
|`hadolint --trusted-registry レジストリ名 Dockerfileパス`|FROMレジストリの指定。による解析。<br>指定外のレジストリ利用の場合警告。<br>例: `hadolint --trusted-registry my-registry.com ~/Dockerfile`|
|`hadolint -f フォーマット Dockerfileパス`|出力結果のフォーマット指定による解析。<br>例: `hadolint -f json ~/Dockerfile`|
|`hadolint -v`|バージョン確認|
|`hadolint -h`|ヘルプ確認|

## 特定ルールの除外
- 上記の基本コマンドの通り、hadolintでは膨大な解析ルールの一部を指定して、無視した解析が可能。
- 利用方法として、コマンドを含めて下記の3つがある。
    - 1. コマンド指定による特定ルールの除外
        - 例: `hadolint --ignore DL3028 ~/Dockerfile`
    - 2. 設定ファイル記述による特定ルールの除外
    - 3. Dockerfileへのコメント式記述による特定ルールの除外
- これら3つのうち、「設定ファイル」「コメント式記述」の手順としては、下記。

### 設定ファイルによる除外
- 1. まず特定ルールを記述するためにDockerfileと同じ場所に`.hadolint.yaml`を作成する。
- 2. 作成後、下記の形式で除外したいルールを記述していく。

```yaml:~/work/.hadolint.yaml
ignored:
  - DL3028
  - DL4000
```

- 3. 記述後、`hadolint Dockerfileパス`等で解析を行い、無視されていれば完了。

### コメント式記述による除外
- 1. Dockerfileに直接除外ルールを記述する場合、まず対象のDockerfileを開く。
- 2. 下記の形式のように、除外したい記述の一行上に`# hadolint ignore=ルール`として書く。

```dockerfile:~/work/Dockerfile
# hadolint ignore=DL3007
FROM ruby:latest
ENV LANG C.UTF-8

# hadolint ignore=DL3008,DL3015
RUN apt-get update -qq && apt-get install -y \
    build-essential \
    nodejs \
 && rm -rf /var/lib/apt/lists/*
```

- 3. 記述後、`hadolint Dockerfileパス`等で解析を行い、無視されていれば完了。

## Visual Studio Codeとの連携
- DockerfileをVisual Studio Codeで編集する場合は、下記の手順でhadolintと連携して、利用することが可能。
    - 1. `Ctrl(Command) + Shift + x`で拡張機能メニューを開く。
    - 2. 検索欄に「hadolint」と入力して、表示される拡張機能をインストールする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336499/edbb6eea-9a7d-4476-62eb-74564defa282.png)

    - 3. 完了。

## まとめ
- 今回はツールを利用した静的解析ということで、大勢の賢人技術者達の「長年の最適化戦闘とツールによる解放」の感動物語に浸りながら、記事を書く。
- 「長年利用していると、使用技術のロゴまでも愛着が湧く」という名言を知り、hadolint利用直後にロゴの猫に忠誠を誓う。
- 次回は作成したDockerイメージの管理や最適化に便利な方法を模索することにしよう。

## 参考サイト
- https://github.com/hadolint/hadolint  
→公式Githubです。大変お世話になりました。
- https://nekopunch.hatenablog.com/entry/2018/10/08/213513  
→こちらの記事を参考にしました。大変お世話になりました。
- https://qiita.com/ryuichi1208/items/d49f3f6ba39c88899049  
→こちらの記事を参考にしました。大変お世話になりました。