Module descriptor

Module descriptor contains all information CEKit needs to introduce a feature to an image. Modules are used as libraries or shared building blocks across images.

It is very important to make a module self-contained which means that executing scripts defined in the module’s definition file should always end up in a state where you could define the module as being installed.

Modules can be stacked – some modules will be run before, some after your module. Please keep that in mind at the time you are developing your module – you don’t know how and when it’ll be executed.

Name

Key
name
Required
Yes

Module identifier used to refer to the module, for example in list of modules to install or in overrides.

Warning

Please note that this key has a different purpose than the name key in image descriptor. When defined in a module it defines the module name and does not override the image name.

name: "python_flask_module"

Execute

Key
execute
Required
No

Execute section defines what needs to be done to install this module in the image. Every execution listed in this section will be run at image build time in the order as defined.

Note

When no user is defined, root user will be used to execute the script.

execute:
    # The install.sh file will be executed first as root user
    - script: install.sh
    # Then the redefine.sh file will be executed as jboss user
    - script: redefine.sh
      user: jboss

Version

Key
version
Required
Yes

Version of the image.

version: "1.4"

Description

Key
description
Required
No

Short summary of the image.

Value of the description key is added to the image as two labels:

  1. description, and
  2. summary.

Note

These labels are not added is these are already defined in the labels section.

description: "Red Hat JBoss Enterprise Application 7.0 - An application platform for hosting your apps that provides an innovative modular, cloud-ready architecture, powerful management and automation, and world class developer productivity."

From

Key
from
Required
Yes

Base image of your image.

from: "jboss-eap-7/eap70:1.2"

Environment variables

Key
envs
Required
No

Similar to labels – we can specify environment variables that should be present in the container after running the image. We provide envs section for this.

Environment variables can be divided into two types:

  1. Information environment variables

    These are set and available in the image. This type of environment variables provide information to the image consumer. In most cases such environment variables should not be modified.

  2. Configuration environment variables

    This type of variables are used to define environment variables used to configure services inside running container.

These environment variables are not set during image build time but can be set at run time.

Every configuration enviromnent variable should provide an example usage (example) and short description (description).

Please note that you could have an environment variable with both: a value and example set. This suggest that this environment variable could be redefined.

Note

Configuration environment variables (without value) are not generated to the build source. These can be used instead as a source for generating documentation.

envs:
    # Configuration env variables below
    # These will be added to container
    - name: "STI_BUILDER"
        value: "jee"
    - name: "JBOSS_MODULES_SYSTEM_PKGS"
        value: "org.jboss.logmanager,jdk.nashorn.api"

    # Information env variables below
    # These will NOT be defined (there is no value)
    - name: "OPENSHIFT_KUBE_PING_NAMESPACE"
        example: "myproject"
        description: "Clustering project namespace."
    - name: "OPENSHIFT_KUBE_PING_LABELS"
        example: "application=eap-app"
        description: "Clustering labels selector."

Labels

Key
labels
Required
No

Note

Learn more about standard labels in container images.

Every image can include labels. CEKit makes it easy to do so with the labels section.

labels:
    - name: "io.k8s.description"
      value: "Platform for building and running JavaEE applications on JBoss EAP 7.0"
    - name: "io.k8s.display-name"
      value: "JBoss EAP 7.0"

Artifacts

It’s common for images to require external artifacts like jar files, installers, etc. In most cases you will want to add some files into the image and use them during image build process.

Artifacts section is meant exactly for this. CEKit will try to automatically fetch any artifacts specified in this section.

If for some reason automatic fetching of artifacts is not an option for you, you should define artifacts as plain artifacts and use the cekit-cache command to add the artifact to local cache, making it available for the build process automatically. See Artifact caching chapter.

Artifact features

Checksums

Almost all artifacts will be checked for consistency by computing checksum of the fetched file and comparing it with the desired value. Currently supported algorithms are: md5, sha1, sha256 and sha512.

You can define multiple checksums for a single artifact. All specified checksums will be validated.

If no algorithm is provided, artifacts will be fetched every time.

This can be useful when building images with snapshot content. In this case you are not concerned about the consistency but rather focusing on rapid development. We advice that you define checksum when your content becomes stable.

Caching
All artifacts are automatically cached during an image build. To learn more about caching please take a look at Artifact caching chapter.

Common artifact keys

name

Used to define unique identifier of the artifact.

The name key is very important. It’s role is to provide a unique identifier for the artifact. If it’s not provided, it will be computed from the resource definition, but we strongly suggest to provide the name keys always.

Value of this key does not need to be a filename, because it’s just an identifier used to refer the artifact. Using meaningful and unique identifiers is important in case when you want to use Overrides. It will make it much easier to refer the artifact and thus override it.

