How to Build and push with non-root users
Use the buildah plugin if you can't use the built-in Build and Push steps.
Introduction
Building with non-root users may be necessary for an organization due to security or compliance requirements. This page describes how to build and push Docker images as a non-root user, and outlines Harness options and best practices for Kubernetes-based builds.
Kaniko Builds
By default, Harness uses Kaniko to build and push images in Kubernetes cluster build infrastructure.
Kaniko does not require privileged mode (
privileged: false).Kaniko can run as non-root in many cases. Root access is only required when your Dockerfile performs privileged operations.
Security recommendation: Run Kaniko in root mode only when your Dockerfile requires privileged operations.
If your Dockerfile requires privileged operations and your policy prohibits root: Use the Buildah plugin described below.
Kaniko is recommended for most security-conscious teams as it minimizes risk by not requiring privileged pods.
BuildX Builds
You may also use BuildX by enabling the CI_USE_BUILDX_ON_K8 flag via Harness Support.
BuildX requires both root user and privileged mode in Kubernetes.
This tool provides the richest feature set, but is the least restrictive in terms of privileges, and is not recommended where least-privilege is a hard requirement.
Drone Docker
You can also use drone-docker for image builds as a plugin step.
This method is generally used for backwards compatibility or in specific CI workflows.
Privilege and user requirements will be similar to Docker/BuildX (privileged and root).
Individual Step Root / Buildah Plugin
If your Kubernetes cluster build infrastructure is configured to run as non-root (runAsNonRoot: true and runAsUser: 1000), you have two options for building images:
Enable root access for individual steps (if allowed by policy): If your build infrastructure is set up for non-root execution (
runAsNonRoot: true), but your security policy allows Build and Push to run as root, set Run as User to0for that step only. This enables only that step to run as root.If your security policy forbids root user entirely for all steps, use the Buildah plugin running as a non-root user, with privileged mode enabled.
Use the Buildah plugin: If your policy does not allow root for any step, use the Buildah plugin in a Plugin step, and specify a non-root UID (
runAsUser: 1000). Buildah can run as a non-root user (e.g., UID 1000). However, it still requires privileged mode in Kubernetes (except for some OpenShift SCC scenarios). This is due to kernel-level operations required by Buildah, even in rootless mode.To use the Buildah plugin, your pipeline must meet these requirements:
CI pipeline with a Build stage
For OpenShift Buildah users:
anyuidSCC is required. OpenShift SCC documentation
Add a Plugin step
At the point in your pipeline where you want to build and upload an image, add a Plugin step that uses the buildah plugin.
Name: Enter a name.
Container Registry: Select a connector corresponding to your push destination.
Docker Hub: Docker connector
ACR: Azure connector
ECR: AWS connector
GAR/GCR: GCP connector
Image: Specify the plugin image and tag to use, such as
plugins/buildah-docker:1.1.0-linux-amd64. If you don't specify a tag, thelatesttag is used by default. Go to an image's Docker Hub page to browse available tags:ACR: buildah-acr
ECR: buildah-ecr
GAR/GCR: buildah-gcr
Docker Hub: buildah-docker
Privileged: Set to
falsefor OpenShift clusters;truefor standard Kubernetes.Run as User: Specify the ID of the non-root user to use for this step, such as
1000.Settings: Add the following settings as key-value pairs.
repo: The name of the repository where you want to store the image, for example,<hub-user>/<repo-name>. For private registries, specify a fully qualified repo name.tags: Specify tags for your image.registry: Specify the registry index, such ashttps://index.docker.io/v2/. The registry format for ECR isaws_account_id.dkr.ecr.region.amazonaws.com.dockerfile: Specify the Dockerfile to use for the build.username: Provide the username to access the push destination, either as plaintext or an expression referencing a Harness secret or pipeline variable, such as<+pipeline.variables.DOCKER_HUB_USER>.password: An expression referencing a Harness secret or pipeline variable containing the password to access the push destination, such as<+pipeline.variables.DOCKER_HUB_SECRET>.For more information and additional settings, including AWS S3 settings, go to Buildah plugin settings.
At the point in your pipeline where you want to build and upload an image, add a Plugin step that uses the buildah plugin, for example:
This step requires the following specifications:
connectorRef: Provide the ID of a Docker connector.image: Specify the plugin image and tag to use, such asplugins/buildah-docker:1.1.0-linux-amd64. If you don't specify a tag, thelatesttag is used by default. Go to an image's Docker Hub page to browse available tags:ACR: buildah-acr
ECR: buildah-ecr
GAR/GCR: buildah-gcr
Docker Hub: buildah-docker
privileged: Set tofalsefor OpenShift clusters. Set totruefor non-OpenShift clusters.runAsUser: Specify the ID of the non-root user to use for this step, such as1000.settings: Add the following settings as key-value pairs.repo: The name of the repository where you want to store the image, for example,<hub-user>/<repo-name>. For private registries, specify a fully qualified repo name.tags: Specify tags for your image.registry: Specify the registry index, such ashttps://index.docker.io/v2/. The registry format for ECR isaws_account_id.dkr.ecr.region.amazonaws.com.dockerfile: Specify the Dockerfile to use for the build.username: Provide the username to access the push destination, either as plaintext or an expression referencing a Harness secret or pipeline variable, such as<+pipeline.variables.DOCKER_HUB_USER>.password: An expression referencing a Harness secret or pipeline variable containing the password to access the push destination, such as<+pipeline.variables.DOCKER_HUB_SECRET>.For more information and additional settings, including AWS S3 settings, go to Buildah plugin settings.
Buildah plugin settings
For information about Buildah plugin settings, go to the Buildah README, the Buildah Drone Plugins Marketplace page, and the main.go file for each destination:
Many Buildah plugin settings correspond with settings for the built-in Build and Push steps. If you're encountering an error with the buildah plugin configuration, you can reference the settings definitions for the built-in steps for guidance on the expected value for the equivalent Buildah settings. However, keep in mind that the configuration for Build and Push steps (such as field names and location in the YAML) is not an exact match to the Plugin step configuration.
Stage YAML example
This YAML example shows a Build (CI) stage with a Kubernetes cluster build infrastructure running as non-root (runAsNonRoot: true and runAsUser: "1000") and a Plugin step running the Buildah plugin.
Build an image without pushing
You can use your CI pipeline to test a Dockerfile used in your codebase and verify that the resulting image is correct before you push it to your Docker repository.
The following configuration is valid with the Docker Buildah plugin (plugins/buildah-docker) only. For other configurations, go to Build without pushing.
In your CI pipeline, go to the Build stage that includes the Plugin step with the Docker Buildah plugin.
In the Build stage's Overview tab, expand the Advanced section.
Select Add Variable and enter the following:
Name:
PLUGIN_DRY_RUNType: String
Value:
true
Save and run the pipeline.
Last updated
Was this helpful?