Chapter 1. Creating container images


As an application developer, create container images using buildah, source-to-image, or the buildpacks strategy, depending on your source code, framework, and automation requirements. You can also use Open Container Initiative (OCI) artifacts to build container images.

1.1. Creating a buildah build

Use a buildah build strategy to build and push a container image using a Dockerfile.

Prerequisites

  • You have installed the Builds for Red Hat OpenShift Operator on the OpenShift Container Platform cluster.
  • You have installed the oc CLI.
  • Optional: You have installed the shp CLI.

Procedure

  1. Create a Build resource and apply it to the OpenShift Container Platform cluster. You can do so by using the oc command or the shp command:

    $ oc apply -f - <<EOF
    apiVersion: shipwright.io/v1beta1
    kind: Build
    metadata:
      name: buildah-golang-build
    spec:
      source:
        type: Git
        git:
          url: https://github.com/shipwright-io/sample-go
        contextDir: docker-build
      strategy:
        name: buildah
        kind: ClusterBuildStrategy
      paramValues:
      - name: dockerfile
        value: Dockerfile
      output:
        image: image-registry.openshift-image-registry.svc:5000/buildah-example/sample-go-app
    EOF

    where:

    source
    Defines the location where the source code is placed.
    strategy
    Defines the build strategy that you use to build the container.
    paramValues
    Defines the parameter defined in the build strategy. To set the value of the dockerfile strategy parameter, specify the Dockerfile location required to build the output image.
    output
    Defines the location where the built image is pushed. In this procedural example, the built image is pushed to the OpenShift Container Platform cluster internal registry. buildah-example is the name of the current project. Ensure that the specified project exists to allow the image push.
    $ shp build create buildah-golang-build \
    --source-url="https://github.com/redhat-openshift-builds/samples"
    --source-context-dir="buildah-build" \
    --strategy-name="buildah" \
    --dockerfile="Dockerfile" \
    --output-image="image-registry.openshift-image-registry.svc:5000/buildah-example/go-app"

    where:

    source-context-dir
    Defines the location where the source code is placed.
    strategy-name
    Defines the build strategy that you use to build the container.
    dockerfile
    Defines the parameter defined in the build strategy. To set the value of the dockerfile strategy parameter, specifies the Dockerfile location required to build the output image.
    output-image
    Defines the location where the built image is pushed. In this procedural example, the built image is pushed to the OpenShift Container Platform cluster internal registry. buildah-example is the name of the current project. Ensure that the specified project exists to allow the image push.
  2. Check if the Build resource is created. You can do so by using the oc command or the shp command:

    $ oc get builds.shipwright.io buildah-golang-build
    $ shp build list
  3. Create a BuildRun resource and apply it to the OpenShift Container Platform cluster. You can do so by using the oc command or the shp command:

    $ oc apply -f - <<EOF
    apiVersion: shipwright.io/v1beta1
    kind: BuildRun
    metadata:
      name: buildah-golang-buildrun
    spec:
      build:
        name: buildah-golang-build
    EOF

    where:

    spec.build.name
    Defines the build to run, which is expected to be available in the same namespace.
    $ shp build run buildah-golang-build --follow
    • --follow:: (Optional) Use the --follow flag to view the build logs in the output result.
  4. Check if the BuildRun resource is created. You can do so by using the oc command or the shp command:

    $ oc get buildrun buildah-golang-buildrun
    $ shp buildrun list

    The BuildRun resource creates a TaskRun resource, which then creates the pods to execute build strategy steps.

Verification

