Universal Base Image

Red Hat Universal Base Images (UBIs) allow developers using Docker on Windows and Mac platforms to tap into the benefits of the large Red Hat ecosystem. This article demonstrates how to use Red Hat Universal Base Images with Docker from a non-Red Hat system, such as a Windows or Mac workstation.

Red Hat Enterprise Linux and Docker

When Red Hat Enterprise Linux (RHEL) 8 was released almost a year ago, and it came with lots of new features related to containers. The biggest ones were the new container tools (Podman, Buildah, and skopeo) and the new Red Hat Universal Base Images. There was also confusion because RHEL 8 dropped support for the Docker toolset. Some developers thought that they could not work with Docker anymore, and had to either migrate to a Red Hat-ecosystem Linux system such as CentOS or stay away from Red Hat customers.

This situation was far from the truth because containers are not just about Docker anymore. Container runtimes, container images, registry servers, and other technologies related to the Linux container ecosystem are now standardized by the Open Container Initiative (OCI). Thanks to the OCI, you can develop a container using one tool and then run the same container using another tool. For example, Red Hat builds a container image using Buildah on RHEL 8, and then you run that container image using Docker on a Windows system.

Another example would be you building a container image using Docker on a Mac system and then later you run that container image on a Red Hat Enterprise Linux 8 server with Podman.

Introducing Red Hat Universal Base Images

Red Hat Universal Base images allow commercial and open source developers to build containers based on RHEL without requiring them or their users to be RHEL subscribers. Open source developers need the ability to run and share their applications anywhere, unencumbered by user agreements. While the Red Hat Developer subscription is useful and popular, it was not the best fit for them.

Some commercial developers want to target both Red Hat customers and non-Red Hat customers. Their Red Hat customers want the ability to use Red Hat support services to their fullest, which implies running container images based on RHEL. So, these developers had to build two versions of their container images, one based on Red Hat Enterprise Linux, and others based on something else, or they had to deny their customers the ability to rely on Red Hat’s support services.

Commercial and open source developers can use UBI to build container images from RHEL packages, and benefit from Red Hat’s fixes to performance and security issues. At the same time, using UBIs does not require any entitlement to a Red Hat subscription, not even a free Red Hat Developer program subscription.

Universal Base Images and packages

UBIs provide a set of base container images to build your application images. Some of these images include only the base operating systems. Others are runtime images that provide a runtime with its dependencies pre-integrated.

UBIs also provide a set of Yum repositories that include a subset of Red Hat Enterprise Linux packages. Not all of RHEL is part of the UBI repositories. As an example, UBIs do not include packages related to low-level network and storage servers.

Exploring Universal Base Images

The best way to see what is provided by UBIs is through a few searches. In the following examples, the prompt is $, which could be on a Mac system running Docker Desktop. This same prompt could also be on a Windows Home system using Docker tools from a Cygwin terminal, or a Windows Professional system using Docker Desktop. It could even be on a non-Red Hat Linux distribution.

First, do a search for all UBI base images on the Red Hat Container Registry:

$ docker search registry.access.redhat.com/ubi
NAME                                          DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
jboss-eap-7/eap72-openjdk11-openshift-rhel8   JBoss EAP 7.2 OpenJDK 11 Container Image for…   0      
ubi8/ubi-init                                 Provides the latest release of the Red Hat U…   0      
ubi8/ubi                                      Provides the latest release of the Red Hat U…   0      
ubi8/ubi-minimal                              Provides the latest release of the Minimal R…   0      
ubi7/ubi-init                                 The Universal Base Image Init is designed to…   0      
ubi7/ubi                                      The Universal Base Image is designed and eng…   0      
ubi7/ubi-minimal                              The Universal Base Image Init is designed to…   0

The Red Hat Container Registry is a public registry that hosts all UBI container images. These same images are also available from the Red Hat terms-based container registry. That registry server requires you to authenticate to prove that you have a valid Red Hat subscription. During this article, I’ll stick to Red Hat’s public registry for ease of use.

Now, start a UBI test container running an interactive shell:

$ docker run -it --name test registry.access.redhat.com/ubi8/ubi:8.1 bash
Unable to find image 'registry.access.redhat.com/ubi8/ubi:8.1' locally
8.1: Pulling from ubi8/ubi
eae5d284042d: Pull complete
ff6f434a470a: Pull complete
Digest: sha256:b6ae810838a1a105b568e5b438a4379ac5e06ee8df1c11d71772f8708180ffcc
Status: Downloaded newer image for registry.access.redhat.com/ubi8/ubi:8.1
[root@de1d73d88418 /]#

