Chapter 6. Adding software to a UBI container


Red Hat Universal Base Images (UBIs) are built from a subset of the RHEL content. UBIs also provide a subset of RHEL packages that are freely available to install for use with UBI. To add or update software to a running container, you can use the DNF repositories that include RPM packages and updates. UBIs provide a set of pre-built language runtime container images such as Python, Perl, Node.js, Ruby, and so on.

To add packages from UBI repositories to running UBI containers:

  • On UBI init and UBI standard images, use the dnf command
  • On UBI minimal images, use the microdnf command
Note

Installing and working with software packages directly in running containers adds packages temporarily. The changes are not saved in the container image. To make package changes persistent, see section Building an image from a Containerfile with Buildah.

6.1. Using the UBI init images

You can build a container by using a Containerfile that installs and configures a Web server (httpd) to start automatically by the systemd service (/sbin/init) when the container is run on a host system. The podman build command builds an image by using instructions in one or more Containerfiles and a specified build context directory. The context directory can be specified as the URL of an archive, Git repository or Containerfile. If no context directory is specified, then the current working directory is considered as the build context, and must contain the Containerfile. You can also specify a Containerfile with the --file option.

Prerequisites

  • The container-tools meta-package is installed.

Procedure

  1. Create a Containerfile with the following contents to a new directory:

    FROM registry.access.redhat.com/ubi10-beta/ubi-init
    RUN dnf -y install httpd; dnf clean all; systemctl enable httpd;
    RUN echo "Successful Web Server Test" > /var/www/html/index.html
    RUN mkdir /etc/systemd/system/httpd.service.d/; echo -e '[Service]\nRestart=always' > /etc/systemd/system/httpd.service.d/httpd.conf
    EXPOSE 80
    CMD [ "/sbin/init" ]

    The Containerfile installs the httpd package, enables the httpd service to start at boot time, creates a test file (index.html), exposes the Web server to the host (port 80), and starts the systemd init service (/sbin/init) when the container starts.

  2. Build the container:

    # podman build --format=docker -t mysysd .
  3. Optional: If you want to run containers with systemd and SELinux is enabled on your system, you must set the container_manage_cgroup boolean variable:

    # setsebool -P container_manage_cgroup 1
  4. Run the container named mysysd_run:

    # podman run -d --name=mysysd_run -p 80:80 mysysd

    The mysysd image runs as the mysysd_run container as a daemon process, with port 80 from the container exposed to port 80 on the host system.

    Note

    In rootless mode, you have to choose host port number >= 1024. For example:

    $ podman run -d --name=mysysd -p 8081:80 mysysd

    To use port numbers < 1024, you have to modify the net.ipv4.ip_unprivileged_port_start variable:

    # sysctl net.ipv4.ip_unprivileged_port_start=80
  5. Check that the container is running:

    # podman ps
    a282b0c2ad3d  localhost/mysysd:latest  /sbin/init  15 seconds ago  Up 14 seconds ago  0.0.0.0:80->80/tcp  mysysd_run
  6. Test the web server:

    # curl localhost/index.html
    Successful Web Server Test

Additional resources

6.2. Using the UBI micro images

You can build a ubi-micro container image by using the Buildah tool.

Prerequisites

  • The container-tools meta-package is installed.

Procedure

  1. Pull and build the registry.access.redhat.com/ubi10-beta/ubi-micro image:

    # microcontainer=$(buildah from registry.access.redhat.com/ubi10-beta/ubi-micro)
  2. Mount a working container root filesystem:

    # micromount=$(buildah mount $microcontainer)
  3. Install the httpd service to the micromount directory:

    # dnf install \
        --installroot $micromount \
        --releasever=/ \
        --setopt install_weak_deps=false \
        --setopt=reposdir=/etc/yum.repos.d/ \
        --nodocs -y \
        httpd
    # dnf clean all \
        --installroot $micromount
  4. Unmount the root file system on the working container:

    # buildah umount $microcontainer
  5. Create the ubi-micro-httpd image from a working container:

    # buildah commit $microcontainer ubi-micro-httpd

Verification

  1. Display details about the ubi-micro-httpd image:

    # podman images ubi-micro-httpd
    localhost/ubi-micro-httpd latest 7c557e7fbe9f  22 minutes ago  151 MB

6.3. Adding software to a UBI container on a subscribed host

If you are running a UBI container on a registered and subscribed RHEL host, the RHEL Base and AppStream repositories are enabled inside the standard UBI container, along with all the UBI repositories.

  • Red Hat entitlements are passed from a subscribed Red Hat host as a secrets mount defined in /usr/share/containers/mounts.conf on the host running Podman.

    Verify the mounts configuration:

    $ cat /usr/share/containers/mounts.conf
    /usr/share/rhel/secrets:/run/secrets
  • The yum, dnf, and microdnf commands should search for entitlement data at this path.
  • If the path is not present, the commands cannot use Red Hat entitled content, such as the RHV repositories, because they lack the keys or content access the host has.
  • This is applicable only for Red Hat shipped or provided Podman on a RHEL host.
  • If you installed Podman not shipped by Red Hat, follow the instructions in How do I attach subscription data to containers running in Docker not provided by Red Hat? article.

