GitHub Actions and Docker

Getting started with GitHub Actions and Docker

Our actions

What is Docker buildx?

  • New builder as CLI plugin available since Docker 19.03
  • docker buildx build <> docker build
  • But with many new features
    • Scoped builder instances
    • Building against multiple nodes concurrently
    • External cache source for your build
    • Building multi-platform images
    • Full BuildKit capabilities with container driver
    • High-level build command with bake
  • ๐Ÿš€ Buildx will replace the legacy build command starting Docker 22.05

Classic workflow

  • ๐Ÿ”ซ Demo!

A buildx command in the wild

  • docker buildx build \
    • --push \
    • --cache-from "type=registry,ref=foo/myapp" \
    • --cache-to "type=inline" \
    • --platform "linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64" \
    • --label "org.opencontainers.image.title=myapp" \
    • --label "org.opencontainers.image.source=https://github.com/foo/myapp" \
    • --label "org.opencontainers.image.version=1.0.0" \
    • --label "org.opencontainers.image.licenses=Apache-2.0" \
    • --tag "foo/myapp:v1.0.0" \
    • --tag "foo/myapp:latest" \
    • --file "./main.Dockerfile" \
    • .

With bake

  • docker buildx bake \
    • --push
    • --cache-from "type=registry,ref=foo/myapp" \
    • --cache-to "type=inline" \
    • --platform "linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64" \
    • --label "org.opencontainers.image.title=myapp" \
    • --label "org.opencontainers.image.source=https://github.com/foo/myapp" \
    • --tag "foo/myapp:v1.0.0" \
    • --tag "foo/myapp:latest" \
    • --file "./main.Dockerfile" \
    • .

bake definition

  • Can be a Docker Compose, JSON or HCL โค๏ธ file
  • Multiple files can be specified with --file flag
    • Configurations are merged
  • Default to
    • Compose: docker-compose.yml, docker-compose.yaml
    • JSON: docker-bake.json, docker-bake.override.json
    • HCL: docker-bake.hcl, docker-bake.override.hcl

HCL format

variable "TAG" {
  default = "v0.0.0"
}

group "default" {
  targets = ["image"]
}

target "tag" {
  tags = ["foo/myapp:${TAG}"]
}

target "image" {
  inherits = ["tag"]
  context = "."
  dockerfile = "./main.Dockerfile"
  cache-from = "type=registry,ref=foo/myapp"
  cache-to = "type=inline"
  labels = [
    "org.opencontainers.image.title=myapp",
    "org.opencontainers.image.source=https://github.com/foo/myapp",
    "org.opencontainers.image.version=1.0.0",
    "org.opencontainers.image.licenses=Apache-2.0"
  ]
  tags = ["foo/myapp:latest"]
}

target "image-all" {
  inherits = ["image"]
  platforms = [ "linux/amd64", "linux/arm/v6", "linux/arm/v7", "linux/arm64" ]
}

Thanks for your time!

Docker Buildx is a CLI plugin that extends the docker command with the full support of the features provided by Moby BuildKit builder toolkit

It provides the same user experience as docker build

But with many new features like creating scoped builder instances and building against multiple nodes concurrently

External cache source like the registry using a cache manifest, or local files, ...

Multi-platform images like `linux/amd64`, `linux/arm64` with a single command. No more operations with docker manifest.

As usual to start a build we do this

But hey we could use some external cache through Docker Hub!

Yeah I want to add support for more platforms

Ok let's add some annotations to be compliant with the OCI Image Format Specification

Tag it

Push it

Choose our Dockerfile

And the context

As you can see bake will remove all the constraint related to the flags that we need for our build.

Also you don't actually need --push as well but we recommend it as it is a simple way to switch in command line in your CI for example (PR vs master branch)

With bake we want to let the users define project specific reusable build flows that can then be easily invoked by anyone using a definition file.

Yeah HCL that's the way x)

Merged with the specified order

Default to the following if not specified

HCL adds support for custom build rules allowing better code reuse and different target groups.

A target reflects a single "docker build" invocation with the same options that you would specify for docker build. A group is a grouping of targets.

A group can specify its list of targets with the targets option. A target can inherit build options by setting the inherits option to the list of targets or groups to inherit from.

Multiple files can include the same target and final build options will be determined by merging them together.

Similar to how Terraform provides a way to define variables, the HCL file format also supports variable block definitions. These can be used to define variables with values provided by the current environment or a default value when unset.

A set of generally useful functions provided by go-cty are available for use in HCL files. In addition, user defined functions are also supported.

Let's jump to the demo!

Prints the resulting options of the targets desired to be built

Override target configurations from command line.

The design of bake is in very early stages and we are looking for feedback from users