GitHub Actions と hadolint (Haskell Dockerfile Linter) を組み合わせて,今まで雑に実装してきた Dockerfile
の静的解析を自動化する環境を作った.できる限り Dockerfile Best Practices を意識していることもあり,警告はあまり多く出なかったけど,やはり CI (Continuous Integration) で気付ける安心感はある!
hadolint (Haskell Dockerfile Linter)
hadolint を使うと Dockerfile
に警告を出してくれる.また Dockerfile
の RUN
は,シェルスクリプトの Linter として有名な ShellCheck を使って警告を出してくれる.例えば FROM centos:latest
のように FROM
に :latest
を使うと,バージョンを指定して!と警告が出る.意識していても漏れることもあり hadolint 便利!
$ hadolint Dockerfile
Dockerfile:1 DL3007 Using latest is prone to errors if the image will ever update. Pin the version explicitly to a release tag
なお,hadolint の Wiki に現時点でサポートされているルール一覧と詳細が載っている.
DL~
は hadolint のルールで,SC~
は ShellCheck のルールとなる.ShellCheck は他にもルールがある.
DL3000
: Use absolute WORKDIR.DL3001
: Command does not make sense in a container.DL3002
: Last user should not be root.DL3003
: Use WORKDIR to switch to a directory.DL3004
: Do not use sudo.DL3005
: Do not use apt-get upgrade or dist-upgrade.DL3006
: Always tag the version of an image explicitly.DL3007
: Using latest is prone to errors if the image will ever update. Pin the version explicitly to a release tag.DL3008
: Pin versions in apt get install.DL3009
: Delete the apt-get lists after installing something.DL3010
: Use ADD for extracting archives into an image.DL3011
: Valid UNIX ports range from 0 to 65535.DL3012
:Provide an email adress or URL as maintainer.🚫DEPRECATEDDL3013
: Pin versions in pip.DL3014
: Use the -y switch.DL3015
: Avoid additional packages by specifying --no-install-recommends.DL3016
: Pin versions in npm.DL3017
: Do not use apk upgradeDL3018
: Pin versions in apk addDL3019
: Use the --no-cache switchDL3020
: Use COPY instead of ADD for files and foldersDL3021
: COPY with more than 2 arguments requires the last argument to end with /DL3022
: COPY --from should reference a previously defined FROM aliasDL3023
: COPY --from cannot reference its own FROM aliasDL3024
: FROM aliases (stage names) must be uniqueDL3025
: Use arguments JSON notation for CMD and ENTRYPOINT argumentsDL3026
: Use only an allowed registry in the FROM imageDL3027
: Do not use apt as it is meant to be an end-user tool, use apt-get or apt-cache instead.DL3028
: Pin versions in gem installDL3029
: Do not use --platform= with FROM.DL4000
: MAINTAINER is deprecatedDL4001
: Either use Wget or Curl but not both.DL4003
: Multiple CMD instructions found. If you list more than one CMD then only the last CMD will take effect.DL4004
: Multiple ENTRYPOINT instructions found. If you list more than one ENTRYPOINT then only the last ENTRYPOINT will take effect.DL4005
: Use SHELL to change the default shellDL4006
: Set the SHELL option -o pipefail before RUN with a pipe inSC2046
: Quote this to prevent word splittingSC2086
: Double quote to prevent globbing and word splitting.
GitHub Actions + hadolint
GitHub Actions と hadolint を組み合わせる場合,Docker Hub に公開された hadolint の Docker イメージを使うこともできるけど,今回は GitHub Actions ですぐに使える Hadolint Action を使うことにした.
さっそく .github/workflows/workflow.yml
に以下を設定する.GitHub に push
をしたら,Hadolint Action を使って Dockerfile
に対して hadolint を実行する単純なワークフローにした.
name: Workflow on: push jobs: build: name: Hadolint runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 - name: Hadolint uses: brpaz/hadolint-action@master
今回サンプルとして,以下のヒドイ Dockerfile
を実装し,GitHub に push
をする.
FROM centos:latest RUN vim hello.txt RUN sudo pwd ADD README.md /app/ EXPOSE 80000
GitHub Actions で実行結果を確認すると,以下のように「計5種類」の警告が出た.
- ❌
DL3007
:FROM
で:latest
を使っている - ❌
DL3001
:vim
コマンドを使っている - ❌
DL3004
:sudo
コマンドを使っている - ❌
DL3020
:COPY
ではなくADD
を使っている - ❌
DL3011
:0 ~ 65535
以外のポートを使っている
Dockerfile:1 DL3007 Using latest is prone to errors if the image will ever update. Pin the version explicitly to a release tag Dockerfile:3 DL3001 For some bash commands it makes no sense running them in a Docker container like `ssh`, `vim`, `shutdown`, `service`, `ps`, `free`, `top`, `kill`, `mount`, `ifconfig` Dockerfile:5 DL3004 Do not use sudo as it leads to unpredictable behavior. Use a tool like gosu to enforce root Dockerfile:7 DL3020 Use COPY instead of ADD for files and folders Dockerfile:9 DL3011 Valid UNIX ports range from 0 to 65535
まとめ
最近 GitHub Actions を使う機会があり,使えば使うほど楽しくなって,今回は hadolint と組み合わせてみた.Dockerfile
を GitHub に push
すると,自動的に静的解析をしてくれるのは便利!オススメ!
関連記事
GitHub Actions に入門するなら「GitHub Learning Lab」を使うと便利!という記事を書いた.
シェルスクリプトを実装するときは ShellCheck をよく使っている.2017年に CircleCI と組み合わせた記事を書いた.