After all the containers complete their tasks, verify the following resources:

  1. Check whether the pod shows the STATUS field as Completed:

    $ oc get pods -w

    Example output:

    NAME                                READY   STATUS    RESTARTS   AGE
    buildah-golang-buildrun-dtrg2-pod   2/2     Running   0          4s
    buildah-golang-buildrun-dtrg2-pod   1/2     NotReady  0          7s
    buildah-golang-buildrun-dtrg2-pod   0/2     Completed 0          55s
  2. Check whether the respective TaskRun resource shows the SUCCEEDED field as True:

    $ oc get tr

    Example output:

    NAME                           SUCCEEDED  REASON     STARTTIME   COMPLETIONTIME
    buildah-golang-buildrun-dtrg2  True       Succeeded  11m         8m51s
  3. Check whether the respective BuildRun resource shows the SUCCEEDED field as True:

    $ oc get br

    Example output:

    NAME                     SUCCEEDED   REASON       STARTTIME     COMPLETIONTIME
    buildah-golang-buildrun  True        Succeeded    13m           11m
  4. During verification, if a build run fails, you can check the status.failureDetails field in your BuildRun resource to identify the exact point where the failure happened in the pod or container.

    Note

    The pod might switch to a NotReady state because one of the containers has completed its task. This is an expected behavior.

  5. Validate whether the image has been pushed to the registry that is specified in the build.spec.output.image field. Run the following command to pull the image from a node that can access the internal registry:

    $ podman manifest inspect image-registry.openshift-image-registry.svc:5000/buildah-example/taxi-app

    In the previous example, the project name is buildah-example, and the image name is taxi-app.

    Example output:

       "schemaVersion": 2,
        "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
        "manifests": [
            {
                "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
                "size": 594,
                "digest": "sha256:6a05100e302c86c03fec6277f4b3107f1fdde6c69d3ca9a4207e4735a5213e32",
                "platform": {
                    "architecture": "amd64",
                    "os": "linux"
                }
         ]

1.2. Creating a source-to-image build

Use a source-to-image (S2I) build strategy to turn application source code into a container image using a base image.

Prerequisites

  • You have installed the Builds for Red Hat OpenShift Operator on the OpenShift Container Platform cluster.
  • You have installed the oc CLI.
  • Optional: You have installed the shp CLI.

Procedure

  1. Create a Build resource and apply it to the OpenShift Container Platform cluster. You can do so by using the oc command or the shp command:

    $ oc apply -f - <<EOF
    apiVersion: shipwright.io/v1beta1
    kind: Build
    metadata:
      name: s2i-nodejs-build
    spec:
      source:
        type: Git
        git:
          url: https://github.com/redhat-openshift-builds/samples
        contextDir: s2i-build/nodejs
      strategy:
        name: source-to-image
        kind: ClusterBuildStrategy
      paramValues:
      - name: builder-image
        value: quay.io/centos7/nodejs-12-centos7:master
      output:
        image: quay.io/<repo>/s2i-nodejs-example
        pushSecret: registry-credential
    EOF

    where:

    source
    Defines the location where the source code is placed.
    strategy
    Defines the build strategy that you use to build the container.
    paramValues
    Defines the parameters for the build strategy. For source-to-image builds, this includes the builder-image parameter that specifies the base image used to build your application.
    output
    Defines the location where the built image is pushed. In this procedural example, the built image is pushed to the OpenShift Container Platform cluster internal registry. buildah-example is the name of the current project. Ensure that the specified project exists to allow the image push.
    pushSecret
    Defines the secret name that stores the credentials for pushing container images. To generate a secret of the type docker-registry for authentication, see "Authentication to container registries".
    $ shp build create s2i-nodejs-build \
    --source-url="https://github.com/redhat-openshift-builds/samples" --source-context-dir="s2i-build/nodejs" \
    --strategy-name="source-to-image" \
    --builder-image="quay.io/centos7/nodejs-12-centos7" \
    --output-image="quay.io/<repo>/s2i-nodejs-example" \
    --output-credentials-secret="registry-credential"

    where:

    source-context-dir
    Defines the location where the source code is placed.
    strategy-name
    The build strategy that you use to build the container.
    builder-image
    The parameter defined in the build strategy. For source-to-image builds, this specifies the base image used to build your application.
    output-image
    The location where the built image is pushed. In this procedural example, the built image is pushed to the OpenShift Container Platform cluster internal registry. buildah-example is the name of the current project. Ensure that the specified project exists to allow the image push.
    output-credentials-secret
    The secret name that stores the credentials for pushing container images. To generate a secret of the type docker-registry for authentication, see "Authentication to container registries".
  2. Check if the Build resource is created. You can do so by using the oc command or the shp command:

    $ oc get builds.shipwright.io s2i-nodejs-build
    $ shp build list
  3. Create a BuildRun resource and apply it to the OpenShift Container Platform cluster. You can do so by using the oc command or the shp command:

    $ oc apply -f - <<EOF
    apiVersion: shipwright.io/v1beta1
    kind: BuildRun
    metadata:
      name: s2i-nodejs-buildrun
    spec:
      build:
        name: s2i-nodejs-build
    EOF

    where:

    spec.build.name
    Specifies the respective build to run, which is expected to be available in the same namespace.
    $ shp build run s2i-nodejs-build --follow

    + where:

    --follow
    (Optional) Use the --follow flag to view the build logs in the output result.
  4. Check if the BuildRun resource is created. You can do so by using the oc command or the shp command:

    $ oc get buildrun s2i-nodejs-buildrun
    $ shp buildrun list

    The BuildRun resource creates a TaskRun resource, which then creates the pods to execute build strategy steps.

Verification

After all the containers complete their tasks, verify the statuses of the following resources:

  1. Check whether the pod shows the STATUS field as Completed:

    $ oc get pods -w

    Example output:

    NAME                                READY   STATUS     RESTARTS   AGE
    s2i-nodejs-buildrun-phxxm-pod       2/2     Running    0          10s
    s2i-nodejs-buildrun-phxxm-pod       1/2     NotReady   0          14s
    s2i-nodejs-buildrun-phxxm-pod       0/2     Completed  0          2m
  2. Check whether the respective TaskRun resource shows the SUCCEEDED field as True:

    $ oc get tr

    Example output:

    NAME                           SUCCEEDED  REASON     STARTTIME   COMPLETIONTIME
    s2i-nodejs-buildrun-phxxm      True       Succeeded  2m39s        13s
  3. Check whether the respective BuildRun resource shows the SUCCEEDED field as True:

    $ oc get br

    Example output:

    NAME                     SUCCEEDED   REASON       STARTTIME     COMPLETIONTIME
    s2i-nodejs-buildrun      True        Succeeded    2m41s           15s
  4. During verification, if a build run fails, you can check the status.failureDetails field in your BuildRun resource to identify the exact point where the failure happened in the pod or container.

    Note

    The pod might switch to a NotReady state because one of the containers has completed its task. This is an expected behavior.

  5. Validate whether the image has been pushed to the registry that is specified in the build.spec.output.image field. Log in to the registry and run the following command to pull the image:

    $ podman manifest inspect image-registry.openshift-image-registry.svc:5000/s2i-example/taxi-app

    In the previous example, the project name is s2i-example, and the image name is taxi-app.

    Example output:

       "schemaVersion": 2,
        "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
        "manifests": [
            {
                "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
                "size": 594,
                "digest": "sha256:6a05100e302c86c03fec6277f4b3107f1fdde6c69d3ca9a4207e4735a5213e32",
                "platform": {
                    "architecture": "amd64",
                    "os": "linux"
                }
         ]

1.3. Creating a buildpacks build

Use a buildpacks build to create and push container images to the target registry. The buildpacks cluster build strategy supports buildpacks and buildpacks-extender strategies.

Important

Builds for Red Hat OpenShift supports the execution process for Cloud Native Buildpacks (CNB) within the build strategies. Red Hat does not provide support for the content of user-provided builder and runtime images. For more information on Cloud Native Buildpacks (CNB), see Cloud Native Buildpacks.

Prerequisites

  • You have installed the Builds for Red Hat OpenShift Operator on the OpenShift Container Platform cluster.
  • You have installed the oc CLI.
  • You have created the project where your final application image is stored by using the command oc new-project buildpacks-example.
  • Optional: You have installed the shp CLI.
Important

Using shp CLI with buildpacks requires additional permissions setup that you must complete before you start creating a buildpacks build.

Procedure

  1. Optional: Run the following commands to use the shp CLI with buildpacks and grant the pipeline service account permission to access the image registry in the buildpacks-example project.

    $ oc policy add-role-to-user system:image-puller system:serviceaccount:default:pipeline --namespace=buildpacks-example
    $ oc policy add-role-to-user system:image-pusher system:serviceaccount:default:pipeline --namespace=buildpacks-example
  2. Optional: Continue with shp CLI by switching back to the primary working project:

    $ oc project default
  3. Optional: Run the following command to apply the permission and finish shp CLI setup:

    $ oc create rolebinding allow-builds-to-push \
    
      --clusterrole=edit \
    
     --serviceaccount=default:pipeline \
    
    --namespace=buildpacks-example
  4. Create a Build resource and apply it to the OpenShift Container Platform cluster. You can do so by using the oc command or the shp command:

    $ oc apply -f - <<EOF
    apiVersion: shipwright.io/v1beta1
    kind: Build
    metadata:
      name: buildpack-nodejs-build
    spec:
      source:
        type: Git
        git:
          url: https://github.com/redhat-openshift-builds/samples.git
      strategy:
        name: buildpacks
        kind: ClusterBuildStrategy
      retention:
        atBuildDeletion: true
      paramValues:
        - name: run-image
          value: paketobuildpacks/run-ubi8-base:latest
        - name: cnb-builder-image
          value: paketobuildpacks/builder-jammy-tiny:0.0.344
        - name: source-subpath
          value: "buildpacks/nodejs"
      output:
        image: image-registry.openshift-image-registry.svc:5000/buildpacks-example/taxi-app
    EOF

    where:

    source
    Specifies the Git repository containing your application source code.
    strategy
    Specifies the build strategy to build the container.
    paramValues
    Specifies the parameters set for the buildpacks strategy.
    name: run-image
    Specifies the base image on which your application runs.
    name: cnb-builder-image
    Specifies the builder image used by Cloud Native Buildpacks (CNB) to detect and build your application.
    name: source-subpath
    Specifies the subdirectory within your Git repository where the application source code is located.
    output
    Specifies the location where the built image is pushed.
    $ shp build create buildpack-nodejs-build \
    --source-git-url="https://github.com/redhat-openshift-builds/samples.git" \
    --strategy-name="buildpacks" \
    --output-image="image-registry.openshift-image-registry.svc:5000/buildpacks-example/taxi-app" \
    --param-value="source-subpath=buildpacks/nodejs" \
    --param-value="cnb-builder-image=paketobuildpacks/builder-jammy-tiny:0.0.344" \
    --param-value="run-image=paketobuildpacks/run-ubi8-base:latest"
  5. Check if the Build resource is created. You can do so by using the oc command or the shp command:

    $ oc get builds.shipwright.io buildpack-nodejs-build
    $ shp build list
  6. Create a BuildRun resource and apply it to the OpenShift Container Platform cluster. You can do so by using the oc command or the shp command:

    $ oc apply -f - <<EOF
    apiVersion: shipwright.io/v1beta1
    kind: BuildRun
    metadata:
      name: buildpack-nodejs-buildrun
      namespace: builds-test
    spec:
      build:
        name: buildpack-nodejs-build
    EOF

    where:

    spec.build.name

    Specifies the buildpack-nodejs-build resource that will be executed.

    $ shp build run buildpack-nodejs-buildrun --follow
    Important

    The shp CLI version 0.16.0 cannot automatically generate a name for the BuildRun resource. You must create the name manually:

    1. Create a BuildRun resource with a unique name.

      $ shp buildrun create buildpack-nodejs-<buildrun_resource_name>  --buildref-name buildpack-nodejs-build

      where:

      <buildrun_resource_name>
      Specifies the buildrun resource name
      --buildref-name buildpack-nodejs-build
      Defines the flag referencing the build.
    2. Follow the logs:

      $ shp buildrun logs buildpack-nodej-<buildrun_resource_name> --follow
  7. Check if the BuildRun resource is created. You can do so by using the oc command or the shp command:

    $ oc get buildrun buildpack-nodejs-buildrun
    $ shp buildrun list
    Note

    The BuildRun resource creates a TaskRun resource, which then creates the pods to execute build strategy steps.

Verification

  1. Wait for all containers to complete their tasks.
  2. Check if the pod shows the STATUS field as Completed:

    $ oc get pods -w

    Example output:

    NAME                                 READY   STATUS     RESTARTS   AGE
    buildpack-go-build-ttwkl-d8x97-pod   2/8     NotReady   0          63s
    buildpack-go-build-ttwkl-d8x97-pod   0/8     Completed   0          72s
    buildpack-go-build-ttwkl-d8x97-pod   0/8     Completed   0          73s
  3. Check if the TaskRun resource shows the SUCCESS field as True:

    $ oc get tr

    Example output:

    NAME                             SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
    buildpack-go-build-ttwkl-d8x97   True        Succeeded   112s        38s
  4. Check if the BuildRun resource shows the SUCCESS field as True:

    $ oc get br

    Example output:

    NAME                       SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
    buildpack-go-build-ttwkl   True        Succeeded   107s        33s
    Note

    If the build run fails, you can check the status.failureDetails field in your BuildRun resource to identify the exact point where the failure happened in the pod or container.

    The pod might switch to a NotReady state because one of the containers has completed its task. This is an expected behavior.

  5. Run the following command from a node that can access internal registry to pull the image to check if the image has been pushed to the registry you specified in the build.spec.output.image field:

    $ podman manifest inspect image-registry.openshift-image-registry.svc:5000/buildpacks-example/taxi-app

    In the previous example, the project name is buildpacks-example, and the image name is taxi-app.

    Example output:

       "schemaVersion": 2,
        "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
        "manifests": [
            {
                "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
                "size": 594,
                "digest": "sha256:6a05100e302c86c03fec6277f4b3107f1fdde6c69d3ca9a4207e4735a5213e32",
                "platform": {
                    "architecture": "amd64",
                    "os": "linux"
                }
         ]

1.4. Creating a build with OCI artifacts

Use Open Container Initiative (OCI) artifacts, also called scratch images, that you store in a registry as source code to build a container image. Pull and extract them to use as the source for your build; they contain only source code, not a runnable container.

Prerequisites

  • You have installed the Builds for Red Hat OpenShift Operator on the OpenShift Container Platform cluster.
  • You have installed the oc command-line interface (CLI).
  • You have installed the shp CLI.

Procedure

  1. Create a Build resource and apply it to the OpenShift Container Platform cluster. See the following example configuration:

    $ oc apply -f - <<EOF
    apiVersion: shipwright.io/v1beta1
    kind: Build
    metadata:
      name: <build_resource_name>
    spec:
      source:
        type: OCI
        ociArtifact:
          image: <quay.io/org/image:tag>
      strategy:
        name: <strategy_name>
        kind: ClusterBuildStrategy
      output:
        image: <target_image_registry/repository/image:tag>
        pushSecret: <secret_name_for_credentials>
    EOF

    where:

    <build_resource_name>
    Specifies the name of the Build resource.
    <quay.io/org/image:tag>
    Specifies the location of the OCI artifact source image.
    <strategy_name>
    Specifies the name of the build strategy to build the container.
    <target_image_registry/repository/image:tag>
    Specifies the location where you want to push the built image.
    <secret_name_for_credentials>
    (Optional) Specifies the secret name that stores the credentials for pushing container images. To generate a secret for a private registry for authentication, see Authentication to container registries.
  2. Choose one of the following methods to upload your source code to the required registry and run the build:

    • Upload the source code using the shp CLI:

      • Run the following command in the directory containing the local source code. It packages your source code into a scratch container image, pushes it to the required registry, and runs the build:

        $ shp build upload <build_resource_name>

        where:

        <build_resource_name>
        Specifies the name of the Build resource.
    • Upload the OCI artifact manually:

      1. Create a Containerfile in the root directory of your source code and add the following configuration:

        FROM scratch
        COPY . /
      2. Run the following command in the root directory of your source code to build the container image using Podman:

        $ podman build -t <registry_path>/<image_name>:<tag> .

        where:

        <registry_path>
        Specifies the build location for the registry where the image is stored.
        <image_name>
        Specifies the name of the container image.
        <tag>

        Specifies the tag of the image.

        When the container image is built successfully, a success message is displayed. See the following example command and output:

        podman build -t quay.io/example/oci:latest .
        STEP 1/2: FROM scratch
        STEP 2/2: COPY . /
        --> Using cache 31f2530b092a8e0d75586407052900e9946043eca09deb9a2c9e50c2541bfcfd
        COMMIT quay.io/example/oci:latest
        --> 31f2530b092a
        Successfully tagged quay.io/example/oci:latest
        31f2530b092a8e0d75586407052900e9946043eca09deb9a2c9e50c2541bfcfd
      3. Push the container image to the required location using the following command:

        $ podman push <registry_path>/<image_name>:<tag>

        where:

        <registry_path>
        Specifies the build location for the registry where the image is stored.
        <image_name>
        Specifies the name of the container image.
        <tag>
        Specifies the tag of the image.
      4. Run the build using the following command:

        $ shp build run <build_resource_name>

        where:

        <build_resource_name>
        Specifies the name of the Build resource.

Verification

After all the containers complete their tasks, verify the statuses of the following resources:

  1. Check whether the pod shows the STATUS field as Completed:

    $ oc get pods -w

    Example output:

    NAME                                READY   STATUS     RESTARTS   AGE
    oci-artifact-buildrun-pxg9w-pod     2/2     Running    0          58s
    oci-artifact-buildrun-pxg9w-pod     0/2     Completed  0          1m42s
  2. Check whether the respective TaskRun resource shows the SUCCEEDED field as True:

    $ oc get tr

    Example output:

    NAME                           SUCCEEDED  REASON     STARTTIME   COMPLETIONTIME
    oci-artifact-buildrun-pxg9w    True       Succeeded  2m10s       28s
  3. Check whether the respective BuildRun resource shows the SUCCEEDED field as True:

    $ oc get br

    Example output:

    NAME                     SUCCEEDED   REASON       STARTTIME     COMPLETIONTIME
    oci-artifact-buildrun    True        Succeeded    2m12s         30s
  4. During verification, if a build run fails, you can check the status.failureDetails field in your BuildRun resource to identify the exact point where the failure happened in the pod or container.

    Note

    The pod might switch to a NotReady state because one of the containers has completed its task. This is an expected behavior.

  5. Validate whether the image has been pushed to the registry that is specified in the build.spec.output.image field. Log in to the registry and run the following command to pull the image:

    $ podman manifest inspect image-registry.openshift-image-registry.svc:5000/oci-artifacts-example/taxi-app

    In the previous example, the project name is oci-artifacts-example, and the image name is taxi-app.

    Example output:

       "schemaVersion": 2,
        "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
        "manifests": [
            {
                "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
                "size": 594,
                "digest": "sha256:6a05100e302c86c03fec6277f4b3107f1fdde6c69d3ca9a4207e4735a5213e32",
                "platform": {
                    "architecture": "amd64",
                    "os": "linux"
                }
         ]
Red Hat logoGithubredditYoutubeTwitter

Learn

Try, buy, & sell

Communities

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.

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 Documentation

Legal Notice

Theme

© 2026 Red Hat
Back to top