Skip to content

🐳 parse & print a Dockerfile as JSON, query (e.g. extract base images) using JSONPath.

License

Notifications You must be signed in to change notification settings

keilerkonzept/dockerfile-json

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

dockerfile-json

Prints Dockerfiles as JSON to stdout, optionally evaluates build args. Uses the official Dockerfile parser from buildkit. Plays well with jq.

Contents

Get it

Using go get:

go get -u github.com/keilerkonzept/dockerfile-json

Or download the binary for your platform from the releases page.

Usage

CLI

dockerfile-json [PATHS...]

Usage of dockerfile-json:
  -build-arg value
    	a key/value pair KEY[=VALUE]
  -expand-build-args
    	expand build args (default true)
  -jsonpath string
    	select parts of the output using JSONPath (https://goessner.net/articles/JsonPath)
  -jsonpath-raw
    	when using JSONPath, output raw strings, not JSON values
  -quiet
    	suppress log output (stderr)

Examples

JSON output

Dockerfile

ARG ALPINE_TAG=3.10

FROM alpine:${ALPINE_TAG} AS build
RUN --network=host echo "Hello world" > abc

FROM build AS test
RUN --security=insecure echo "foo" > bar

FROM scratch
COPY --from=build --chown=nobody:nobody abc .
RUN --mount=type=bind,source=./abc,target=/def
CMD ["echo"]
$ dockerfile-json Dockerfile | jq .
{
  "MetaArgs": [
    {
      "Key": "ALPINE_TAG",
      "DefaultValue": "3.10",
      "ProvidedValue": null,
      "Value": "3.10"
    }
  ],
  "Stages": [
    {
      "Name": "build",
      "OrigCmd": "FROM",
      "BaseName": "alpine:3.10",
      "Platform": "",
      "Comment": "",
      "SourceCode": "FROM alpine:${ALPINE_TAG} AS build",
      "Location": [
        {
          "Start": {
            "Line": 3,
            "Character": 0
          },
          "End": {
            "Line": 3,
            "Character": 0
          }
        }
      ],
      "As": "build",
      "From": {
        "Image": "alpine:3.10"
      },
      "Commands": [
        {
          "CmdLine": [
            "echo \"Hello world\" > abc"
          ],
          "Files": null,
          "FlagsUsed": [
            "network"
          ],
          "Mounts": [],
          "Name": "RUN",
          "NetworkMode": "host",
          "PrependShell": true,
          "Security": "sandbox"
        }
      ]
    },
    {
      "Name": "test",
      "OrigCmd": "FROM",
      "BaseName": "build",
      "Platform": "",
      "Comment": "",
      "SourceCode": "FROM build AS test",
      "Location": [
        {
          "Start": {
            "Line": 6,
            "Character": 0
          },
          "End": {
            "Line": 6,
            "Character": 0
          }
        }
      ],
      "As": "test",
      "From": {
        "Stage": {
          "Named": "build",
          "Index": 0
        }
      },
      "Commands": [
        {
          "CmdLine": [
            "echo \"foo\" > bar"
          ],
          "Files": null,
          "FlagsUsed": [
            "security"
          ],
          "Mounts": [],
          "Name": "RUN",
          "NetworkMode": "default",
          "PrependShell": true,
          "Security": "insecure"
        }
      ]
    },
    {
      "Name": "",
      "OrigCmd": "FROM",
      "BaseName": "scratch",
      "Platform": "",
      "Comment": "",
      "SourceCode": "FROM scratch",
      "Location": [
        {
          "Start": {
            "Line": 9,
            "Character": 0
          },
          "End": {
            "Line": 9,
            "Character": 0
          }
        }
      ],
      "From": {
        "Scratch": true
      },
      "Commands": [
        {
          "Chmod": "",
          "Chown": "nobody:nobody",
          "DestPath": ".",
          "ExcludePatterns": null,
          "From": "build",
          "Link": false,
          "Mounts": null,
          "Name": "COPY",
          "NetworkMode": "",
          "Parents": false,
          "Security": "",
          "SourceContents": null,
          "SourcePaths": [
            "abc"
          ]
        },
        {
          "CmdLine": [],
          "Files": null,
          "FlagsUsed": [
            "mount"
          ],
          "Mounts": [
            {
              "Type": "bind",
              "From": "",
              "Source": "",
              "Target": "",
              "ReadOnly": true,
              "SizeLimit": 0,
              "CacheID": "",
              "CacheSharing": "",
              "Required": false,
              "Env": null,
              "Mode": null,
              "UID": null,
              "GID": null
            }
          ],
          "Name": "RUN",
          "NetworkMode": "default",
          "PrependShell": true,
          "Security": "sandbox"
        },
        {
          "CmdLine": [
            "echo"
          ],
          "Files": null,
          "Mounts": null,
          "Name": "CMD",
          "NetworkMode": "",
          "PrependShell": false,
          "Security": ""
        }
      ]
    }
  ]
}

Extract build stage names

Dockerfile

FROM maven:alpine AS build
# ...

FROM build AS test
# ...

FROM openjdk:jre-alpine
# ...
$ dockerfile-json --jsonpath=..As Dockerfile
"build"
"test"

Extract base images

Dockerfile

ARG ALPINE_TAG=3.10
ARG APP_BASE=scratch

FROM alpine:$ALPINE_TAG AS build
# ...

FROM build
# ...

FROM $APP_BASE
# ...

Expand build args, omit stage aliases and scratch

Using jq:

$ dockerfile-json Dockerfile |
    jq '.Stages[] | select(.From | .Stage or .Scratch | not) | .BaseName'
"alpine:3.10"

Using --jsonpath:

$ dockerfile-json --jsonpath=..Image Dockerfile
"alpine:3.10"

Using --jsonpath, --jsonpath-raw output:

$ dockerfile-json --jsonpath=..Image --jsonpath-raw Dockerfile
alpine:3.10

Set build args, omit stage aliases and scratch

$ dockerfile-json --build-arg ALPINE_TAG=hello-world --jsonpath=..Image Dockerfile
"alpine:hello-world"

Expand build args, include all base names

$  dockerfile-json --jsonpath=..BaseName Dockerfile
"alpine:3.10"
"build"
"scratch"

Ignore build args, include all base names

$ dockerfile-json --expand-build-args=false --jsonpath=..BaseName Dockerfile
"alpine:${ALPINE_TAG}"
"build"
"${APP_BASE}"