Is there any way to using hadolint for multiple dockerfiles?

Viewed 708

Hadolint is an awesome tool for linting Dockerfiles. I am trying to integrated to my CI but I am dealing with for run over multiple Dockerfiles. Does someone know how the syntax look like? Here is how my dirs appears to:

dir1/Dockerfile
dir2/Dockerfile
dir3/foo/Dockerfile

in gitlab-ci

  stage: hadolint
  image: hadolint/hadolint:latest-debian
  script:
  - mkdir -p reports
  - |
   hadolint dir1/Dockerfile > reports/dir1.json \
   hadolint dir2/Dockerfile > reports/dir2.json \
   hadolint dir3/foo/Dockerfile > reports/dir3.json 

But the sample above is now working.

2 Answers

So as far as I found it, hadolint runs recursively. So in my case:

  - hadolint */Dockerfile > reports/all_reports.json 

But the problem with this approach is that all reports will be in one file which humper the maintenance and clarity

If you want to keep all reports separated (one per top-level directory), you may want to rely on some shell snippet?

I mean something like:

- |
  find . -name Dockerfile -exec \
    sh -c 'src=${1#./} && { set -x && hadolint "$1"; } | tee -a "reports/${src%%/*}.txt"' sh "{}" \;

Explanation:

  • find . -name Dockerfile loops over all Dockerfiles in the current directory;
  • -exec sh -c '…' runs a subshell for each Dockerfile, setting:
    • $0 = "sh" (dummy value)
    • $1 = "{}" (the full, relative path of the Dockerfile), "{}" and \; being directly related to the find … -exec pattern;
  • src=${1#./} trims the path, replacing ./dir1/Dockerfile with dir1/Dockerfile
  • ${src%%/*} extracts the top-level directory name (dir1/Dockerfile → dir1)
  • and | tee -a … copies the output, appending hadolint's output to the top-level directory report file, for each parsed Dockerfile (while > … should be avoided here for obvious reasons, if you have several Dockerfiles in a single top-level directory).
  • I have replaced the .json extension with .txt as hadolint does not seem to output JSON data.
Related