Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow option to build image with Docker buildx Bake #311

Open
c-ameron opened this issue Sep 26, 2023 · 2 comments
Open

Allow option to build image with Docker buildx Bake #311

c-ameron opened this issue Sep 26, 2023 · 2 comments

Comments

@c-ameron
Copy link

It would be great to allow the option to use Docker's Bake cli tool to build images as well.
https://docs.docker.com/engine/reference/commandline/buildx_bake/

In my repos, we're using bake internally to build images (including sourcing remote docker bake files), it would be great to have this option as well so we could have parity with devcontainers.

Could potentially be merged with this feature request on allow extra flags to the buildx command #85

Thanks!

@ruffsl
Copy link

ruffsl commented Apr 14, 2024

This would be awesome! My team is evaluating the use of Docker buildx Bake to segment our Dockerfiles while keeping them DRY by having the build stages defined in one Dockerfile for reuse across all others. However, it becomes tricky if we then want to use the same Dockerfiles with Dev Containers, given that by taking advantage of advance bake file context features, the Dockerfiles themselves may not be as simple to rebuild, in the same manner, using singular docker buildx build command.

Perhaps an additional top level keyword could be use, given that docker buildx bake may not support all the same set of CLI arguments as docker buildx build. This could be make exclusive to the existing keywords image and build. E.g:

{
    "name": "Example",
    // Uncomment to bake image
    "bake": {
        "bakefiles": [ "../docker-bake.hcl" ],
        "target": "foo",
        "pull": "true",
        "set": [
            "target.args.mybuildarg=value",
            "foo*.args.mybuildarg=value",
        ],
    },
    // Uncomment to build image
    "build": {
        "dockerfile": "../Dockerfile",
        "context": "..",
        "target": "foo",
        "cacheFrom": [
            "ghcr.io/pre/built:image"
        ]
    },
    // Uncomment to use pre-built image
    "image": "pre/built:image",
}

One hurtle may be in how current tools auto generate a Dockerfile to define the dev container image by appending subsequent stages to the original Dockerfile. If there is no single Dockerfile, what would be used instead.

I'd propose adding a subsequent target that points the users provided target (or default target if none is specified from the devcontainer.json), that then includes that users provided target as context to base its own Dockerfile with. E.g

docker-bake.hcl - user provided

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

target "foo" {
  target = "some-dockerfile-stage"
  dockerfile = "path/to/Dockerfile"
  tags = ["org/repo:tag"]
  push = false
  no-cache = false
  cache-from = [
    "type=registry,ref=ghcr.io/pre/built:image",
  ]
  cache-to = [
    "type=inline",
  ]
  ...
}
...

devcontainer-bake.hcl - auto generated

target "_dev_containers_bake_target" {
  dockerfile = "path/to/Dockerfile-with-features"
  contexts = {
    _DEV_CONTAINERS_BASE_IMAGE = "target:foo"
  }
  target = "dev_containers_target_stage"
  tags = ["vsc-NAME-HASH"]
}

Dockerfile-with-features - auto generated

FROM _DEV_CONTAINERS_BASE_IMAGE AS dev_containers_target_stage
...

Bake command - auto generated

$ docker buildx bake --load \
    --file ../docker-bake.hcl \
    --set=target.args.mybuildarg=value \
    --set=foo*.args.mybuildarg=value \
    --pull \
    --file path/to/devcontainer-bake.hcl \
    _dev_containers_bake_target

cc @chrmarti @samruddhikhandale any thoughts?

@ruffsl
Copy link

ruffsl commented Apr 15, 2024

Well, in the meantime, I've found using the initializeCommand lifecycle-script to be a decent workaround. E.g:

devcontainer.json

{
    "name": "Example",
    "initializeCommand": ".devcontainer/initialize-command.sh foo",
    "image": "vsc:devcontainer",
}

initialize-command.sh

#!/bin/bash

# Immediately catch all errors
set -eo pipefail

# Uncomment for debugging
# set -x
# env

# Use first argument as target name
target=$1

# Bake the target and export locally to static tag
docker buildx bake --load \
    --file docker-bake.hcl \
    --set $target.tags=vsc:devcontainer \
    $target

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants
@ruffsl @c-ameron and others