6.4. Adding software in a standard UBI container

To add software inside the standard UBI container, disable non-UBI dnf repositories to ensure the containers you build can be redistributed.

Prerequisites

  • The container-tools meta-package is installed.

Procedure

  1. Pull and run the registry.access.redhat.com/ubi10-beta/ubi image:

    $ podman run -it --name myubi registry.access.redhat.com/ubi10-beta/ubi
  2. Add a package to the myubi container.

    • To add a package that is in the UBI repository, disable all dnf repositories except for UBI repositories. For example, to add the bzip2 package:

      # dnf install --disablerepo=* --enablerepo=ubi-8-appstream-rpms --enablerepo=ubi-8-baseos-rpms bzip2
    • To add a package that is not in the UBI repository, do not disable any repositories. For example, to add the zsh package:

      # dnf install zsh
    • To add a package that is in a different host repository, explicitly enable the repository you need. For example, to install the python38-devel package from the codeready-builder-for-rhel-8-x86_64-rpms repository:

      # dnf install --enablerepo=codeready-builder-for-rhel-8-x86_64-rpms python38-devel

Verification

  1. List all enabled repositories inside the container:

    # dnf repolist
  2. Ensure that the required repositories are listed.
  3. List all installed packages:

    # rpm -qa
  4. Ensure that the required packages are listed.
Note

Installing Red Hat packages that are not inside the Red Hat UBI repositories can limit the ability to distribute the container outside of subscribed RHEL systems.

6.5. Adding software in a minimal UBI container

UBI dnf repositories are enabled inside UBI Minimal images by default.

Prerequisites

  • The container-tools meta-package is installed.

Procedure

  1. Pull and run the registry.access.redhat.com/ubi10-beta/ubi-minimal image:

    $ podman run -it --name myubimin registry.access.redhat.com/ubi10-beta/ubi-minimal
  2. Add a package to the myubimin container:

    • To add a package that is in the UBI repository, do not disable any repositories. For example, to add the bzip2 package:

      # microdnf install bzip2 --setopt install_weak_deps=false
    • To add a package that is in a different host repository, explicitly enable the repository you need. For example, to install the python38-devel package from the codeready-builder-for-rhel-8-x86_64-rpms repository:

      # microdnf install --enablerepo=codeready-builder-for-rhel-8-x86_64-rpms python38-devel --setopt install_weak_deps=false

      The --setopt install_weak_deps=false option disables the installation of weak dependencies. Weak dependencies include recommended or suggested packages that are not strictly required but are often installed by default.

Verification

  1. List all enabled repositories inside the container:

    # microdnf repolist
  2. Ensure that the required repositories are listed.
  3. List all installed packages:

    # rpm -qa
  4. Ensure that the required packages are listed.
Note

Installing Red Hat packages that are not inside the Red Hat UBI repositories can limit the ability to distribute the container outside of subscribed RHEL systems.

6.6. Adding software to a UBI container on a unsubscribed host

You do not have to disable any repositories when adding software packages on unsubscribed RHEL systems.

Prerequisites

  • The container-tools meta-package is installed.

Procedure

  • Add a package to a running container based on the UBI standard or UBI init images. Do not disable any repositories. Use the podman run command to run the container. then use the dnf install command inside a container.

    • For example, to add the bzip2 package to the UBI standard based container:

      $ podman run -it --name myubi registry.access.redhat.com/ubi10-beta/ubi
      # dnf install bzip2
    • For example, to add the bzip2 package to the UBI init based container:

      $ podman run -it --name myubimin registry.access.redhat.com/ubi10-beta/ubi-minimal
      # microdnf install bzip2

Verification

  1. List all enabled repositories:

    • To list all enabled repositories inside the containers based on UBI standard or UBI init images:

      #  dnf repolist
    • To list all enabled repositories inside the containers based on UBI minimal containers:

      # microdnf repolist
  2. Ensure that the required repositories are listed.
  3. List all installed packages:

    # rpm -qa
  4. Ensure that the required packages are listed.

6.7. Building UBI-based images

You can create a UBI-based web server container from a Containerfile by using the Buildah utility. You have to disable all non-UBI dnf repositories to ensure that your image contains only Red Hat software that you can redistribute.

Note

For UBI minimal images, use microdnf instead of dnf: RUN microdnf update -y && rm -rf /var/cache/yum and RUN microdnf install httpd -y && microdnf clean all commands.

Prerequisites

  • The container-tools meta-package is installed.

