Query Dockerfiles
Query Dockerfiles with cnquery
Mondoo's docker provider lets you use cnquery to query and analyze Dockerfiles. You can explore base images, instructions, stages, and configuration within your container build definitions.
Requirements
To query Dockerfiles with cnquery, you must have:
- cnquery installed on your workstation
- A Dockerfile or directory containing Dockerfiles
Connect to a Dockerfile
To open a cnquery shell and query a Dockerfile:
cnquery shell docker file FILEPATH| For... | Substitute... |
|---|---|
| FILEPATH | The path to the Dockerfile |
For example:
cnquery shell docker file ./DockerfileTo find and query nested Dockerfiles within a directory:
cnquery shell docker file ./docker/Example queries
Stages
Retrieve all stages in a multi-stage Dockerfile:
cnquery> docker.file.stages
docker.file.stages: [
0: docker.file.stage
1: docker.file.stage
]Base images
Retrieve the base image for the first stage:
cnquery> docker.file.stages[0].from
docker.file.stages[0].from: {
image: "ubuntu"
tag: "22.04"
}Retrieve all FROM instructions:
cnquery> docker.file.stages { from }
docker.file.stages: [
0: {
from: {
image: "node"
tag: "18-alpine"
}
}
1: {
from: {
image: "nginx"
tag: "alpine"
}
}
]RUN instructions
Retrieve all RUN instructions:
cnquery> docker.file.stages[0].run
docker.file.stages[0].run: [
0: "apt-get update"
1: "apt-get install -y curl"
]User configuration
Retrieve the USER instruction:
cnquery> docker.file.stages[0].user
docker.file.stages[0].user: {
user: "appuser"
}Exposed ports
Retrieve exposed ports:
cnquery> docker.file.stages[0].expose
docker.file.stages[0].expose: [
0: {
port: 8080
protocol: "tcp"
}
]Environment variables
Retrieve environment variables:
cnquery> docker.file.stages[0].env
docker.file.stages[0].env: {
NODE_ENV: "production"
APP_PORT: "8080"
}COPY instructions
Retrieve COPY instructions with ownership and permissions:
cnquery> docker.file.stages[0].copy { src dst chown chmod }
docker.file.stages[0].copy: [
0: {
src: ["package.json"]
dst: "/app/"
chown: "appuser:appuser"
chmod: ""
}
]ADD instructions
Retrieve ADD instructions:
cnquery> docker.file.stages[0].add { src dst }
docker.file.stages[0].add: [
0: {
src: ["https://example.com/config.tar.gz"]
dst: "/opt/"
}
]ARG instructions
Retrieve build arguments:
cnquery> docker.file.stages[0].arg { name default }
docker.file.stages[0].arg: [
0: {
name: "NODE_VERSION"
default: "18"
}
]Labels
Retrieve image labels:
cnquery> docker.file.stages[0].labels
docker.file.stages[0].labels: {
maintainer: "team@example.com"
version: "1.0"
}Entrypoint and CMD
Retrieve the entrypoint:
cnquery> docker.file.stages[0].entrypoint
docker.file.stages[0].entrypoint: {
script: "node server.js"
}Retrieve the CMD instruction:
cnquery> docker.file.stages[0].cmd
docker.file.stages[0].cmd: {
script: "npm start"
}All instructions
Retrieve all instructions in order:
cnquery> docker.file.instructions
docker.file.instructions: {
FROM: ["node:18-alpine"]
RUN: ["apt-get update", "apt-get install -y curl"]
COPY: ["package.json /app/"]
...
}Security checks
Verify no stage uses the latest tag:
cnquery> docker.file.stages.all(from.tag != "latest")
docker.file.stages.all: trueVerify COPY is used instead of ADD:
cnquery> docker.file.stages.all(add == empty)
docker.file.stages.all: trueVerify no RUN instructions use sudo:
cnquery> docker.file.stages.all(run.none(script.contains("sudo")))
docker.file.stages.all: trueLearn more
-
To learn more about how the MQL query language works, read Write Effective MQL.
-
For a list of all the Dockerfile resources and fields you can query, read the OS Resource Pack Reference.