target

The output name for fetched resources will match the target attribute. If it is not defined then base name of the name attribute will be used. If it’s not provided either then base name of the path/URL will be used.

Below you can find a few examples.

artifacts:
    - name: jboss-eap-distribution
      path: jboss-eap-6.4.0.zip
      target: jboss-eap.zip

Target file name: jboss-eap.zip.

artifacts:
    - name: jboss-eap-distribution
      path: jboss-eap-6.4.0.zip

Target file name: jboss-eap-distribution.

artifacts:
    - path: jboss-eap-6.4.0.zip

Target file name: jboss-eap-6.4.0.zip.

description

Describes the artifact. This is an optional key that can be used to add more information about the artifact.

Adding description to artifacts makes it much easier to understand what artifact it is just by looking at the image/module descriptor.

artifacts:
  - path: jboss-eap-6.4.0.zip
    md5: 9a5d37631919a111ddf42ceda1a9f0b5
    description: "Red Hat JBoss EAP 6.4.0 distribution available on Customer Portal: https://access.redhat.com/jbossnetwork/restricted/softwareDetail.html?softwareId=37393&product=appplatform&version=6.4&downloadType=distributions"

If CEKit is not able to download an artifact and this artifact has a description defined – the build will fail but a message with the description will be printed together with information on where to place the manually downloaded artifact so that the build could be resumed.

Artifact types

CEKit supports following artifact types:

  • Plain artifacts
  • URL artifacts
  • Path artifacts
  • Image source artifacts

Plain artifacts

This is an abstract way of defining artifacts. The only required keys are name and the md5 checksum. This type of artifacts is used to define artifacts that are not available publicly and instead provided by some (internal) systems.

Schema
{
    "map": {
        "description": {
            "desc": "Description of the resource", 
            "type": "str"
        }, 
        "md5": {
            "desc": "The md5 checksum of the resource", 
            "required": true, 
            "type": "str"
        }, 
        "name": {
            "desc": "Key used to identify the resource", 
            "required": true, 
            "type": "str"
        }, 
        "sha1": {
            "desc": "The sha1 checksum of the resource", 
            "type": "str"
        }, 
        "sha256": {
            "desc": "The sha256 checksum of the resource", 
            "type": "str"
        }, 
        "sha512": {
            "desc": "The sha512 checksum of the resource", 
            "type": "str"
        }, 
        "target": {
            "desc": "Target file name for the resource", 
            "type": "str"
        }
    }
}
Examples
artifacts:
    - name: jolokia
      md5: 75e5b5ba0b804cd9def9f20a70af649f
      target: jolokia.tar.gz

As you can see, the definition does not define from where the artifact should be fetched. This approach relies on Artifact caching to provide the artifact.

Note

See Red Hat environment for description how plain artifacts are used in the Red Hat environment.

URL artifacts

This is the simplest way of defining artifacts. You need to provide the url key which is the URL from where the artifact should be fetched from.

Schema
{
    "map": {
        "description": {
            "desc": "Description of the resource", 
            "type": "str"
        }, 
        "md5": {
            "desc": "The md5 checksum of the resource", 
            "type": "str"
        }, 
        "name": {
            "desc": "Key used to identify the resource", 
            "type": "str"
        }, 
        "sha1": {
            "desc": "The sha1 checksum of the resource", 
            "type": "str"
        }, 
        "sha256": {
            "desc": "The sha256 checksum of the resource", 
            "type": "str"
        }, 
        "sha512": {
            "desc": "The sha512 checksum of the resource", 
            "type": "str"
        }, 
        "target": {
            "desc": "Target file name for the resource", 
            "type": "str"
        }, 
        "url": {
            "desc": "URL where the resource can be found", 
            "required": true, 
            "type": "str"
        }
    }
}

Tip

You should always specify at least one checksum to make sure the downloaded artifact is correct.

Examples
artifacts:
    - name: "jolokia"
      url: "https://github.com/rhuss/jolokia/releases/download/v1.3.6/jolokia-1.3.6-bin.tar.gz"
      # The md5 checksum of the artifact
      md5: "75e5b5ba0b804cd9def9f20a70af649f"

    - name: "jolokia"
      url: "https://github.com/rhuss/jolokia/releases/download/v1.3.6/jolokia-1.3.6-bin.tar.gz"
      # Free text description of the artifact
      description: "Library required to access server data via JMX"
      md5: "75e5b5ba0b804cd9def9f20a70af649f"
      # Final name of the downloaded artifact
      target: "jolokia.tar.gz"

Path artifacts

This way of defining artifacts is mostly used in development overrides and enables you to inject artifacts from a local filesystem.

