From Fedora Project Wiki

(Moving the guidelines to docs.fp.o)
 
(35 intermediate revisions by 9 users not shown)
Line 1: Line 1:
= Container Maintainer Guidelines =
= Container Maintainer Guidelines =


In the Fedora world, the concept of being a [https://fedoraproject.org/wiki/Category:Package_Maintainers Package Maintainer] is well known as all the software currently released and published as an official "Build Artifact" of the Fedora Project for inclusion in the Fedora GNU/Linux distribution has always been packaged in [http://rpm.org/ RPM] Package Manager Format.
The guidelines have been moved [https://docs.fedoraproject.org/en-US/containers/guidelines/guidelines/ here]
 
However, as technology changes so must the Fedora Project. The concept of "containers" on Linux has become quite prominent and Fedora will be publishing container images as officially released Build Artifact. One thing to note is that container images are not a new software packaging format but more so a delivery mechanism where many different things can be easily shipped as a single unit. An example of this is packages that can be combined to deliver an easily ran "software solution".
 
Below you will find Guidelines similar in nature to that of the Fedora [https://fedoraproject.org/wiki/Packaging:Guidelines Packaging Guidelines] but catered towards the concept of Containers. Fedora is targeting the any [https://www.opencontainers.org/ OCI Compliant] container runtime implementation.
 
== General Fedora Container Information ==
 
In this section you will find general information about Fedora Container Images that should be useful for Fedora Container Layered Image Maintainers.
 
 
=== Build System ===
 
In order to get a better understanding of the big picture of how all this works, Container Maintainers might find the [https://docs.pagure.org/releng/layered_image_build_service.html Layered Image Build Service Architecture Document] interesting. However, extensive coverage of the Build System is out of the scope of this Guidelines document.
 
=== Vocabulary Terms ===
 
* '''Container Registry''' - (often refereed to as simply a "registry") a service that stores and distributes Container Images via namespaces/repositories.
* '''Fedora Generational Core''' - defined by the [[Modularity|Fedora Modularity]] effort as a part of [[BaseRuntime| the Base Runtime]] and will serve as our registry namespace. For all intents and purposes this will be a synonym of the Fedora Release. (Will often be noted as <code>$FGC</code>)
 
=== Fedora Container Naming ===
 
A Fedora Container Layered Image name should be the same as the the name of main service that it intends to provide end users. Therefore, naming must follow the [[Packaging:NamingGuidelines|Fedora Naming Guidelines]].
 
Container naming as it will exist in [https://admin.fedoraproject.org/pkgdb/packages/*/?branches=&status=&owner=&namespace=docker Fedora Package DB] (and [Distgit http://pkgs.fedoraproject.org/cgit/docker]) should be relatively standard. None of the Fedora releases/DistGit-branch naming should be taken into consideration by the main container name, just as it is for RPM Package Naming.
 
Fedora content is now "namespaced" in both [https://admin.fedoraproject.org/pkgdb/packages/ Fedora Package DB] and [http://pkgs.fedoraproject.org/cgit/rpms/ DigtGit], with the default namespace being 'rpms' for backwards compatibility. This allows for Container Layered Images to share the same base component name as their RPM counterpart (where applicable).
 
Below is a reference of the [[Container:Guidelines#Registry_Layout|Registry Layout]] which will clarify how different Fedora releases are handled.
 
=== Fedora Base Image ===
 
The Fedora Base Image provides information that can be used by the Layered Images via inherited Environment Variables.
 
These are outlined below:
 
* <code>$FGC</code> is defined as Fedora Generational Core by the [[Modularity|Fedora Modularity]] effort as a part of [[BaseRuntime| the Base Runtime]] and will serve as our registry namespace.
* <code>$DISTTAG</code> is defined just as it is for RPMs, but since Dockerfiles lack a mechanism similar to RPM Macros this is being stored in the base image such that it can be inherited by layered images.
 
=== Fedora Container Registries and Updates ===
 
In Fedora there are two Registries: candidate and stable.
 
All Layered Image Builds end up in the candidate registry as soon as they are successful in the Fedora Layered Image Build System. These images can immediately be pulled (example using docker: <code>docker pull candidate-registry.fedoraproject.org/$FGC/$NAME:latest</code>).
 
Gated releases will happen on a Two Week Cadence, alternating with the Fedora Two Week Atomic Host.
 
==== Registry Layout ====
 
Fedora Base Images will be available at the "root" namespace of the registry, an example is below:
 
<pre>
https://candidate-registry.fedoraproject.org/fedora:24
https://candidate-registry.fedoraproject.org/fedora:25
https://candidate-registry.fedoraproject.org/fedora:latest
 
https://registry.fedoraproject.org/fedora:24
https://registry.fedoraproject.org/fedora:25
https://registry.fedoraproject.org/fedora:latest
</pre>
 
Fedora Layered Images will be available in their respective <code>$FGC</code> namespace which coorelates to their DistGit branch and Koji tag. An example is as follows for the <code>f25</code> Fedora Generational Core and the cockpit container image.
 
There are multiple tags applied to each image:
* <code>$FGC/Name:Version-Release</code> (including <code>$DISTTAG</code>)
* <code>$FGC/Name:Version</code>
* <code>$FGC/Name:latest</code>
** The :latest tag can be omitted when issuing a <code>docker pull</code> command.
 
The latter two tags are updated in-place and a new execution of <code>docker pull</code> will get the latest image.
 
<pre>
https://candidate-registry.fedoraproject.org/f25/cockpit:0-1.f25docker
https://candidate-registry.fedoraproject.org/f25/cockpit:0
https://candidate-registry.fedoraproject.org/f25/cockpit:latest
 
https://registry.fedoraproject.org/f25/cockpit:0-1.f25docker
https://registry.fedoraproject.org/f25/cockpit:0
https://registry.fedoraproject.org/f25/cockpit:latest
</pre>
 
==== Searching the Registry ====
 
At the time of this writing there is no search functionality for the Container Registry but we will release a manifest of all available stable Fedora Layered Images in the Fedora Container Registry as Layered Images become available for release. We aim to change this in the future and provide search functionality to users.
 
== Container Guidelines ==
 
The Container Guidelines are a collection of common issues and the severity that should be placed on them. While these guidelines should not be ignored, they should also not be blindly followed. If you think that your container should be exempt from part of the Guidelines, please bring the issue to the Fedora Container Committee (Pending Existence). In the absence of a Fedora Container Committee, please seek guidance from the [[Cloud_SIG|Fedora Cloud SIG]].
 
=== Containers (Dockerfile) ===
 
Container images in Fedora are built using a [https://docs.docker.com/engine/reference/builder/ Dockerfile] much in the same way an [http://rpm.org/ RPM] is built using a spec file. In this section are Fedora Guidelines for creating Container images using a Dockerfile.
 
 
{{admon/note|Dockerfile Guidelines Upstream|
These guidelines are a Fedora adaptation of the Upstream [https://projectatomic.io Project Atomic] effort to define [https://github.com/projectatomic/container-best-practices Container Best Practices].
}}
 
==== LABELS ====
 
Dockerfiles have a concept of a [https://docs.docker.com/engine/reference/builder/#label LABEL] which can add arbitrary metadata to an image as a key-value pair. Fedora Guidelines on the topic of LABELs follows the [http://www.projectatomic.io/ Project Atomic] [https://github.com/projectatomic/ContainerApplicationGenericLabels Container Application Generic Labels] standards for LABEL definition.
 
'''Required''' LABELs for a Fedora Layered Image are as follows:
 
{|
!Name
!Description
|-
|BZComponent
|The Bugzilla component name where bugs against this container should be reported by users.
|-
|Name
|Name of the Image
|-
|Version
|Version of the image
|-
|Release
|Release Number for this version
|-
|Architecture
|Architecture the software in the image should target (Optional: if omitted, it will be built for all supported Fedora Architectures)
|-
|RUN or Usage
|Either provides an Atomic Run line, or a human readable example of container execution
|-
|Help
|Provides a detailed narrative of how the container is meant to be used.  In many cases will be a link.
|}
 
'''Optional''' labels for Fedora Layered Images
 
{|
!Name
!Description
|-
|INSTALL
|Powers "atomic install" command.  Usually required for system containers.
|-
|UNINSTALL
|Powers "atomic uninstall" command.  Required if Install is present.
|}
 
See LABEL SPECIFICATION below for more details on what's required for each of these labels.
 
{{admon/note|Dockerfile Label Guidelines Upstream|
The LABELs used here are meant to be a Fedora adaptation of the upstream [https://projectatomic.io Project Atomic] effort to define [https://github.com/projectatomic/ContainerApplicationGenericLabels Container Application Generic Labels] as well as [http://docs.projectatomic.io/container-best-practices/ Container Best Practices].
}}
 
These LABELs should be defined in a single line of the Dockerfile such that they don't each lead to another layer in the build. The following is a very simple Dockerfile example containing the required LABELs:
 
A recommended pattern is to define these items as ENV variables such that they can be used elsewhere, also note the <code>$FGC</code> and <code>$DISTTAG</code>.
 
<code>$FGC</code> is defined as Fedora Generational Core by the [[Modularity|Fedora Modularity]] effort as a part of [[BaseRuntime| the Base Runtime]] and will serve as our registry namespace.
 
<code>$DISTTAG</code> is defined just as it is for RPMs, but since Dockerfiles lack a mechanism similar to RPM Macros this is being stored in the base image such that it can be inherited by layered images.
 
By following the pattern below, we can define the container specific information in one place on the ENV line and have it be set properly in the LABEL line (again, noting the <code>$FGC</code> and <code>$DISTTAG</code> being used but never defined as these are inherited).
 
<pre>
FROM fedora:25
LABEL MAINTAINER "Adam Miller" <maxamillion@fedoraproject.org>
 
ENV NAME=myawesomecontainer VERSION=0 RELEASE=1 ARCH=x86_64
LABEL BZComponent="$NAME" \
        Name="$FGC/$NAME" \
        Version="$VERSION" \
        Release="$RELEASE.$DISTTAG" \
        Architecture="$ARCH" \
        Usage="docker run -p 9000:9000 f25/myawesomecontainer" \
        Help="Runs myawesomeapp, which listens on port 9000 and tells you how awesome it is.  No depedancies."
</pre>
 
==== LABEL SPECIFICATION ====
 
Some additional details about how each label is to be populated.
 
'''BZComponent''': Existing Bugzilla component against which bugs in this image should be reported.
 
'''Name''': Name of the image.  If the image replaces a standard RPM, it should have the exact same name of that RPM.  Otherwise, please see naming guidelines above.
 
'''Version''': Usually 0.  Populated from the ENV variable.  See "VERSIONING" below for explanation.
 
'''Release''': Populated from the ENV variable.  Should start at 1, and increment every time the image changes.  Generally carries a suffix of "f##container", depending (i.e. "f26container").
 
'''Architecture''': usually "x86_64", unless the container image supports other/all architectures.
 
'''Usage''':
 
'''RUN''':
 
'''INSTALL''':
 
'''UNINSTALL''':
 
'''Help''':
 
==== VERSIONING ====
 
In the previous section there was coverage of LABELs, one of those is the Version that is set in the example using the <code>ENV</code> variable <code>VERSION</code> which at this time needs to be <code>0</code>. Any changes made to the <code>Dockerfile</code> or the contents of the resulting image that would require a rebuild should increment the <code>Release</code> LABEL that is similarly set using the <code>ENV</code> variable named <code>RELEASE</code>. The reasoning for this is described below.
 
At this time there is no way to automatically populate the <code>Version</code>/<code>VERSION</code> value with the same value of the latest version of the primary RPM belonging to the container image. This is something that is currently [https://pagure.io/atomic-wg/issue/249 on the roadmap].
 
Why is this needed?
 
If we set the <code>Version</code> LABEL to the version of it's respective RPM at the time of the Container Image Review, then the maintainer will constantly have to update it by hand every time there is a RPM update which is inconvenient and error prone. Beyond that, there's a possibility that the version of the RPM could be updated by the layered image automatic rebuilds and the maintainer isn't able to update the <code>Dockerfile</code> in a timely manner (Automatic Rebuilds are done by [https://docs.pagure.org/releng/ Release Engineering] in order to pull in security updates for all layered images). If this were to happen, then the version of the container image will not match the version of the software it's meant to deliver which would lead to confusion and potentially unexpected negative side effects for users. Therefore, for the time being we're saying that the version number of the container is not meaningful but it will be as soon as possible.
 
==== CMD / ENTRYPOINT ====
 
Another item required is a CMD or ENTRYPOINT entry so that when an user were run perform the following command (for example), expected behavior occurs.:
 
<pre>docker run registry.fedoraproject.org/f25/myawesomecontainer</pre>
 
For more information on these entries, please reference the upstream [https://docs.docker.com/engine/reference/builder/ Dockerfile documentation]. The following is extending on the above example, showing a CMD directive.
 
<pre>
FROM fedora:25
LABEL MAINTAINER "Adam Miller" <maxamillion@fedoraproject.org>
 
ENV NAME=myawesomecontainer VERSION=0 RELEASE=1 ARCH=x86_64
LABEL BZComponent="$NAME" \
        Name="$FGC/$NAME" \
        Version="$VERSION" \
        Release="$RELEASE.$DISTTAG" \
        Architecture="$ARCH"
 
CMD printf "My Awesome Container!\n"
</pre>
 
=== System Containers ===
 
System containers are read-only, OS specific runc containers running as systemd services. They use OSTree as storage, skopeo to pull from registries and are managed with the atomic CLI.
 
System containers' Dockerfiles have the following differences:
 
==== LABELS ====
 
* Install/Uninstall: system containers should not have an install/uninstall label. The install is always done through  <code>atomic install --system $IMAGE</code>  which checks out the image and creates a systemd service.
 
* Run/Usage: system containers should not have a Run/Usage label. All system containers, post installation, should be ran with  <code>systemctl start $SERVICE</code>  or  <code>atomic run $CONTAINER</code>.
 
* atomic.type: Include this as a label if the container is meant to be ONLY ran as a system container. This is a special label to tell the atomic CLI that the image should be pulled to ostree. Usage: <code>atomic.type='system'</code>.
 
An example set of labels for a system container:
 
<pre>
ENV VERSION=0.1 RELEASE=1 ARCH=x86_64
LABEL BZComponent="flannel" \
      Name="$FGC/flannel" \
      Version="$VERSION" \
      Release="$RELEASE.$DISTTAG" \
      Architecture="$ARCH" \
      Summary="An etcd driven address agent, intended to be run as a system container" \
      maintainer="Giuseppe Scrivano <gscrivan@redhat.com>" \
      atomic.type='system'
</pre>
 
==== CMD/ENTRYPOINT ====
 
System containers also do not need a CMD directive. The installation command  <code>atomic install --system</code>  checks out a local copy of the image and creates necessary files. To set up necessary environment/files/scripts, instead do so through runc's config.json.template or systemd tmpfiles (tmpfiles.template).
 
If the container can double as a docker container, then the CMD directive should follow the same guidelines as a docker container as highlighted above.
 
==== Other ====
 
A system container only requires a bare minimum of a Dockerfile, but for most services that is not enough to create a working service. For more detailed guidelines on specifications of other files, please visit [[:Container:System_Container]]
 
== Content ==
 
Dockerfiles in Fedora should not contain net new code. The meaning of this is that software should be packaged properly as RPMs and placed in the Fedora repositories, Dockerfiles are simply a deliver mechanism for pre-defined "ready to run" configurations. This can be achieved as an [https://github.com/projectatomic/atomicapp/blob/master/docs/start_guide.md Atomic App] or similar. Any content that is to accompany the Dockerfile must either be configuration files or startup/orchestration scripts. The goal of this is such that we follow the key points of the [https://docs.pagure.org/releng/philosophy.html Fedora Release Engineering Philosophy].
 
=== Multi Container Services ===
Each container image should provide only one "service" and multi-container services should be handled by an external orchestration tool at the users discretion such as [https://www.openshift.org/ OpenShift Origin], [http://kubernetes.io/ kubernetes], [http://deis.io/ deis], [https://docs.docker.com/swarm/ Docker Swarm], [https://docs.docker.com/compose/ Docker Compose], [https://dcos.io/ DC/OS], [https://www.cloudfoundry.org/ Cloud Foundry], [https://mesos.apache.org/ Apache Mesos], etc.
 
These types of multi-container services should be documented in such a way that users can adapt them to their needs. One example would be using the [https://projectatomic.io Project Atomic] [https://github.com/projectatomic/nulecule nulecule] specification.
 
{{admon/important|Future|In the future there will be an user facing outlet such that this information can be index and searched so that it's easy for users to consume this content. Our long term [[Changes/FedoraDockerRegistry| Fedora Container Registry]] goals are still in development}}
 
= Discussion =
 
For suggestions, feedback, or to report issues with this page please contact the [[Cloud|Fedora Cloud SIG]].
 
See [[Talk:PackagingDrafts/Containers]] for discussion.
 
 
= See also =
 
[[Container:Review_Process]]

Latest revision as of 15:23, 17 June 2019

Container Maintainer Guidelines

The guidelines have been moved here