Inside the test container, list its preconfigured Yum repositories:

[root@de1d73d88418 /]# yum repolist
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
Red Hat Universal Base Image 8 (RPMs) - BaseOS                                                      123 kB/s | 760 kB     00:06    
Red Hat Universal Base Image 8 (RPMs) - AppStream                                                   301 kB/s | 3.3 MB     00:11    
Red Hat Universal Base Image 8 (RPMs) - CodeReady Builder                                           2.2 kB/s | 9.1 kB     00:04    
repo id                                       repo name                                                                       status
ubi-8-appstream                               Red Hat Universal Base Image 8 (RPMs) - AppStream                               819
ubi-8-baseos                                  Red Hat Universal Base Image 8 (RPMs) - BaseOS                                  664
ubi-8-codeready-builder                       Red Hat Universal Base Image 8 (RPMs) - CodeReady Builder                        12

Note: You can safely ignore Yum messages about Red Hat’s subscription manager. UBI images are designed to work for Red Hat subscribers as well, letting them add packages from Red Hat Enterprise Linux that require a valid entitlement.

You can also search for individual packages available from these repositories. The following example searches for Nginx web server packages:

[root@de1d73d88418 /]# yum search nginx
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
Last metadata expiration check: 0:00:06 ago on Mon Feb 24 23:37:46 2020.
=================================================== Name Exactly Matched: nginx ====================================================
nginx.x86_64 : A high performance web server and reverse proxy server
================================================== Name & Summary Matched: nginx ===================================================
nginx-mod-mail.x86_64 : Nginx mail modules
nginx-mod-stream.x86_64 : Nginx stream modules
nginx-mod-http-perl.x86_64 : Nginx HTTP perl module
nginx-mod-http-xslt-filter.x86_64 : Nginx XSLT module
nginx-mod-http-image-filter.x86_64 : Nginx HTTP image filter module
nginx-filesystem.noarch : The basic directory layout for the Nginx server
nginx-all-modules.noarch : A meta package that installs all available Nginx modules

Finally, leave the test container, stop, and remove it:

[root@de1d73d88418 /]# exit
$ docker stop test
test
$ docker rm test
test

As you can see, running UBIs using Docker just works. But what about building container images based on Universal Base Images?

A sample Dockerfile for a PHP application

The following listing shows a sample Dockerfile for a PHP application:

FROM registry.access.redhat.com/ubi8/ubi:8.1

RUN yum --disableplugin=subscription-manager -y module enable php:7.3 \
  && yum --disableplugin=subscription-manager -y install httpd php \
  && yum --disableplugin=subscription-manager clean all

ADD index.php /var/www/html

RUN sed -i 's/Listen 80/Listen 8080/' /etc/httpd/conf/httpd.conf \
  && sed -i 's/listen.acl_users = apache,nginx/listen.acl_users =/' /etc/php-fpm.d/www.conf \
  && mkdir /run/php-fpm \
  && chgrp -R 0 /var/log/httpd /var/run/httpd /run/php-fpm \
  && chmod -R g=u /var/log/httpd /var/run/httpd /run/php-fpm

EXPOSE 8080
USER 1001
CMD php-fpm & httpd -D FOREGROUND

The second RUN instruction allows the image to run unchanged under OpenShift’s default security policies and also under rootless podman. Otherwise, that image would require running as the root user, something that regular OpenShift users cannot do.

You also need a "hello, world"-style PHP page for the index.php file:

<html>
<body>
<?php print "Hello, world!\n" ?>
</body>
</html>

Now build the sample image:

$  docker build -t php-hello .
Sending build context to docker daemon  3.584kB
Step 1/7 : FROM registry.access.redhat.com/ubi8/ubi:8.1
 ---> fd73e6738a95
...
Successfully tagged php-hello:latest

And start a container from the sample image:

$ docker run --name hello -p 8080:8080 -d php-hello

Finally, open a web browser and access localhost:8080 to see the Hello, world! message returned by your sample container. When you are happy with the results, stop and delete the sample container:

$ docker stop hello
hello
$ docker rm hello
hello

As you see, there is nothing unusual about using Universal Base Images with Docker. They just work.

Updated on September 14, 2020: Fixed the sample Dockerfile to work with rootless podman from RHEL 8.1+ and Fedora. The change does not affect running under Docker and early OpenShift 4.x.

Learning more about UBIs

Last updated: February 22, 2024