Procedure

  1. Create a Containerfile:

    FROM registry.access.redhat.com/ubi10-beta/ubi
    USER root
    LABEL maintainer="John Doe"
    # Update image
    RUN dnf update --disablerepo=* --enablerepo=ubi-8-appstream-rpms --enablerepo=ubi-8-baseos-rpms -y && rm -rf /var/cache/yum
    RUN dnf install --disablerepo=* --enablerepo=ubi-8-appstream-rpms --enablerepo=ubi-8-baseos-rpms httpd -y && rm -rf /var/cache/yum
    # Add default Web page and expose port
    RUN echo "The Web Server is Running" > /var/www/html/index.html
    EXPOSE 80
    # Start the service
    CMD ["-D", "FOREGROUND"]
    ENTRYPOINT ["/usr/sbin/httpd"]
  2. Build the container image:

    # buildah bud -t johndoe/webserver .
    STEP 1: FROM registry.access.redhat.com/ubi10-beta/ubi:latest
    STEP 2: USER root
    STEP 3: LABEL maintainer="John Doe"
    STEP 4: RUN dnf update --disablerepo=* --enablerepo=ubi-8-appstream-rpms --enablerepo=ubi-8-baseos-rpms -y
    ...
    Writing manifest to image destination
    Storing signatures
    --> f9874f27050
    f9874f270500c255b950e751e53d37c6f8f6dba13425d42f30c2a8ef26b769f2

Verification

  1. Run the web server:

    # podman run -d --name=myweb -p 80:80 johndoe/webserver
    bbe98c71d18720d966e4567949888dc4fb86eec7d304e785d5177168a5965f64
  2. Test the web server:

    # curl http://localhost/index.html
    The Web Server is Running

6.8. Using Application Stream runtime images

Runtime images based on Application Streams offer a set of container images that you can use as the basis for your container builds.

Supported runtime images are Python, Ruby, s2-core, s2i-base, .NET Core, PHP. The runtime images are available in the Red Hat Container Catalog.

Note

Because these UBI images contain the same basic software as their legacy image counterparts, you can learn about those images from the Using Red Hat Software Collections Container Images guide.

6.9. Getting UBI container image source code

Source code is available for all Red Hat UBI-based images in the form of downloadable container images. Source container images cannot be run, despite being packaged as containers. To install Red Hat source container images on your system, use the skopeo command, not the podman pull command.

Source container images are named based on the binary containers they represent. For example, for a particular standard RHEL UBI 10-beta container registry.access.redhat.com/ubi10-beta:8.1-397 append -source to get the source container image (registry.access.redhat.com/ubi10-beta:8.1-397-source).

Prerequisites

  • The container-tools meta-package is installed.

Procedure

  1. Use the skopeo copy command to copy the source container image to a local directory:

    $ skopeo copy \
    docker://registry.access.redhat.com/ubi10-beta:8.1-397-source \
    dir:$HOME/TEST
    ...
    Copying blob 477bc8106765 done
    Copying blob c438818481d3 done
    ...
    Writing manifest to image destination
    Storing signatures
  2. Use the skopeo inspect command to inspect the source container image:

    $ skopeo inspect dir:$HOME/TEST
    {
        "Digest": "sha256:7ab721ef3305271bbb629a6db065c59bbeb87bc53e7cbf88e2953a1217ba7322",
        "RepoTags": [],
        "Created": "2020-02-11T12:14:18.612461174Z",
        "DockerVersion": "",
        "Labels": null,
        "Architecture": "amd64",
        "Os": "linux",
        "Layers": [
            "sha256:1ae73d938ab9f11718d0f6a4148eb07d38ac1c0a70b1d03e751de8bf3c2c87fa",
            "sha256:9fe966885cb8712c47efe5ecc2eaa0797a0d5ffb8b119c4bd4b400cc9e255421",
            "sha256:61b2527a4b836a4efbb82dfd449c0556c0f769570a6c02e112f88f8bbcd90166",
            ...
            "sha256:cc56c782b513e2bdd2cc2af77b69e13df4ab624ddb856c4d086206b46b9b9e5f",
            "sha256:dcf9396fdada4e6c1ce667b306b7f08a83c9e6b39d0955c481b8ea5b2a465b32",
            "sha256:feb6d2ae252402ea6a6fca8a158a7d32c7e4572db0e6e5a5eab15d4e0777951e"
        ],
        "Env": null
    }
  3. Unpack all the content:

    $ cd $HOME/TEST
    $ for f in $(ls); do tar xvf $f; done
  4. Check the results:

    $ find blobs/ rpm_dir/
    blobs/
    blobs/sha256
    blobs/sha256/10914f1fff060ce31388f5ab963871870535aaaa551629f5ad182384d60fdf82
    rpm_dir/
    rpm_dir/gzip-1.9-4.el8.src.rpm

    If the results are correct, the image is ready to be used.

Note

It could take several hours after a container image is released for its associated source container to become available.

Additional resources

  • skopeo-copy (1) and skopeo-inspect(1) man pages on your system
Red Hat logoGithubRedditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

© 2024 Red Hat, Inc.