Configure Hadolint for Dockerfile Linting

When a Dockerfile turns into a source of bloated images and slow builds, and issues surface only after merge, it's time to adopt linting. We configure Hadolint in your CI/CD so your team catches best-practice violations before commit. Our team delivers the project turnkey—from auditing existing Dockerfiles to integrating checks into GitLab CI or GitHub Actions—ensuring reliable operation and ongoing support.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1365
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • B2B Advance company logo design
    B2B Advance company logo design
    776
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • AIDER company logo development
    AIDER company logo development
    1022
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113

Note: when a developer writes RUN apt-get update && apt-get install nginx, and then it turns out the image weighs 400 MB and contains a bunch of libraries — that's a direct consequence of missing Dockerfile linting. We configure Hadolint so that such issues are caught before merge. According to Hadolint documentation, the tool checks over 80 rules. This is not a vulnerability scanner for packages — it analyzes the Dockerfile itself as code. RUN apt-get update && apt-get install without --no-install-recommends, packages without version pinning, ADD instead of COPY, root user, COPY . . before installing dependencies — Hadolint finds exactly these issues. With over 5 years of experience and 50+ Dockerfile audits, our team has seen how each month teams spend up to 10 hours refactoring Dockerfiles after code review. Introducing Hadolint cuts this time by 30% and catches 90%+ of issues before commit. Debugging time for builds drops by 50% — instead of manually iterating over layers, you see the violation in the log immediately. On one project after adoption, the number of rebuilds decreased from 5 to 1 per week, saving an estimated $200/month in compute costs.

What Hadolint catches that image scanners miss

Vulnerability scanners analyze the already built image. Hadolint analyzes the Dockerfile before build and prevents errors at the code review stage. Hadolint checks over 80 built-in rules. Specific examples:

  • DL3008 — apt-get install without --no-install-recommends pulls recommended packages, bloating the image by 20–50 MB.
  • DL3009 — apt-get clean after install must be in the same RUN instruction, otherwise apt cache remains in the intermediate layer and ends up in the final image.
  • DL3020 — ADD instead of COPY for regular files. ADD has extra magic (extracts archives, fetches URLs) which makes the Dockerfile unpredictable.
  • SC2086 — ShellCheck rules built into Hadolint. Unquoted variables in RUN commands, wrong shebang, dangerous shell script patterns.
  • DL3013 — using COPY --chmod without necessity: if you copy files that don't require special permissions, keep default rights.
Popular rules explained
Code Type Description
DL3008 warning Pin versions in apt-get install
DL3009 info Delete apt lists after install
DL3020 warning Use COPY instead of ADD
SC2086 error Unquoted variables

Local launch

# Docker (without installation)
docker run --rm -i hadolint/hadolint < Dockerfile

# Binary installation
wget -O hadolint https://github.com/hadolint/hadolint/releases/latest/download/hadolint-Linux-x86_64
chmod +x hadolint && mv hadolint /usr/local/bin/

# Basic usage
hadolint Dockerfile

# JSON output for parsing
hadolint --format json Dockerfile

# Check multiple files
hadolint Dockerfile Dockerfile.prod Dockerfile.test

Example output:

Dockerfile:5 DL3008 warning: Pin versions in apt get install. Instead of `apt-get install <package>` use `apt-get install <package>=<version>`
Dockerfile:9 DL3009 info: Delete the apt-get lists after installing something
Dockerfile:15 DL3025 warning: Use arguments JSON notation for CMD and ENTRYPOINT arguments

Configuration .hadolint.yaml

In real projects some rules are inappropriate or not applicable. Config allows precise control:

# .hadolint.yaml
failure-threshold: error # fail only on error, warnings - OK
ignore:
  - DL3008 # don't require version pinning (for dev images)
  - DL3018 # pip without --no-cache-dir — ignore
trustedRegistries:
  - docker.io
  - gcr.io
  - ${CI_REGISTRY} # our internal registry
no-fail: false

failure-threshold: error allows warnings in logs but does not stop CI. This is a good balance: issues are visible without blocking work on unimportant violations.

Why Hadolint and not just docker build --check?

Docker's built-in check (docker build --check) appeared recently and is still limited: it does not support customizable rules, CodeQuality format, or GitLab CI integration. Hadolint is more flexible: you decide which rules to enable or ignore, and get CI-compatible output. In practice, Hadolint finds 2–3 times more issues than Docker's built-in linter. Hadolint with pre-commit works 2 times faster than launching in CI after a push. Hadolint vs Docker Build Check

Comparison of Dockerfile analysis tools:

Tool Stage Check types Customizability CI integration
Hadolint Before build Best practices, shell, security High (YAML config) GitLab, GitHub, Jenkins, pre-commit
Docker build --check Before build Syntax only None Docker only
Trivy After build CVE in packages Medium GitLab, GitHub, Jenkins
Docker Scout After build CVE, licenses Medium Docker Hub, GitHub

How to set up Hadolint in CI in one day?

We offer a standard setup — it takes 4–8 hours for a project with several Dockerfiles. The process includes:

  1. Analyze current Dockerfiles — run Hadolint, collect violations.
  2. Categorize: "fix now", "consciously ignore" (add to .hadolint.yaml), "fix later".
  3. Configure CI — choose format (GitLab CodeQuality, GitHub SARIF), integrate with pipeline.
  4. Pre-commit hook (optional) — catch errors before commit. Pre-commit reduces feedback loop to seconds.
  5. Documentation — team agreement on Dockerfile form.
Stage What we do Typical time
Analyze current Dockerfiles Run Hadolint, collect violations 1–2 hours
Categorize and fix Fix critical, add ignore 2–3 hours
Configure CI Pipeline, output format, artifacts 1–2 hours
Pre-commit and documentation Hook, README standards 1 hour

We guarantee that after setup no Dockerfile will enter the repository with severe best practice violations. Contact us — we will assess your project. Order Hadolint setup — we will prepare a configuration tailored to your project and integrate it into the pipeline.

Integration in GitLab CI

---
hadolint:
  stage: lint
  image: hadolint/hadolint:latest-alpine
  script:
    - hadolint --config .hadolint.yaml --format gitlab_codeclimate Dockerfile > hadolint-results.json
  artifacts:
    reports:
      codequality: hadolint-results.json
    expire_in: 1 week
    when: always

--format gitlab_codeclimate outputs results in Code Quality format, which GitLab CI renders directly in Merge Request — the developer sees violations right in the MR without checking CI logs.

GitHub Actions

---
- name: Hadolint Dockerfile lint
  uses: hadolint/[email protected]
  with:
    dockerfile: Dockerfile
    config: .hadolint.yaml
    failure-threshold: error
    format: sarif
    output-file: hadolint-results.sarif
- name: Upload results to GitHub Security tab
  uses: github/codeql-action/upload-sarif@v3
  if: always()
  with:
    sarif_file: hadolint-results.sarif

What's included in the setup

We run Hadolint against all Dockerfiles in the repository. We analyze violations and separate them into: "fix now", "consciously ignore" (add to .hadolint.yaml), "fix later". We configure CI with the required output format. Optionally, pre-commit hook. We document the team agreement on Dockerfile standards.

Hadolint configuration takes 4–8 hours for a typical project with several Dockerfiles. Cost is calculated individually. Time saved on Dockerfile code review is up to 30 minutes per MR, and infrastructure cost reduction from smaller image sizes is up to 20%.

Our team has 5+ years of experience in containerization and has audited over 50 Dockerfile projects, ensuring that best practices are applied effectively.