Schema
{
    "map": {
        "description": {
            "desc": "Description of the resource", 
            "type": "str"
        }, 
        "md5": {
            "desc": "The md5 checksum of the resource", 
            "type": "str"
        }, 
        "name": {
            "desc": "Key used to identify the resource", 
            "type": "str"
        }, 
        "path": {
            "desc": "Relative (suggested) or absolute path to the resource", 
            "required": true, 
            "type": "str"
        }, 
        "sha1": {
            "desc": "The sha1 checksum of the resource", 
            "type": "str"
        }, 
        "sha256": {
            "desc": "The sha256 checksum of the resource", 
            "type": "str"
        }, 
        "sha512": {
            "desc": "The sha512 checksum of the resource", 
            "type": "str"
        }, 
        "target": {
            "desc": "Target file name for the resource", 
            "type": "str"
        }
    }
}

Tip

You should always specify at least one checksum to make sure the artifact is correct.

Examples
artifacts:
    - name: jolokia-1.3.6-bin.tar.gz
      path: local-artifacts/jolokia-1.3.6-bin.tar.gz
      md5: 75e5b5ba0b804cd9def9f20a70af649f

Note

If you are using relative path to define an artifact, path is considered relative to an image descriptor which introduced that artifact.

Example
If an artifact is defined inside /foo/bar/image.yaml with a path: baz/1.zip the artifact will be resolved as /foo/bar/baz/1.zip

Image source artifacts

Image source artifacts are used in multi-stage builds. With image source artifacts you can define files built in previous stages of the multi-stage builds.

Schema
{
    "map": {
        "description": {
            "desc": "Description of the resource", 
            "type": "str"
        }, 
        "image": {
            "desc": "Name of the image which holds the resource", 
            "required": true, 
            "type": "str"
        }, 
        "name": {
            "desc": "Key used to identify the resource", 
            "type": "str"
        }, 
        "path": {
            "desc": "Path in the image under which the resource can be found", 
            "required": true, 
            "type": "str"
        }, 
        "target": {
            "desc": "Target file name for the resource", 
            "type": "str"
        }
    }
}

Note

Please note that image source artifacts do not allow for defining checksums due to the nature of this type of artifact.

Examples
artifacts:
    - name: application
      # Name of the image (stage) from where we will fetch the artifact
      image: builder
      # Path to the artifact within the image
      path: /path/to/application/inside/the/builder/image.jar

Packages

Key
packages
Required
No

To install additional RPM packages you can use the packages section where you specify package names and repositories to be used, as well as the package manager that is used to manage packages in this image.

packages:
    repositories:
        - name: extras
            id: rhel7-extras-rpm
    manager: dnf
    install:
        - mongodb24-mongo-java-driver
        - postgresql-jdbc
        - mysql-connector-java
        - maven
        - hostname

Packages to install

Key
install
Required
No

Packages listed in the install section are marked to be installed in the container image.

packages:
    install:
        - mongodb24-mongo-java-driver
        - postgresql-jdbc

Package manager

Key
manager
Required
No

It is possible to define package manager used in the image used to install packages as part of the build process.

Currently available options are yum, dnf, and microdnf.

Note

If you do not specify this key the default value is yum.

It will work fine on Fedora and RHEL images because OS maintains a symlink to the proper package manager.

packages:
    manager: dnf
    install:
        - git

Package repositories

Key
repositories
Required
No

CEKit uses all repositories configured inside the image. You can also specify additional repositories using repositories subsection. CEKit currently supports following ways of defining additional repositories:

Tip

See repository guidelines guide to learn about best practices for repository definitions.

packages:
    repositories:
        - name: scl
          rpm: centos-release-scl
        - name: extras
          id: rhel7-extras-rpm
          description: "Repository containing extras RHEL7 extras packages"

Plain repository

With this approach you specify repository id and CEKit will not perform any action and expect the repository definition exists inside the image. This is useful as a hint which repository must be present for particular image to be buildable. The definition can be overridden by your preferred way of injecting repositories inside the image.

packages:
    repositories:
        - name: extras
          id: rhel7-extras-rpm
          description: "Repository containing extras RHEL7 extras packages"

RPM repository

This ways is using repository configuration files and related keys packaged as an RPM.

Example: To enable CentOS SCL inside the image you should define repository in a following way:

packages:
    repositories:
        - name: scl
          rpm: centos-release-scl

Tip

The rpm key can also specify a URL to a RPM file:

packages:
    repositories:
        - name: epel
          rpm: https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

URL repository

This approach enables you to download a yum repository file and corresponding GPG key. To do it, define repositories section in a way of:

packages:
    repositories:
        - name: foo
          url:
            repository: https://web.example/foo.repo

Content sets

