Building and publishing container images with EDF

EDF integrates the OpenEmbedded meta-virtualization and meta-xilinx-virtualization layers, which together let you build container images that follow the OCI (Open Container Initiative) specification directly from BitBake recipes. The build pipeline that publishes xilinx/edf on Docker Hub uses the same recipes and classes described here. This page covers three capabilities:

  1. Build target container images with BitBake.

  2. Customize entrypoint, environment, and metadata.

  3. Publish the resulting OCI image to a registry such as Docker Hub.

How EDF builds container images

EDF uses the OCI image type from meta-virtualization. A recipe becomes a container image by setting IMAGE_FSTYPES = "container oci" (typically inherited from container-base.bb) and inheriting image-oci. BitBake then assembles a rootfs and packs it into an OCI image directory and tar archive.

Three reusable base recipes ship in meta-xilinx/meta-xilinx-virtualization/recipes-extended/images/:

Recipe

Purpose

container-base.bb

Minimal rootfs (base-files, base-passwd, netbase, a shell). Inherit when you want to define an image from scratch.

container-app-base.bb

Single-application container; set CONTAINER_APP to the package list and CONTAINER_APP_CMD to the entrypoint binary.

container-devtools-base.bb

Adds dev-pkgs, tools-sdk, package-management, vim-tiny, and a coreutils set. Use as the base for development containers.

Two ready-to-build EDF reference recipes live in meta-amd-edf/recipes-extended/images/:

  • container-app-hello-world.bb – minimal app container that runs hello.

  • container-devtools-edf.bb – developer container that adds ca-certificates and git on top of container-devtools-base.

Both build for any of the EDF common machines (for example amd-cortexa72-common, amd-cortexa78-mali-common).

Build a container image

Build the EDF developer container for an aarch64 target:

$ MACHINE=amd-cortexa72-common bitbake container-devtools-edf

Outputs land under tmp/deploy/images/<MACHINE>/ and include both the OCI directory layout and a tar archive:

$ ls tmp/deploy/images/amd-cortexa72-common/container-devtools-edf-*
container-devtools-edf-latest-oci -> ...rootfs-oci/
container-devtools-edf-latest-oci-dir.tar -> ...rootfs-oci-dir.tar
container-devtools-edf-latest-oci.tar -> ...rootfs-oci.tar

The -oci symlink points at an unpacked OCI image directory; the two tar variants are the same image packaged for transport. Use whichever your downstream tooling prefers.

Customize image metadata

The image-oci.bbclass exposes the standard OCI configuration as BitBake variables. Set them in the recipe to control runtime behavior and image metadata:

Variable

Purpose

OCI_IMAGE_TAG

Image tag. Defaults to latest.

OCI_IMAGE_ENTRYPOINT

Executable run when the container starts.

OCI_IMAGE_ENTRYPOINT_ARGS

Default arguments for the entrypoint.

OCI_IMAGE_LABELS

Space-separated key=value labels.

OCI_IMAGE_ENV_VARS

Space-separated key=value environment variables.

OCI_IMAGE_PORTS

Ports to expose, in <port>[/tcp|/udp] form.

OCI_IMAGE_AUTHOR, OCI_IMAGE_AUTHOR_EMAIL

Author metadata recorded in the image config.

Example: a custom container that exposes port 8080, sets a label, and runs my-server at startup:

require recipes-extended/images/container-app-base.bb

CONTAINER_APP     = "my-server"
CONTAINER_APP_CMD = "my-server"

OCI_IMAGE_TAG    = "1.0"
OCI_IMAGE_PORTS  = "8080/tcp"
OCI_IMAGE_LABELS = "org.opencontainers.image.vendor=AMD \
                    org.opencontainers.image.title=my-server"

Publish to a registry

The OCI tarballs that BitBake produces are not in the legacy Docker image format. docker load and docker pull therefore cannot consume them directly. Use skopeo to copy them into a registry, where any container runtime can then pull them.

Install skopeo on the build host (Ubuntu example):

$ sudo apt install skopeo

Push the produced OCI image to Docker Hub:

$ cd tmp/deploy/images/amd-cortexa72-common
$ skopeo copy --dest-creds <user>:<token> \
      oci:container-devtools-edf-latest-oci:latest \
      docker://docker.io/<user>/container-devtools-edf:latest

Verify by pulling the image with the standard Docker client:

$ docker pull docker.io/<user>/container-devtools-edf:latest

Other registries follow the same pattern. Replace docker://docker.io/... with the appropriate docker:// URL.

Tip

For CI pipelines, prefer a short-lived registry token (Docker Hub personal access token, or a project-scoped token from a private registry) over an account password.

Importing without a registry

If a registry is not available, the rootfs tarball that BitBake produces alongside the OCI tar can be imported directly into Docker on the target. This loses container metadata (entrypoint, labels, exposed ports), so it is suitable only for quick experiments. See Hello World container example for the full procedure.

Next steps

References