ibm-clouddocker-buildkitcontainer-registry

How to push a single image with multiple tags to a container registry?


I'm currently using the following command to build an image with a tag:

buildctl build \
    --frontend dockerfile.v0 --opt filename=${DOCKER_FILE} --local dockerfile=${DOCKER_ROOT} \
    ${BUILD_ARGS} --local context=${DOCKER_ROOT} \
    --import-cache type=registry,ref=${REGISTRY_URL}/${REGISTRY_NAMESPACE}/${IMAGE_NAME} \
    --output type=image,name="${REGISTRY_URL}/${REGISTRY_NAMESPACE}/${IMAGE_NAME}:${IMAGE_TAG}",push=true

I want to add a new tag to the same image. I've tried what is suggested on Buildctl command to tag multiple images, but it fails.

buildctl build \
    --frontend dockerfile.v0 --opt filename=${DOCKER_FILE} --local dockerfile=${DOCKER_ROOT} \
    ${BUILD_ARGS} --local context=${DOCKER_ROOT} \
    --import-cache type=registry,ref=${REGISTRY_URL}/${REGISTRY_NAMESPACE}/${IMAGE_NAME} \
    --output type=image,name="${REGISTRY_URL}/${REGISTRY_NAMESPACE}/${IMAGE_NAME}:${IMAGE_TAG},${REGISTRY_URL}/${REGISTRY_NAMESPACE}/${IMAGE_NAME}:latest",push=true
error: invalid value acme.com/namespace/image-name:latest

I also tried the following, but it only creates the image with the latest tag, not both

buildctl build \
    --frontend dockerfile.v0 --opt filename=${DOCKER_FILE} --local dockerfile=${DOCKER_ROOT} \
    ${BUILD_ARGS} --local context=${DOCKER_ROOT} \
    --import-cache type=registry,ref=${REGISTRY_URL}/${REGISTRY_NAMESPACE}/${IMAGE_NAME} \
    --output type=image,name="${REGISTRY_URL}/${REGISTRY_NAMESPACE}/${IMAGE_NAME}:${IMAGE_TAG},name=${REGISTRY_URL}/${REGISTRY_NAMESPACE}/${IMAGE_NAME}:latest",push=true

What I want:

Does anyone know how to do it?


Solution

  • There seems to be a difference between name="foo" and "name=foo". The correct one in this case is the latter.

    I tracked the issue that enabled this funcitonality https://github.com/moby/buildkit/issues/797. The comments show how to do it (depending on your environment, escaping might be necessary; although, not always).

    Following the scenario from the question, the propper way to build and push a single image with multiple tags is as follows (notice how it's "name=)

    buildctl build \
        --frontend dockerfile.v0 --opt filename=${DOCKER_FILE} --local dockerfile=${DOCKER_ROOT} \
        ${BUILD_ARGS} --local context=${DOCKER_ROOT} \
        --import-cache type=registry,ref=${REGISTRY_URL}/${REGISTRY_NAMESPACE}/${IMAGE_NAME} \
        --output type=image,\"name=${REGISTRY_URL}/${REGISTRY_NAMESPACE}/${IMAGE_NAME}:${IMAGE_TAG},${REGISTRY_URL}/${REGISTRY_NAMESPACE}/${IMAGE_NAME}:latest\",push=true