Content sets are tightly integrated to OSBS style of defining repositories in content_sets.yml file. If this kind of repository is present in the image descriptor it overrides all other repositories types. For local Docker based build these repositories are ignored similarly to Plain repository types and we expect repository definitions to be available inside image. See upstream docs for more details about content sets.

Note

Behavior of Content sets repositories is changed when running in Red Hat Environment.

There are two possibilities how to define Content sets type of repository:

Embedded content sets

In this approach content sets are embedded inside image descriptor under the content_sets key.

packages:
    content_sets:
        x86_64:
        - server-rpms
        - server-extras-rpms
Linked content sets

In this approach Contet sets file is linked from a separate yaml file next to image descriptor via content_sets_file key.

Image descriptor:

packages:
    content_sets_file: content_sets.yml

content_sets.yml located next to image descriptor:

x86_64:
  - server-rpms
  - server-extras-rpms

Ports

Key
ports
Required
No

This section is used to mark which ports should be exposed in the container. If we want to highlight a port used in the container, but not necessary expose it – we should set the expose flag to false (true by default).

You can provide additional documentation as to the usage of the port with the keys protocol, to specify which IP protocol is used over the port number (e.g TCP, UDP…) and service to describe what network service is running on top of the port (e.g. “http”, “https”). You can provide a human-readable long form description of the port with the description key.

ports:
    - value: 8443
      service: https
    - value: 8778
      expose: false
      protocol: tcp
      description: internal port for communication.

Volumes

Key
volumes
Required
No

In case you want to define volumes for your image, just use the volumes section!

volumes:
    - name: "volume.eap"
      path: "/opt/eap/standalone"

Note

The name key is optional. If not specified the value of path key will be used.

Modules

Key
modules
Required
No

The modules section is responsible for defining module repositories and providing the list of modules to be installed in order.

modules:
    repositories:
        # Add local modules located next to the image descriptor
        # These modules are specific to the image we build and are not meant
        # to be shared
        - path: modules

        # Add a shared module repository located on GitHub. This repository
        # can contain several modules.
        - git:
            url: https://github.com/cekit/example-common-module.git
            ref: master

    # Install selected modules (in order)
    install:
        - name: jdk8
        - name: user
        - name: tomcat

Module repositories

Key
repositories
Required
No

Module repositories specify location of modules that are to be incorporated into the image. These repositories may be git repositories or directories on the local file system (path). CEKit will scan the repositories for module.xml files, which are used to encapsulate image details that may be incorporated into multiple images.

modules:
  repositories:
      # Modules pulled from Java image project on GitHub
    - git:
          url: https://github.com/jboss-container-images/redhat-openjdk-18-openshift-image
          ref: 1.0

      # Modules pulled locally from "custom-modules" directory, collocated with image descriptor
    - path: custom-modules

Module installation

Key
install
Required
No

The install section is used to define what modules should be installed in the image in what order. Name used to specify the module is the name field from the module descriptor.

modules:
  install:
      - name: xpaas.java
      - name: xpaas.amq.install

You can even request specific module version via version key as follows:

modules:
  install:
      - name: xpaas.java
        version: 1.2-dev
      - name: xpaas.amq.install

Run

Key
run
Required
No

The run section encapsulates instructions related to launching main process in the container including: cmd, entrypoint, user and workdir. All subsections are described later in this paragraph.

Below you can find full example that uses every possible option.

run:
    cmd:
        - "argument1"
        - "argument2"
    entrypoint:
        - "/opt/eap/bin/wrapper.sh"
    user: "alice"
    workdir: "/home/jboss"

Cmd

Key
cmd
Required
No

Command that should be executed by the container at run time.

run:
    cmd:
        - "some cmd"
        - "argument"

Entrypoint

Key
entrypoint
Required
No

Entrypoint that should be executed by the container at run time.

run:
    entrypoint:
        - "/opt/eap/bin/wrapper.sh"

User

Key
user
Required
No

Specifies the user (can be username or uid) that should be used to launch the main process.

run:
    user: "alice"

Working directory

Key
workdir
Required
No

Sets the current working directory of the entrypoint process in the container.

run:
    workdir: "/home/jboss"

Help

Key
help
Required
No

At image build-time CEKit can generate a documentation page about the image. This file is a human-readable conversion of the resulting image descriptor. That is, a descriptor with all overrides and modules combined together, which was used to build the image.

If an image help page is requested to be added to the image (by setting the add key), a help.md is generated and added to the root of the image.

By default image help pages are not generated.

The default help template is supplied within CEKit. You can override it for every image via image definition. The optional help sub-section can define defines a single key template, which can be used to define a filename to use for generating image documentation at build time.

The template is interpreted by the Jinja2 template engine. For a concrete example, see the default help.jinja supplied in the CEKit source code.

help:
  add: true
  template: my_help.md