Skip to main content

Build and push with non-root users

With a Kubernetes cluster build infrastructure, all Build and Push steps use kaniko. Other build infrastructures use drone-docker.

Kaniko requires root access to build the Docker image. It doesn't support non-root users. If your Kubernetes cluster build infrastructure is configured to run as non-root, you can either enable root access individual steps or use the Buildah plugin, which doesn't require root access.

Enable root access for a single step

If your build runs as non-root (runAsNonRoot: true), and you want to run the Build and Push step as root, you can set Run as User to 0 on the Build and Push step to use the root user for that individual step only.

If your security policy doesn't allow running as root for any step, you must use the Buildah plugin.

Use the Buildah plugin

If your security policy doesn't allow running as root for any step, you must use the Buildah plugin in a Plugin step to build and push your image.

To use the Buildah plugin, you must meet the following requirements:

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, for example:

                - step:
type: Plugin
name: buildah-docker
identifier: buildahdocker
connectorRef: account.harnessImage
image: plugins/buildah-docker:1.1.0-linux-amd64
privileged: false
repo: myDockerHub1234/test
tags: buildahtest
dockerfile: Dockerfile
username: <+secrets.getValue("DOCKER_HUB_USER")>
password: <+secrets.getValue("DOCKER_HUB_SECRET")>
runAsUser: "1000"

This step requires the following specifications:

  • connectorRef: Provide the ID of 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, the latest tag is used by default. Go to an image's Docker Hub page to browse available tags:
  • privileged: Set to false for OpenShift clusters. Set to true for non-OpenShift clusters.
  • runAsUser: 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 as The registry format for ECR is
    • 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 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.

DestinationBuildah imageBuildah main.goEquivalent Build and Push step
Docker Hubbuildah-dockerDocker main.goBuild and Push to Docker Registry
ACRbuildah-acrACR main.goBuild and Push to ACR
ECRbuildah-ecrECR main.goBuild and Push to ECR
GAR/GCRbuildah-grcGCR main.goBuild and Push to GAR/Build and Push to GCR

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.

    - stage:
identifier: stage1
type: CI
name: stage1
cloneCodebase: true
type: KubernetesDirect
automountServiceAccountToken: true
nodeSelector: {}
runAsNonRoot: true
runAsUser: "1000"
os: Linux
- step:
identifier: buildah plugin
type: Plugin
name: buildah_plugin
image: plugins/buildah-docker:1.1.0-linux-amd64
privileged: true
repo: myhub/test-repo
tags: builadhrootless
dockerfile: Dockerfile2
username: <+pipeline.variables.DOCKER_HUB_USER>
password: <+secrets.getValue("MyDockerPAT")>
runAsUser: "1000"

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.

  1. In your CI pipeline, go to the Build stage that includes the Plugin step with the Docker Buildah plugin.
  2. In the Build stage's Overview tab, expand the Advanced section.
  3. Select Add Variable and enter the following:
    • Name: PLUGIN_DRY_RUN
    • Type: String
    • Value: true
  4. Save and run the pipeline.