Skip to content

Upgrade UBI Build System to Docker Buildx + Bake (Multi-Platform + Variants) #121

@szmyty

Description

@szmyty

TITLE: Upgrade UBI Build System to Docker Buildx + Bake (Multi-Platform + Variants)


GOAL

Upgrade the UBI repository to support multi-platform, reproducible image
builds using Docker Buildx + Bake, while preserving:

  • The devcontainer-first authoring workflow
  • Nix-based deterministic toolchains
  • The concept of variant images (base, dev, python, infra, etc.)
  • A clean separation between authoring and distribution

The devcontainer remains an authoring environment.
Buildx + Bake become the canonical distribution build system.


PROBLEM STATEMENT

Currently:

  • The UBI image is authored and iterated inside a devcontainer
  • The Dockerfile is correct and sophisticated, but:
    • builds are implicitly single-platform
    • there is no external, canonical build orchestration
    • variant images are not formalized
    • CI / release builds depend on devcontainer context

This makes it hard to:

  • build for linux/amd64 and linux/arm64
  • produce variant images consistently
  • build images outside VS Code
  • scale toward CI/CD and distribution

We need a first-class build system that is:

  • external to the devcontainer
  • multi-platform
  • variant-aware
  • CI-friendly
  • reproducible

DESIRED OUTCOMES

After this task:

  • docker buildx bake is the canonical build entrypoint
  • Multi-platform images can be built locally and in CI
  • Variant images are first-class targets
  • Devcontainer workflow remains unchanged
  • CI can build images without VS Code or devcontainers

SCOPE OF WORK

  1. Introduce Docker Buildx + Bake
  • Add a root-level docker-bake.hcl (or docker-bake.json)
  • Define a default build group targeting:
    • linux/amd64
    • linux/arm64
  • Ensure BuildKit features are enabled
  • Use Buildx consistently (no legacy docker build)
  1. Formalize Image Targets (Variants)

Define explicit build targets such as:

  • ubi-base
  • ubi-dev
  • ubi-python
  • ubi-infra (future)

Each target should:

  • Reference a specific Dockerfile stage or target
  • Share common build args and labels
  • Be buildable independently or as a group

Conceptual example (DO NOT use backticks, this is illustrative):

snippet
group "default" {
targets = ["ubi-base", "ubi-dev"]
}

target "ubi-base" {
context = "."
dockerfile = "Dockerfile"
target = "final"
platforms = ["linux/amd64", "linux/arm64"]
}
snippet

  1. Separate Authoring vs Distribution Cleanly
  • Devcontainer:
    • continues to use the existing Dockerfile
    • optimized for DX, debugging, iteration
  • Build system:
    • does not rely on devcontainer features
    • uses Buildx + Bake directly
    • is callable from local host or CI

Document this separation clearly in the repo.

  1. Add Consistent Metadata & OCI Labels

Add OCI-standard labels via Bake:

  • org.opencontainers.image.source
  • org.opencontainers.image.revision
  • org.opencontainers.image.created
  • org.opencontainers.image.version
  • org.opencontainers.image.description

Ensure labels are applied consistently across all variants.

  1. CI-Friendly Build Entry Point

Ensure the following works outside the devcontainer:

snippet
docker buildx bake
snippet

Behavior:

  • Builds all default targets
  • Supports multi-platform
  • Can optionally:
    • push to registry
    • load locally for testing
  1. GitHub Actions Integration (Scaffold Only)

Add a non-destructive CI scaffold:

  • .github/workflows/build.yml
  • Uses:
    • docker/setup-buildx-action
    • docker/bake-action
  • Initially:
    • build only
    • no registry push
  • Designed so pushing can be enabled later via secrets
  1. Documentation

Add or update documentation explaining:

  • Why Buildx + Bake is used
  • How to build images locally
  • How variant images work
  • The difference between:
    • devcontainer authoring
    • production/distribution builds

CONSTRAINTS / NON-GOALS

  • Do NOT remove or break the existing devcontainer
  • Do NOT inline CI logic into the Dockerfile
  • Do NOT require Nix on the host
  • Do NOT assume a single platform
  • Do NOT over-optimize caching yet

Correctness and structure come first.


DESIGN PRINCIPLES

  • Explicit > implicit
  • Reproducible > convenient
  • Authoring ≠ distribution
  • One canonical build entrypoint
  • Variants are additive, not forks

ACCEPTANCE CRITERIA

  • docker buildx bake works on macOS and Linux
  • Multi-platform builds succeed
  • Variant targets are clearly defined
  • CI can build without VS Code
  • Devcontainer workflow remains intact

NOTES FOR COPILOT

  • Prefer Docker Bake over shell scripts
  • Avoid hardcoding platforms in multiple places
  • Reuse build args across targets
  • Keep changes incremental and readable
  • Match existing verbosity and commenting style

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions