If you did not migrate your account yet, visit https://idp-portal-info.suse.com/
Building derived containers
- 1 Specification
- 2 Getting started
- 3 Implementation Details
This is the specification for all container images inside openSUSE distributions. If you build images in your home project on OBS or in a devel project not intended for submission to a openSUSE distribution, they are not required to follow this specification.
Rules enforced by openSUSE:Factory
If these rules are not followed, the factory-auto bot will reject the submit request to
- The container image must be built using KIWI
- Custom repositories are not added inside the *.kiwi file (only
foo.kiwifile has a matching
<image name="foo"/>attribute inside the
foo.kiwifile matches the file's basename
The name of the image (e.g.
opensuse/hello-world) has to be prefixed with either
kubic/ and must not collide with other images in openSUSE distributions, as they would overwrite each other.
Tags can be defined freely. On every release of a new build (Tumbleweed Snapshot, Leap Images build), the new builds are
released into a subproject of
openSUSE:Container and the old images are kept.
If a tag is provided by multiple images, the newest image is used.
One drawback of using Docker labels (which we need for compatibility) is that there is only one level of them in an image and not one per layer.
This means that labels defined in the base container can be overwritten by labels in derived images. Those which aren't overwritten aren't shown as coming from the base container.
To workaround that, specific information has to be cloned in container-specific labels, which are prefixed with
Here's the full list of labels/annotations defined in a openSUSE base container. Most of them need to be provided by derived images as well.
|Label(s)||OCI Annotation||Must be provided by derived images||Description||Example|
|org.opencontainers.image.title org.opensuse.base.title||org.opencontainers.image.title||Yes||Title of the image|| |
|org.opencontainers.image.description org.opensuse.base.description||org.opencontainers.image.description||Yes||Short description of the image|| |
|org.opencontainers.image.version org.opensuse.base.version||org.opencontainers.image.version||Yes||Version of the image. <version>.<cicnt>.<bldcnt>|| |
|org.opencontainers.image.created org.opensuse.base.created||org.opencontainers.image.created||Yes||Date/time of image build|| |
|org.opencontainers.image.vendor org.opensuse.base.vendor||org.opencontainers.image.vendor||No||Vendor of the image|| |
|org.opencontainers.image.url org.opensuse.base.url||org.opencontainers.image.url||No||URL with more information|| |
|org.openbuildservice.disturl org.opensuse.base.disturl||org.openbuildservice.disturl||Yes||Dist URL as provided by OBS|| |
|org.opensuse.reference org.opensuse.base.reference||org.opensuse.reference||Yes|| Reference pointing to this specific image (
Each image should define a history entry with a human-readable description of what it is. This way it's easy to get an overview on what each layer in in image is.
> docker history opensuse/tumbleweed IMAGE CREATED CREATED BY SIZE COMMENT aaa05880bad2 2 days ago KIWI 9.17.15 123MB openSUSE Tumbleweed 20190312 Base Container
The easiest way to get started with a new container image build is by using the predefined templates and submitting them.
Branching a Template
On the OBS main page, there's a link to an overview of available templates.
Choose one of the "Container built using KIWI" options for the distribution you want to build against. Make sure to branch into a project which does not exist yet or the image will not build correctly. If the target project is already set up to build images against the distro you selected, for instance by branching into the project previously, that's fine too.
Editing the Predefined Configuration
As first step, you should rename the
config.kiwi file appropriately and adjust the name inside. For instance, if you want to build a container for "foo", rename
foo.kiwi and set the
name attribute at the top as well, e.g.
<image name="foo" ... />.
Next, set the metainfo in the
<containerconfig/> element, so name, tag(s), labels and the history entry.
Also adjust the
<description/> element to match the image you're creating.
For the syntax and structure of the .kiwi file in general, read the KIWI manual.
After enabling publishing for the package (or entire project) on OBS, the image is accessible through registry.opensuse.org. You can use docker and podman to download it, see the registry overview page.
Container images can be submitted to
openSUSE:Leap:15.1 and later.
For Leap it's possible to introduce new images by submitting it as maintenance update.
The usual rules for submission to distros apply, so a devel project needs to be picked and used as submission base.
After the image got accepted into the distro, ask the release team to enable it for publishing either per E-Mail to the [opensuse-factory] mailing list or the #opensuse-factory IRC channel on freenode.
KIWI supports an
additionaltags attribute and obs services, such as obs-service-kiwi_metainfo_helper, can add build-time information to tags.
<preferences> <type image="docker"> <containerconfig name="opensuse/leap" tag="15.0.%RELEASE%" additionaltags="15.0" maintainer="Fabian Vogt <firstname.lastname@example.org>"> <labels>
To make it easier to define labels for the "org.opensuse.<containername>" namespace, there's an OBS service that converts the OCI annotations to the final labels.
Copy of the README:
This service can be enabled to run during buildtime, when it will edit the
kiwi image descriptions to expand the
<image [...] xmlns:suse_label_helper="com.suse.label_helper"> [...] <containerconfig [...]> <labels> <suse_label_helper:add_prefix prefix="org.opensuse.base"> <label name="org.opencontainers.image.title" value="openSUSE Tumbleweed Base Container"/> </suse_label_helper:add_prefix>
<image [...] xmlns:suse_label_helper="com.suse.label_helper"> [...] <containerconfig [...]> <labels> <label name="org.opencontainers.image.title" value="openSUSE Tumbleweed Base Container"/> <label name="org.opensuse.base.title" value="openSUSE Tumbleweed Base Container"/>
To make it possible to include buildtime information as used for the labels and tags, this service substitutes certain placeholders.
An updated list of all placeholders and their content is in the package itself, you can read it here.
Containers are built in
openSUSE:Leap:15.x:Images next to other images in the same repo. A list in the OSRT:ToTestManagerConfig attribute for each project tells the totest-manager bot which of the built images are container images and should be released to the registry instead of the download server.
Those images are released into the
containers repo of the
:ToTest subproject, where they are pushed to
registry.opensuse.org and openQA can download and test them from there. This is done by the "docker_image" test module.
After openQA marks a snapshot/build as good, ttm releases the containers from
:ToTest/containers into its releasetarget. For
openSUSE:Factory:ToTest/containers that is
Those target projects have
kind="maintenance_release" set in their meta, so on every release, binaries are added instead of overwritten. This means that every container released (and not cleaned up) is available on OBS and the registry.
For every repo on the registry (e.g.
kubic/pause), there's exactly one project/repo combination on OBS which provides the images to feed those. This is not an issue for Tumbleweed and Kubic currently, but as all versions of Leap share one repo but the images are distributed over multiple projects (
openSUSE:Containers:Leap:15.x), this has to be worked around. It is achieved by creating an intermediate project at
openSUSE:Containers:Leap which aggregates all binaries ending up in the
opensuse/leap repo on the registry. The origin projects itself are publish disabled to make it work.
For providing the dynamic
opensuse/leap:15 tags, those are added to the aggregates as specified in the project config.