curl --request POST \
--url https://api.iotools.cloud/v1/tool/dockerfile-linter \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"dockerfile": "FROM ubuntu:latest\n\nMAINTAINER john@example.com\n\nRUN apt-get update\nRUN apt-get install -y curl wget git\nRUN cd /app && npm install\n\nADD ./config.txt /app/config.txt\n\nENV DB_PASSWORD=mysecretpass123\nENV API_KEY=sk-1234567890abcdef\n\nEXPOSE 8080\nEXPOSE 99999\n\nCOPY . /app\n\nRUN chmod +x /app/start.sh\n\nCMD node server.js"
}
'{
"tool": "dockerfile-linter",
"tool_version": "1.0.1",
"outputs": {
"summary": [
{
"severity": "Errors",
"count": "1"
},
{
"severity": "Warnings",
"count": "9"
},
{
"severity": "Info",
"count": "3"
},
{
"severity": "Total",
"count": "13"
}
],
"issues": [
{
"line": "1",
"severity": "Warning",
"rule": "DL3007",
"message": "Using the :latest tag is not recommended",
"explanation": "Pin to a specific version for reproducible builds (e.g., node:18-alpine instead of node:latest)."
},
{
"line": "3",
"severity": "Warning",
"rule": "DL4000",
"message": "MAINTAINER is deprecated — use LABEL maintainer=\"...\"",
"explanation": "The MAINTAINER instruction is deprecated. Use LABEL maintainer=\"name\" instead."
},
{
"line": "5",
"severity": "Warning",
"rule": "DL3059",
"message": "3 consecutive RUN instructions — consider combining",
"explanation": "Each RUN creates a new layer. Combine with && \\ to reduce layers and image size."
},
{
"line": "6",
"severity": "Warning",
"rule": "DL3009",
"message": "Delete the apt-get lists after installing packages",
"explanation": "Run \"rm -rf /var/lib/apt/lists/*\" after apt-get install to reduce image size."
},
{
"line": "6",
"severity": "Info",
"rule": "DL3015",
"message": "Use --no-install-recommends with apt-get install",
"explanation": "Avoids installing unnecessary recommended packages, reducing image size."
},
{
"line": "7",
"severity": "Warning",
"rule": "DL3003",
"message": "Use WORKDIR to switch directories instead of cd in RUN",
"explanation": "Using cd in RUN does not persist across instructions. Use WORKDIR instead."
},
{
"line": "9",
"severity": "Warning",
"rule": "DL3020",
"message": "Use COPY instead of ADD for files and folders",
"explanation": "ADD has extra features (auto-extraction, URLs) that make it less predictable. Use COPY unless you need ADD features."
},
{
"line": "11",
"severity": "Warning",
"rule": "DL3060",
"message": "Possible secret or credential in ENV",
"explanation": "Avoid hardcoding secrets in Dockerfiles. Use --build-arg, Docker secrets, or runtime environment variables."
},
{
"line": "12",
"severity": "Warning",
"rule": "DL3060",
"message": "Possible secret or credential in ENV",
"explanation": "Avoid hardcoding secrets in Dockerfiles. Use --build-arg, Docker secrets, or runtime environment variables."
},
{
"line": "15",
"severity": "Error",
"rule": "DL3011",
"message": "Invalid EXPOSE port: 99999",
"explanation": "Port numbers must be between 0 and 65535."
},
{
"line": "21",
"severity": "Warning",
"rule": "DL3002",
"message": "No USER instruction found — container will run as root",
"explanation": "Running containers as root is a security risk. Add a USER instruction to run as a non-root user."
},
{
"line": "21",
"severity": "Info",
"rule": "DL3025",
"message": "Use JSON notation for CMD",
"explanation": "Use CMD [\"executable\", \"param1\"] to avoid shell processing issues."
},
{
"line": "21",
"severity": "Info",
"rule": "DL3048",
"message": "Missing HEALTHCHECK instruction",
"explanation": "Add a HEALTHCHECK to let Docker know how to check if the container is still working."
}
],
"formatted": "FROM ubuntu:latest\n\nMAINTAINER john@example.com\n\nRUN apt-get update && \\\n apt-get install -y curl git wget && \\\n cd /app && \\\n npm install\n\nADD ./config.txt /app/config.txt\n\nENV DB_PASSWORD=mysecretpass123\nENV API_KEY=sk-1234567890abcdef\n\nEXPOSE 8080\nEXPOSE 99999\n\nCOPY . /app\n\nRUN chmod +x /app/start.sh\n\nCMD node server.js\n"
},
"credits_used": 3,
"credits_remaining": null
}Utilities
Dockerfile Linter
Lint a Dockerfile against 18 Hadolint-style best-practice rules (unpinned base images, running as root, secrets in ENV, layer bloat, and more) and auto-format it — combining RUN layers and sorting package lists. Runs entirely in your browser.
POST
/
v1
/
tool
/
dockerfile-linter
curl --request POST \
--url https://api.iotools.cloud/v1/tool/dockerfile-linter \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"dockerfile": "FROM ubuntu:latest\n\nMAINTAINER john@example.com\n\nRUN apt-get update\nRUN apt-get install -y curl wget git\nRUN cd /app && npm install\n\nADD ./config.txt /app/config.txt\n\nENV DB_PASSWORD=mysecretpass123\nENV API_KEY=sk-1234567890abcdef\n\nEXPOSE 8080\nEXPOSE 99999\n\nCOPY . /app\n\nRUN chmod +x /app/start.sh\n\nCMD node server.js"
}
'{
"tool": "dockerfile-linter",
"tool_version": "1.0.1",
"outputs": {
"summary": [
{
"severity": "Errors",
"count": "1"
},
{
"severity": "Warnings",
"count": "9"
},
{
"severity": "Info",
"count": "3"
},
{
"severity": "Total",
"count": "13"
}
],
"issues": [
{
"line": "1",
"severity": "Warning",
"rule": "DL3007",
"message": "Using the :latest tag is not recommended",
"explanation": "Pin to a specific version for reproducible builds (e.g., node:18-alpine instead of node:latest)."
},
{
"line": "3",
"severity": "Warning",
"rule": "DL4000",
"message": "MAINTAINER is deprecated — use LABEL maintainer=\"...\"",
"explanation": "The MAINTAINER instruction is deprecated. Use LABEL maintainer=\"name\" instead."
},
{
"line": "5",
"severity": "Warning",
"rule": "DL3059",
"message": "3 consecutive RUN instructions — consider combining",
"explanation": "Each RUN creates a new layer. Combine with && \\ to reduce layers and image size."
},
{
"line": "6",
"severity": "Warning",
"rule": "DL3009",
"message": "Delete the apt-get lists after installing packages",
"explanation": "Run \"rm -rf /var/lib/apt/lists/*\" after apt-get install to reduce image size."
},
{
"line": "6",
"severity": "Info",
"rule": "DL3015",
"message": "Use --no-install-recommends with apt-get install",
"explanation": "Avoids installing unnecessary recommended packages, reducing image size."
},
{
"line": "7",
"severity": "Warning",
"rule": "DL3003",
"message": "Use WORKDIR to switch directories instead of cd in RUN",
"explanation": "Using cd in RUN does not persist across instructions. Use WORKDIR instead."
},
{
"line": "9",
"severity": "Warning",
"rule": "DL3020",
"message": "Use COPY instead of ADD for files and folders",
"explanation": "ADD has extra features (auto-extraction, URLs) that make it less predictable. Use COPY unless you need ADD features."
},
{
"line": "11",
"severity": "Warning",
"rule": "DL3060",
"message": "Possible secret or credential in ENV",
"explanation": "Avoid hardcoding secrets in Dockerfiles. Use --build-arg, Docker secrets, or runtime environment variables."
},
{
"line": "12",
"severity": "Warning",
"rule": "DL3060",
"message": "Possible secret or credential in ENV",
"explanation": "Avoid hardcoding secrets in Dockerfiles. Use --build-arg, Docker secrets, or runtime environment variables."
},
{
"line": "15",
"severity": "Error",
"rule": "DL3011",
"message": "Invalid EXPOSE port: 99999",
"explanation": "Port numbers must be between 0 and 65535."
},
{
"line": "21",
"severity": "Warning",
"rule": "DL3002",
"message": "No USER instruction found — container will run as root",
"explanation": "Running containers as root is a security risk. Add a USER instruction to run as a non-root user."
},
{
"line": "21",
"severity": "Info",
"rule": "DL3025",
"message": "Use JSON notation for CMD",
"explanation": "Use CMD [\"executable\", \"param1\"] to avoid shell processing issues."
},
{
"line": "21",
"severity": "Info",
"rule": "DL3048",
"message": "Missing HEALTHCHECK instruction",
"explanation": "Add a HEALTHCHECK to let Docker know how to check if the container is still working."
}
],
"formatted": "FROM ubuntu:latest\n\nMAINTAINER john@example.com\n\nRUN apt-get update && \\\n apt-get install -y curl git wget && \\\n cd /app && \\\n npm install\n\nADD ./config.txt /app/config.txt\n\nENV DB_PASSWORD=mysecretpass123\nENV API_KEY=sk-1234567890abcdef\n\nEXPOSE 8080\nEXPOSE 99999\n\nCOPY . /app\n\nRUN chmod +x /app/start.sh\n\nCMD node server.js\n"
},
"credits_used": 3,
"credits_remaining": null
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
application/json
Dockerfile
Response
Tool output
Show child attributes
Show child attributes
The tool's slug, echoing the {slug} in the request path.
Output-contract version for this tool.
Credits this call consumed, after any settlement refund. 0 when metering is disabled.
Credits left in the current monthly allowance, or null when metering is disabled.
Correlation id, also sent as x-request-id.
Was this page helpful?
⌘I