{"id":16788007,"url":"https://hadolint.github.io/hadolint/","last_synced_at":"2025-11-03T04:30:39.583Z","repository":{"id":37251588,"uuid":"46234189","full_name":"hadolint/hadolint","owner":"hadolint","description":"Dockerfile linter, validate inline bash, written in Haskell","archived":false,"fork":false,"pushed_at":"2024-06-12T13:33:43.000Z","size":3911,"stargazers_count":9993,"open_issues_count":197,"forks_count":406,"subscribers_count":69,"default_branch":"master","last_synced_at":"2024-06-16T05:30:17.625Z","etag":null,"topics":["docker","dockerfile","dockerfile-linter","haskell","linter","shellcheck","static-analysis"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hadolint.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-11-15T20:20:58.000Z","updated_at":"2024-06-16T05:30:30.110Z","dependencies_parsed_at":"2024-03-28T15:05:27.569Z","dependency_job_id":"45dde6bb-68a6-4e9b-9547-f36658a87f1a","html_url":"https://github.com/hadolint/hadolint","commit_stats":{"total_commits":933,"total_committers":125,"mean_commits":7.464,"dds":0.6870310825294748,"last_synced_commit":"742b76e3b9b4d45d6716771b0f1fae2fa0069104"},"previous_names":["lukasmartinelli/hadolint"],"tags_count":82,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hadolint%2Fhadolint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hadolint%2Fhadolint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hadolint%2Fhadolint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hadolint%2Fhadolint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hadolint","download_url":"https://codeload.github.com/hadolint/hadolint/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239191775,"owners_count":19597571,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","dockerfile","dockerfile-linter","haskell","linter","shellcheck","static-analysis"],"created_at":"2024-10-13T08:16:34.855Z","updated_at":"2025-11-03T04:30:39.552Z","avatar_url":"https://github.com/hadolint.png","language":"Haskell","funding_links":[],"categories":["Docker"],"sub_categories":["Java"],"readme":"# Haskell Dockerfile Linter\n\n[![Build Status][github-actions-img]][github-actions]\n[![GPL-3 licensed][license-img]][license]\n[![GitHub release][release-img]][release]\n![GitHub downloads][downloads-img]\n\u003cimg align=\"right\" alt=\"pipecat\" width=\"150\"\nsrc=\"https://hadolint.github.io/hadolint/img/cat_container.png\" /\u003e\n\nA smarter Dockerfile linter that helps you build [best practice][] Docker\nimages. The linter parses the Dockerfile into an AST and performs rules on\ntop of the AST. It stands on the shoulders of [ShellCheck][] to lint\nthe Bash code inside `RUN` instructions.\n\n[:globe_with_meridians: **Check the online version on\nhadolint.github.io/hadolint**](https://hadolint.github.io/hadolint)\n[![Screenshot](screenshot.png)](https://hadolint.github.io/hadolint)\n\n## Table of Contents\n\n- [How to use](#how-to-use)\n- [Install](#install)\n- [CLI](#cli)\n- [Configure](#configure)\n- [Non-Posix Shells](#non-posix-shells)\n- [Ignoring Rules](#ignoring-rules)\n  - [Inline ignores](#inline-ignores)\n  - [Global ignores](#global-ignores)\n- [Linting Labels](#linting-labels)\n  - [Note on dealing with variables in labels](#note-on-dealing-with-variables-in-labels)\n- [Integrations](#integrations)\n- [Rules](#rules)\n- [Develop](#develop)\n  - [Setup](#setup)\n  - [REPL](#repl)\n  - [Tests](#tests)\n  - [AST](#ast)\n  - [Building against custom libraries](#building-against-custom-libraries)\n- [Alternatives](#alternatives)\n\n## How to use\n\nYou can run `hadolint` locally to lint your Dockerfile.\n\n```bash\nhadolint \u003cDockerfile\u003e\nhadolint --ignore DL3003 --ignore DL3006 \u003cDockerfile\u003e # exclude specific rules\nhadolint --trusted-registry my-company.com:500 \u003cDockerfile\u003e # Warn when using untrusted FROM images\n```\n\nDocker comes to the rescue, providing an easy way how to run `hadolint` on most\nplatforms.\nJust pipe your `Dockerfile` to `docker run`:\n\n```bash\ndocker run --rm -i hadolint/hadolint \u003c Dockerfile\n# OR\ndocker run --rm -i ghcr.io/hadolint/hadolint \u003c Dockerfile\n```\n\nor using [Podman](https://podman.io/):\n\n```bash\npodman run --rm -i docker.io/hadolint/hadolint \u003c Dockerfile\n# OR\npodman run --rm -i ghcr.io/hadolint/hadolint \u003c Dockerfile\n```\n\nor using Windows PowerShell:\n\n```powershell\ncat .\\Dockerfile | docker run --rm -i hadolint/hadolint\n```\n\n## Install\n\nYou can download prebuilt binaries for OSX, Windows and Linux from the latest\n[release page][]. However, if this does not work for you, please fall back to\ncontainer (Docker), `brew` or source installation.\n\nOn OSX, you can use [brew](https://brew.sh/) to install `hadolint`.\n\n```bash\nbrew install hadolint\n```\n\nOn Windows, you can use [scoop](https://github.com/lukesampson/scoop) to\ninstall `hadolint`.\n\n```batch\nscoop install hadolint\n```\n\nOn distributions that have `nix` installed, you can use the `hadolint`\npackage to run ad-hoc shells or permanently install `hadolint` into\nyour environment.\n\nAs mentioned earlier, `hadolint` is available as a container image:\n\n```bash\ndocker pull hadolint/hadolint\n# OR\ndocker pull ghcr.io/hadolint/hadolint\n```\n\nIf you need a container with shell access, use the Debian or Alpine\nvariants:\n\n```bash\ndocker pull hadolint/hadolint:latest-debian\n# OR\ndocker pull hadolint/hadolint:latest-alpine\n# OR\ndocker pull ghcr.io/hadolint/hadolint:latest-debian\n# OR\ndocker pull ghcr.io/hadolint/hadolint:latest-alpine\n```\n\nYou can also build `hadolint` locally. You need [Haskell][] and the [cabal][]\nbuild tool to build the binary.\n\n```bash\ngit clone https://github.com/hadolint/hadolint \\\n  \u0026\u0026 cd hadolint \\\n  \u0026\u0026 cabal configure \\\n  \u0026\u0026 cabal build \\\n  \u0026\u0026 cabal install\n```\n\nIf you want the\n[VS Code Hadolint](https://github.com/michaellzc/vscode-hadolint)\nextension to use Hadolint in a container, you can use the following\n[wrapper script](https://github.com/hadolint/hadolint/issues/691#issuecomment-932116329):\n\n```bash\n#!/bin/bash\ndockerfile=\"$1\"\nshift\ndocker run --rm -i hadolint/hadolint hadolint \"$@\" - \u003c \"$dockerfile\"\n```\n\n## CLI\n\n```bash\nhadolint --help\n```\n\n```text\nhadolint - Dockerfile Linter written in Haskell\n\nUsage: hadolint [-v|--version] [-c|--config FILENAME] [DOCKERFILE...]\n                [--file-path-in-report FILEPATHINREPORT] [--no-fail]\n                [--no-color] [-V|--verbose] [-f|--format ARG] [--error RULECODE]\n                [--warning RULECODE] [--info RULECODE] [--style RULECODE]\n                [--ignore RULECODE]\n                [--trusted-registry REGISTRY (e.g. docker.io)]\n                [--require-label LABELSCHEMA (e.g. maintainer:text)]\n                [--strict-labels] [--disable-ignore-pragma]\n                [-t|--failure-threshold THRESHOLD]\n  Lint Dockerfile for errors and best practices\n\nAvailable options:\n  -h,--help                Show this help text\n  -v,--version             Show version\n  -c,--config FILENAME     Path to the configuration file\n  --file-path-in-report FILEPATHINREPORT\n                           The file path referenced in the generated report.\n                           This only applies for the 'checkstyle' format and is\n                           useful when running Hadolint with Docker to set the\n                           correct file path.\n  --no-fail                Don't exit with a failure status code when any rule\n                           is violated\n  --no-color               Don't colorize output\n  -V,--verbose             Enables verbose logging of hadolint's output to\n                           stderr\n  -f,--format ARG          The output format for the results [tty | json |\n                           checkstyle | codeclimate | gitlab_codeclimate | gnu |\n                           codacy | sonarqube | sarif] (default: tty)\n  --error RULECODE         Make the rule `RULECODE` have the level `error`\n  --warning RULECODE       Make the rule `RULECODE` have the level `warning`\n  --info RULECODE          Make the rule `RULECODE` have the level `info`\n  --style RULECODE         Make the rule `RULECODE` have the level `style`\n  --ignore RULECODE        A rule to ignore. If present, the ignore list in the\n                           config file is ignored\n  --trusted-registry REGISTRY (e.g. docker.io)\n                           A docker registry to allow to appear in FROM\n                           instructions\n  --require-label LABELSCHEMA (e.g. maintainer:text)\n                           The option --require-label=label:format makes\n                           Hadolint check that the label `label` conforms to\n                           format requirement `format`\n  --strict-labels          Do not permit labels other than specified in\n                           `label-schema`\n  --disable-ignore-pragma  Disable inline ignore pragmas `# hadolint\n                           ignore=DLxxxx`\n  -t,--failure-threshold THRESHOLD\n                           Exit with failure code only when rules with a\n                           severity equal to or above THRESHOLD are violated.\n                           Accepted values: [error | warning | info | style |\n                           ignore | none] (default: info)\n```\n\n## Configure\n\nConfiguration files can be used globally or per project.\nHadolint looks for configuration files in the following locations or their\nplatform specific equivalents in this order and uses the first one exclusively:\n- `$PWD/.hadolint.yaml`\n- `$XDG_CONFIG_HOME/hadolint.yaml`\n- `$HOME/.config/hadolint.yaml`\n- `$HOME/.hadolint/hadolint.yaml or $HOME/hadolint/config.yaml`\n- `$HOME/.hadolint.yaml`\n\nIn windows, the `%LOCALAPPDATA%` environment variable is used instead of \n`XDG_CONFIG_HOME`. Config files can have either `yaml` or `yml` extensions.\n\n`hadolint` full `yaml` config file schema\n\n```yaml\nfailure-threshold: string               # name of threshold level (error | warning | info | style | ignore | none)\nformat: string                          # Output format (tty | json | checkstyle | codeclimate | gitlab_codeclimate | gnu | codacy)\nignored: [string]                       # list of rules\nlabel-schema:                           # See Linting Labels below for specific label-schema details\n  author: string                        # Your name\n  contact: string                       # email address\n  created: timestamp                    # rfc3339 datetime\n  version: string                       # semver\n  documentation: string                 # url\n  git-revision: string                  # hash\n  license: string                       # spdx\nno-color: boolean                       # true | false\nno-fail: boolean                        # true | false\noverride:\n  error: [string]                       # list of rules\n  warning: [string]                     # list of rules\n  info: [string]                        # list of rules\n  style: [string]                       # list of rules\nstrict-labels: boolean                  # true | false\ndisable-ignore-pragma: boolean          # true | false\ntrustedRegistries: string | [string]    # registry or list of registries\n```\n\n`hadolint` supports specifying the ignored rules using a configuration\nfile. The configuration file should be in `yaml` format. This is one\nvalid configuration file as an example:\n\n```yaml\nignored:\n  - DL3000\n  - SC1010\n```\n\nAdditionally, `hadolint` can warn you when images from untrusted\nrepositories are being used in Dockerfiles, you can append the\n`trustedRegistries` keys to the configuration file, as shown below:\n\n```yaml\nignored:\n  - DL3000\n  - SC1010\n\ntrustedRegistries:\n  - docker.io\n  - my-company.com:5000\n  - \"*.gcr.io\"\n```\n\nIf you want to override the severity of specific rules, you can do that too:\n\n```yaml\noverride:\n  error:\n    - DL3001\n    - DL3002\n  warning:\n    - DL3042\n    - DL3033\n  info:\n    - DL3032\n  style:\n    - DL3015\n```\n\n`failure-threshold` Exit with failure code only when rules with a\nseverity above THRESHOLD are violated (Available in v2.6.0+)\n\n```yaml\nfailure-threshold: info\noverride:\n  warning:\n    - DL3042\n    - DL3033\n  info:\n    - DL3032\n```\n\nAdditionally, you can pass a custom configuration file in the command line with\nthe `--config` option\n\n```bash\nhadolint --config /path/to/config.yaml Dockerfile\n```\n\nTo pass a custom configuration file (using relative or absolute path) to\na container, use the following command:\n\n```bash\ndocker run --rm -i -v /your/path/to/hadolint.yaml:/.config/hadolint.yaml hadolint/hadolint \u003c Dockerfile\n# OR\ndocker run --rm -i -v /your/path/to/hadolint.yaml:/.config/hadolint.yaml ghcr.io/hadolint/hadolint \u003c Dockerfile\n```\n\nIn addition to config files, Hadolint can be configured with environment\nvariables.\n```bash\nNO_COLOR=1                               # Set or unset. See https://no-color.org\nHADOLINT_NOFAIL=1                        # Truthy value e.g. 1, true or yes\nHADOLINT_VERBOSE=1                       # Truthy value e.g. 1, true or yes\nHADOLINT_FORMAT=json                     # Output format (tty | json | checkstyle | codeclimate | gitlab_codeclimate | gnu | codacy | sarif )\nHADOLINT_FAILURE_THRESHOLD=info          # threshold level (error | warning | info | style | ignore | none)\nHADOLINT_OVERRIDE_ERROR=DL3010,DL3020    # comma separated list of rule codes\nHADOLINT_OVERRIDE_WARNING=DL3010,DL3020  # comma separated list of rule codes\nHADOLINT_OVERRIDE_INFO=DL3010,DL3020     # comma separated list of rule codes\nHADOLINT_OVERRIDE_STYLE=DL3010,DL3020    # comma separated list of rule codes\nHADOLINT_IGNORE=DL3010,DL3020            # comma separated list of rule codes\nHADOLINT_STRICT_LABELS=1                 # Truthy value e.g. 1, true or yes\nHADOLINT_DISABLE_IGNORE_PRAGMA=1         # Truthy value e.g. 1, true or yes\nHADOLINT_TRUSTED_REGISTRIES=docker.io    # comma separated list of registry urls\nHADOLINT_REQUIRE_LABELS=maintainer:text  # comma separated list of label schema items\n```\n\n## Non-Posix Shells\n\nWhen using base images with non-posix shells as default (e.g. Windows based\nimages) a special pragma `hadolint shell` can specify which shell the base image\nuses, so that Hadolint can automatically ignore all shell-specific rules.\n\n```Dockerfile\nFROM mcr.microsoft.com/windows/servercore:ltsc2022\n# hadolint shell=powershell\nRUN Get-Process notepad | Stop-Process\n```\n\n## Ignoring Rules\n\n### Inline ignores\n\nIt is also possible to ignore rules by adding a special comment directly\nabove the Dockerfile statement for which you want to make an exception for.\nSuch comments look like\n`# hadolint ignore=DL3001,SC1081`. For example:\n\n```dockerfile\n# hadolint ignore=DL3006\nFROM ubuntu\n\n# hadolint ignore=DL3003,SC1035\nRUN cd /tmp \u0026\u0026 echo \"hello!\"\n```\n\nThe comment \"inline ignores\" applies only to the statement following it.\n\n### Global ignores\n\nRules can also be ignored on a per-file basis using the global ignore pragma.\nIt works just like inline ignores, except that it applies to the whole file\ninstead of just the next line.\n\n```dockerfile\n# hadolint global ignore=DL3003,DL3006,SC1035\nFROM ubuntu\n\nRUN cd /tmp \u0026\u0026 echo \"foo\"\n```\n\n## Linting Labels\n\nHadolint is able to check if specific labels are present and conform\nto a predefined label schema.\nFirst, a label schema must be defined either via the command line:\n\n```bash\nhadolint --require-label author:text --require-label version:semver Dockerfile\n```\n\nor via the config file:\n\n```yaml\nlabel-schema:\n  author: text\n  contact: email\n  created: rfc3339\n  version: semver\n  documentation: url\n  git-revision: hash\n  license: spdx\n```\n\nThe value of a label can be either of `text`, `url`, `semver`, `hash` or\n`rfc3339`:\n| Schema  | Description                                        |\n|:--------|:---------------------------------------------------|\n| text    | Anything                                           |\n| rfc3339 | A time, formatted according to [RFC 3339][rfc3339] |\n| semver  | A [semantic version][semver]                       |\n| url     | A URI as described in [RFC 3986][rfc3986]          |\n| hash    | Either a short or a long [Git hash][githash]       |\n| spdx    | An [SPDX license identifier][spdxid]               |\n| email   | An email address conforming to [RFC 5322][rfc5322] |\n\nBy default, Hadolint ignores any label that is not specified in the label schema. To\nwarn against such additional labels, turn on strict labels, using the command line:\n\n```bash\nhadolint --strict-labels --require-label version:semver Dockerfile\n```\n\nor the config file:\n\n```yaml\nstrict-labels: true\n```\n\nWhen strict labels is enabled, but no label schema is specified, `hadolint`\nwill warn if any label is present.\n\n### Note on dealing with variables in labels\n\nIt is a common pattern to fill the value of a label not statically, but rather\ndynamically at build time by using a variable:\n\n```dockerfile\nFROM debian:buster\nARG VERSION=\"du-jour\"\nLABEL version=\"${VERSION}\"\n```\n\nTo allow this, the label schema must specify `text` as value for that label:\n\n```yaml\nlabel-schema:\n  version: text\n```\n\n## Integrations\n\nTo get most of `hadolint`, it is useful to integrate it as a check in your CI\nor into your editor, or as a pre-commit hook, to lint your `Dockerfile` as you\nwrite it. See our [Integration][] docs.\n\n- [Code Review Platform Integrations][]\n- [Continuous Integrations][]\n- [Editor Integrations][]\n- [Version Control Integrations][]\n\n## Rules\n\nAn incomplete list of implemented rules. Click on the error code to get more\ndetailed information.\n\n-   Rules with the prefix `DL` are from `hadolint`. Have a look at\n    `Rules.hs` to find the implementation of the rules.\n\n-   Rules with the `SC` prefix are from **ShellCheck** (only the most\n    common rules are listed, there are dozens more).\n\nPlease [create an issue][] if you have an idea for a good rule.\n\n\u003c!--lint disable maximum-line-length--\u003e\n\n| Rule                                                         | Default Severity | Description                                                                                                                                         |\n| :----------------------------------------------------------- | :--------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------- |\n| [DL1001](https://github.com/hadolint/hadolint/wiki/DL1001)   | Ignore           | Please refrain from using inline ignore pragmas `# hadolint ignore=DLxxxx`.                                                                         |\n| [DL3000](https://github.com/hadolint/hadolint/wiki/DL3000)   | Error            | Use absolute WORKDIR.                                                                                                                               |\n| [DL3001](https://github.com/hadolint/hadolint/wiki/DL3001)   | Info             | 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. |\n| [DL3002](https://github.com/hadolint/hadolint/wiki/DL3002)   | Warning          | Last user should not be root.                                                                                                                       |\n| [DL3003](https://github.com/hadolint/hadolint/wiki/DL3003)   | Warning          | Use WORKDIR to switch to a directory.                                                                                                               |\n| [DL3004](https://github.com/hadolint/hadolint/wiki/DL3004)   | Error            | Do not use sudo as it leads to unpredictable behavior. Use a tool like gosu to enforce root.                                                        |\n| [DL3006](https://github.com/hadolint/hadolint/wiki/DL3006)   | Warning          | Always tag the version of an image explicitly.                                                                                                      |\n| [DL3007](https://github.com/hadolint/hadolint/wiki/DL3007)   | Warning          | Using latest is prone to errors if the image will ever update. Pin the version explicitly to a release tag.                                         |\n| [DL3008](https://github.com/hadolint/hadolint/wiki/DL3008)   | Warning          | Pin versions in `apt-get install`.                                                                                                                  |\n| [DL3009](https://github.com/hadolint/hadolint/wiki/DL3009)   | Info             | Delete the apt-get lists after installing something.                                                                                                |\n| [DL3010](https://github.com/hadolint/hadolint/wiki/DL3010)   | Info             | Use ADD for extracting archives into an image.                                                                                                      |\n| [DL3011](https://github.com/hadolint/hadolint/wiki/DL3011)   | Error            | Valid UNIX ports range from 0 to 65535.                                                                                                             |\n| [DL3012](https://github.com/hadolint/hadolint/wiki/DL3012)   | Error            | Multiple `HEALTHCHECK` instructions.                                                                                                                |\n| [DL3013](https://github.com/hadolint/hadolint/wiki/DL3013)   | Warning          | Pin versions in pip.                                                                                                                                |\n| [DL3014](https://github.com/hadolint/hadolint/wiki/DL3014)   | Warning          | Use the `-y` switch.                                                                                                                                |\n| [DL3015](https://github.com/hadolint/hadolint/wiki/DL3015)   | Info             | Avoid additional packages by specifying `--no-install-recommends`.                                                                                  |\n| [DL3016](https://github.com/hadolint/hadolint/wiki/DL3016)   | Warning          | Pin versions in `npm`.                                                                                                                              |\n| [DL3018](https://github.com/hadolint/hadolint/wiki/DL3018)   | Warning          | Pin versions in `apk add`. Instead of `apk add \u003cpackage\u003e` use `apk add \u003cpackage\u003e=\u003cversion\u003e`.                                                        |\n| [DL3019](https://github.com/hadolint/hadolint/wiki/DL3019)   | Info             | Use the `--no-cache` switch to avoid the need to use `--update` and remove `/var/cache/apk/*` when done installing packages.                        |\n| [DL3020](https://github.com/hadolint/hadolint/wiki/DL3020)   | Error            | Use `COPY` instead of `ADD` for files and folders.                                                                                                  |\n| [DL3021](https://github.com/hadolint/hadolint/wiki/DL3021)   | Error            | `COPY` with more than 2 arguments requires the last argument to end with `/`                                                                        |\n| [DL3022](https://github.com/hadolint/hadolint/wiki/DL3022)   | Warning          | `COPY --from` should reference a previously defined `FROM` alias                                                                                    |\n| [DL3023](https://github.com/hadolint/hadolint/wiki/DL3023)   | Error            | `COPY --from` cannot reference its own `FROM` alias                                                                                                 |\n| [DL3024](https://github.com/hadolint/hadolint/wiki/DL3024)   | Error            | `FROM` aliases (stage names) must be unique                                                                                                         |\n| [DL3025](https://github.com/hadolint/hadolint/wiki/DL3025)   | Warning          | Use arguments JSON notation for CMD and ENTRYPOINT arguments                                                                                        |\n| [DL3026](https://github.com/hadolint/hadolint/wiki/DL3026)   | Error            | Use only an allowed registry in the `FROM image`                                                                                                    |\n| [DL3027](https://github.com/hadolint/hadolint/wiki/DL3027)   | Warning          | Do not use `apt` as it is meant to be an end-user tool, use `apt-get` or `apt-cache` instead                                                        |\n| [DL3028](https://github.com/hadolint/hadolint/wiki/DL3028)   | Warning          | Pin versions in gem install. Instead of `gem install \u003cgem\u003e` use `gem install \u003cgem\u003e:\u003cversion\u003e`                                                       |\n| [DL3029](https://github.com/hadolint/hadolint/wiki/DL3029)   | Warning          | Do not use --platform flag with FROM.                                                                                                               |\n| [DL3030](https://github.com/hadolint/hadolint/wiki/DL3030)   | Warning          | Use the `-y` switch to avoid manual input `yum install -y \u003cpackage\u003e`                                                                                |\n| [DL3032](https://github.com/hadolint/hadolint/wiki/DL3032)   | Warning          | `yum clean all` missing after yum command.                                                                                                          |\n| [DL3033](https://github.com/hadolint/hadolint/wiki/DL3033)   | Warning          | Specify version with `yum install -y \u003cpackage\u003e-\u003cversion\u003e`                                                                                           |\n| [DL3034](https://github.com/hadolint/hadolint/wiki/DL3034)   | Warning          | Non-interactive switch missing from `zypper` command: `zypper install -y`                                                                           |\n| [DL3035](https://github.com/hadolint/hadolint/wiki/DL3035)   | Warning          | Do not use `zypper dist-upgrade`.                                                                                                                   |\n| [DL3036](https://github.com/hadolint/hadolint/wiki/DL3036)   | Warning          | `zypper clean` missing after zypper use.                                                                                                            |\n| [DL3037](https://github.com/hadolint/hadolint/wiki/DL3037)   | Warning          | Specify version with `zypper install -y \u003cpackage\u003e[=]\u003cversion\u003e`.                                                                                     |\n| [DL3038](https://github.com/hadolint/hadolint/wiki/DL3038)   | Warning          | Use the `-y` switch to avoid manual input `dnf install -y \u003cpackage\u003e`                                                                                |\n| [DL3040](https://github.com/hadolint/hadolint/wiki/DL3040)   | Warning          | `dnf clean all` missing after dnf command.                                                                                                          |\n| [DL3041](https://github.com/hadolint/hadolint/wiki/DL3041)   | Warning          | Specify version with `dnf install -y \u003cpackage\u003e-\u003cversion\u003e`                                                                                           |\n| [DL3042](https://github.com/hadolint/hadolint/wiki/DL3042)   | Warning          | Avoid cache directory with `pip install --no-cache-dir \u003cpackage\u003e`.                                                                                  |\n| [DL3043](https://github.com/hadolint/hadolint/wiki/DL3043)   | Error            | `ONBUILD`, `FROM` or `MAINTAINER` triggered from within `ONBUILD` instruction.                                                                      |\n| [DL3044](https://github.com/hadolint/hadolint/wiki/DL3044)   | Error            | Do not refer to an environment variable within the same `ENV` statement where it is defined.                                                        |\n| [DL3045](https://github.com/hadolint/hadolint/wiki/DL3045)   | Warning          | `COPY` to a relative destination without `WORKDIR` set.                                                                                             |\n| [DL3046](https://github.com/hadolint/hadolint/wiki/DL3046)   | Warning          | `useradd` without flag `-l` and high UID will result in excessively large Image.                                                                    |\n| [DL3047](https://github.com/hadolint/hadolint/wiki/DL3047)   | Info             | `wget` without flag `--progress` will result in excessively bloated build logs when downloading larger files.                                       |\n| [DL3048](https://github.com/hadolint/hadolint/wiki/DL3048)   | Style            | Invalid Label Key                                                                                                                                   |\n| [DL3049](https://github.com/hadolint/hadolint/wiki/DL3049)   | Info             | Label `\u003clabel\u003e` is missing.                                                                                                                         |\n| [DL3050](https://github.com/hadolint/hadolint/wiki/DL3050)   | Info             | Superfluous label(s) present.                                                                                                                       |\n| [DL3051](https://github.com/hadolint/hadolint/wiki/DL3051)   | Warning          | Label `\u003clabel\u003e` is empty.                                                                                                                           |\n| [DL3052](https://github.com/hadolint/hadolint/wiki/DL3052)   | Warning          | Label `\u003clabel\u003e` is not a valid URL.                                                                                                                 |\n| [DL3053](https://github.com/hadolint/hadolint/wiki/DL3053)   | Warning          | Label `\u003clabel\u003e` is not a valid time format - must conform to RFC3339.                                                                               |\n| [DL3054](https://github.com/hadolint/hadolint/wiki/DL3054)   | Warning          | Label `\u003clabel\u003e` is not a valid SPDX license identifier.                                                                                             |\n| [DL3055](https://github.com/hadolint/hadolint/wiki/DL3055)   | Warning          | Label `\u003clabel\u003e` is not a valid git hash.                                                                                                            |\n| [DL3056](https://github.com/hadolint/hadolint/wiki/DL3056)   | Warning          | Label `\u003clabel\u003e` does not conform to semantic versioning.                                                                                            |\n| [DL3057](https://github.com/hadolint/hadolint/wiki/DL3057)   | Ignore           | `HEALTHCHECK` instruction missing.                                                                                                                  |\n| [DL3058](https://github.com/hadolint/hadolint/wiki/DL3058)   | Warning          | Label `\u003clabel\u003e` is not a valid email format - must conform to RFC5322.                                                                              |\n| [DL3059](https://github.com/hadolint/hadolint/wiki/DL3059)   | Info             | Multiple consecutive `RUN` instructions. Consider consolidation.                                                                                    |\n| [DL3060](https://github.com/hadolint/hadolint/wiki/DL3060)   | Info             | `yarn cache clean` missing after `yarn install` was run.                                                                                            |\n| [DL3061](https://github.com/hadolint/hadolint/wiki/DL3061)   | Error            | Invalid instruction order. Dockerfile must begin with `FROM`, `ARG` or comment.                                                                     |\n| [DL4000](https://github.com/hadolint/hadolint/wiki/DL4000)   | Error            | `MAINTAINER` is deprecated.                                                                                                                         |\n| [DL4001](https://github.com/hadolint/hadolint/wiki/DL4001)   | Warning          | Either use Wget or Curl but not both.                                                                                                               |\n| [DL4003](https://github.com/hadolint/hadolint/wiki/DL4003)   | Warning          | Multiple `CMD` instructions found.                                                                                                                  |\n| [DL4004](https://github.com/hadolint/hadolint/wiki/DL4004)   | Error            | Multiple `ENTRYPOINT` instructions found.                                                                                                           |\n| [DL4005](https://github.com/hadolint/hadolint/wiki/DL4005)   | Warning          | Use `SHELL` to change the default shell.                                                                                                            |\n| [DL4006](https://github.com/hadolint/hadolint/wiki/DL4006)   | Warning          | Set the `SHELL` option -o pipefail before `RUN` with a pipe in it                                                                                   |\n| [SC1000](https://github.com/koalaman/shellcheck/wiki/SC1000) |                  | `$` is not used specially and should therefore be escaped.                                                                                          |\n| [SC1001](https://github.com/koalaman/shellcheck/wiki/SC1001) |                  | This `\\c` will be a regular `'c'` in this context.                                                                                                  |\n| [SC1007](https://github.com/koalaman/shellcheck/wiki/SC1007) |                  | Remove space after `=` if trying to assign a value (or for empty string, use `var='' ...`).                                                         |\n| [SC1010](https://github.com/koalaman/shellcheck/wiki/SC1010) |                  | Use semicolon or linefeed before `done` (or quote to make it literal).                                                                              |\n| [SC1018](https://github.com/koalaman/shellcheck/wiki/SC1018) |                  | This is a unicode non-breaking space. Delete it and retype as space.                                                                                |\n| [SC1035](https://github.com/koalaman/shellcheck/wiki/SC1035) |                  | You need a space here                                                                                                                               |\n| [SC1045](https://github.com/koalaman/shellcheck/wiki/SC1045) |                  | It's not `foo \u0026; bar`, just `foo \u0026 bar`.                                                                                                            |\n| [SC1065](https://github.com/koalaman/shellcheck/wiki/SC1065) |                  | Trying to declare parameters? Don't. Use `()` and refer to params as `$1`, `$2` etc.                                                                |\n| [SC1066](https://github.com/koalaman/shellcheck/wiki/SC1066) |                  | Don't use $ on the left side of assignments.                                                                                                        |\n| [SC1068](https://github.com/koalaman/shellcheck/wiki/SC1068) |                  | Don't put spaces around the `=` in assignments.                                                                                                     |\n| [SC1077](https://github.com/koalaman/shellcheck/wiki/SC1077) |                  | For command expansion, the tick should slant left (\\` vs ´).                                                                                        |\n| [SC1078](https://github.com/koalaman/shellcheck/wiki/SC1078) |                  | Did you forget to close this double-quoted string?                                                                                                  |\n| [SC1079](https://github.com/koalaman/shellcheck/wiki/SC1079) |                  | This is actually an end quote, but due to next char, it looks suspect.                                                                              |\n| [SC1081](https://github.com/koalaman/shellcheck/wiki/SC1081) |                  | Scripts are case sensitive. Use `if`, not `If`.                                                                                                     |\n| [SC1083](https://github.com/koalaman/shellcheck/wiki/SC1083) |                  | This `{/}` is literal. Check expression (missing `;/\\n`?) or quote it.                                                                              |\n| [SC1086](https://github.com/koalaman/shellcheck/wiki/SC1086) |                  | Don't use `$` on the iterator name in for loops.                                                                                                    |\n| [SC1087](https://github.com/koalaman/shellcheck/wiki/SC1087) |                  | Braces are required when expanding arrays, as in `${array[idx]}`.                                                                                   |\n| [SC1095](https://github.com/koalaman/shellcheck/wiki/SC1095) |                  | You need a space or linefeed between the function name and body.                                                                                    |\n| [SC1097](https://github.com/koalaman/shellcheck/wiki/SC1097) |                  | Unexpected `==`. For assignment, use `=`. For comparison, use `[ .. ]` or `[[ .. ]]`.                                                               |\n| [SC1098](https://github.com/koalaman/shellcheck/wiki/SC1098) |                  | Quote/escape special characters when using `eval`, e.g. `eval \"a=(b)\"`.                                                                             |\n| [SC1099](https://github.com/koalaman/shellcheck/wiki/SC1099) |                  | You need a space before the `#`.                                                                                                                    |\n| [SC2002](https://github.com/koalaman/shellcheck/wiki/SC2002) |                  | Useless cat. Consider \u003ccode\u003ecmd \u003c file \u0026#124; ..\u003c/code\u003e or \u003ccode\u003ecmd file \u0026#124; ..\u003c/code\u003e instead.                                                 |\n| [SC2015](https://github.com/koalaman/shellcheck/wiki/SC2015) |                  | Note that \u003ccode\u003eA \u0026\u0026 B \u0026#124;\u0026#124; C\u003c/code\u003e is not if-then-else. C may run when A is true.                                                         |\n| [SC2026](https://github.com/koalaman/shellcheck/wiki/SC2026) |                  | This word is outside of quotes. Did you intend to 'nest '\"'single quotes'\"' instead'?                                                               |\n| [SC2028](https://github.com/koalaman/shellcheck/wiki/SC2028) |                  | `echo` won't expand escape sequences. Consider `printf`.                                                                                            |\n| [SC2035](https://github.com/koalaman/shellcheck/wiki/SC2035) |                  | Use `./*glob*` or `-- *glob*` so names with dashes won't become options.                                                                            |\n| [SC2039](https://github.com/koalaman/shellcheck/wiki/SC2039) |                  | In POSIX sh, something is undefined.                                                                                                                |\n| [SC2046](https://github.com/koalaman/shellcheck/wiki/SC2046) |                  | Quote this to prevent word splitting                                                                                                                |\n| [SC2086](https://github.com/koalaman/shellcheck/wiki/SC2086) |                  | Double quote to prevent globbing and word splitting.                                                                                                |\n| [SC2140](https://github.com/koalaman/shellcheck/wiki/SC2140) |                  | Word is in the form `\"A\"B\"C\"` (B indicated). Did you mean `\"ABC\"` or `\"A\\\"B\\\"C\"`?                                                                   |\n| [SC2154](https://github.com/koalaman/shellcheck/wiki/SC2154) |                  | var is referenced but not assigned.                                                                                                                 |\n| [SC2155](https://github.com/koalaman/shellcheck/wiki/SC2155) |                  | Declare and assign separately to avoid masking return values.                                                                                       |\n| [SC2164](https://github.com/koalaman/shellcheck/wiki/SC2164) |                  | Use \u003ccode\u003ecd ... \u0026#124;\u0026#124; exit\u003c/code\u003e in case `cd` fails.                                                                                       |\n\n\u003c!--lint enable maximum-line-length--\u003e\n\n## Develop\n\nIf you are an experienced Haskeller, we would be very grateful if you would\ntear our code apart in a review.\n\nTo compile, you will need a recent Haskell environment and `cabal-install`.\n\n### Setup\n\n1.  Clone repository\n\n    ```bash\n    git clone --recursive git@github.com:hadolint/hadolint.git\n    ```\n\n1.  Install dependencies and compile source\n\n    ```bash\n    cabal configure\n    cabal build\n    ```\n\n1.  (Optional) Install Hadolint on your system\n\n    ```bash\n    cabal install\n    ```\n\n### REPL\n\nThe easiest way to try out the parser is using the REPL.\n\n```bash\n# start the repl\ncabal repl\n# overload strings to be able to use Text\n:set -XOverloadedStrings\n# import parser library\nimport Language.Docker\n# parse instruction and look at AST representation\nparseText \"FROM debian:jessie\"\n```\n\n### Tests\n\nCompile with unit tests and run them:\n\n```bash\ncabal configure --enable-tests\ncabal build --enable-tests\ncabal test\n```\n\nRun integration tests:\n\n```bash\n./integration_test.sh\n```\n\n### AST\n\nDockerfile syntax is fully described in the [Dockerfile reference][].\nJust take a look at [Syntax.hs][] in the `language-docker` project to see\nthe AST definition.\n\n### Building against custom libraries\n\nHadolint uses many libraries to do the dirty work. In particular,\nlanguage-docker is used to parse Dockerfiles and produce an AST which then can\nbe analyzed. To build Hadolint against a custom version of such libraries, do\nthe following. This example uses language-docker, but it would work with any\nother library as well.\n\n 1) In the same directory (e.g. `/home/user/repos`) clone Hadolint and\n    language-docker git repositories\n\n```bash\ncd /home/user/repos\ngit clone https://github.com/hadolint/hadolint.git\ngit clone https://github.com/hadolint/language-docker.git\n```\n\n 2) Make your modifications to language-docker\n\n 3) In the Hadolint repo, edit the `cabal.project` file, such that the\n    `packages` property points to the other repo too\n\n```yaml\n[...]\npackages:\n  .\n  ../language-docker\n[...]\n```\n\n 4) Recompile Hadolint and run the tests\n```bash\ncd /home/user/repos/hadolint\ncabal configure --enable-tests\ncabal build --enable-tests\ncabal test\n```\n\n## Alternatives\n\n-   replicatedhq/[dockerfilelint](https://github.com/replicatedhq/dockerfilelint),\n    the other linter used by the [super-linter](https://github.com/github/super-linter/blob/main/README.md#supported-linters)\n\n-   RedCoolBeans/[dockerlint](https://github.com/RedCoolBeans/dockerlint/)\n\n-   projectatomic/[dockerfile_lint](https://github.com/projectatomic/dockerfile_lint/)\n\n\u003c!-- References --\u003e\n\n[github-actions-img]: https://github.com/hadolint/hadolint/workflows/Haskell%20Tests/badge.svg?branch=master\n[github-actions]: https://travis-ci.org/hadolint/hadolint/actions\n[license-img]: https://img.shields.io/badge/license-GPL--3-blue.svg\n[license]: https://tldrlegal.com/l/gpl-3.0\n[release-img]: https://img.shields.io/github/release/hadolint/hadolint.svg\n[release]: https://github.com/hadolint/hadolint/releases/latest\n[downloads-img]: https://img.shields.io/github/downloads/hadolint/hadolint/total.svg\n[best practice]: https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices\n[shellcheck]: https://github.com/koalaman/shellcheck\n[release page]: https://github.com/hadolint/hadolint/releases/latest\n[haskell]: https://www.haskell.org/downloads/\n[cabal]: https://www.haskell.org/cabal/\n[integration]: docs/INTEGRATION.md\n[code review platform integrations]: docs/INTEGRATION.md#code-review\n[continuous integrations]: docs/INTEGRATION.md#continuous-integration\n[editor integrations]: docs/INTEGRATION.md#editors\n[version control integrations]: docs/INTEGRATION.md#version-control\n[create an issue]: https://github.com/hadolint/hadolint/issues/new\n[dockerfile reference]: http://docs.docker.com/engine/reference/builder/\n[syntax.hs]: https://www.stackage.org/haddock/nightly-2022-11-15/language-docker-12.0.0/Language-Docker-Syntax.html\n[rfc3339]: https://www.ietf.org/rfc/rfc3339.txt\n[semver]: https://semver.org/\n[rfc3986]: https://www.ietf.org/rfc/rfc3986.txt\n[githash]: https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection\n[spdxid]: https://spdx.org/licenses/\n[rfc5322]: https://www.ietf.org/rfc/rfc5322.txt\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/hadolint.github.io%2Fhadolint%2F","html_url":"https://awesome.ecosyste.ms/projects/hadolint.github.io%2Fhadolint%2F","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/hadolint.github.io%2Fhadolint%2F/lists"}