Custom Docker Image

Build component for Docker images


Custom Docker Image Components are useful when you don't have your images already built (by a pipeline) and also they require a custom setup, more than DockerImage component can offer. Defining such a component will enable Bunnyshell to build your images for you to use in other components.

This is a combination between GenericComponent and DockerImage, you can declare any build steps, what is important in the end, the image $BNS_IMAGE_FULL_NAME should exists in the registry.

Custom Docker Image components are not displayed in the main user interface. They can be defined and edited only within the bunnyshell.yaml file, where they have their own kind, named CustomDockerImage.



    kind: CustomDockerImage
    name: my-app-image
    gitRepo: ''
    gitBranch: master
    gitApplicationPath: /
    runnerImage: openjdk:17-jdk-alpine
        ENV: bunnyshell
        - 'echo "building $BNS_IMAGE_FULL_NAME ..."'

Component attributes

CustomDockerImage Components have the following attributes:

  • runnerImage: the Docker image in which the build commands will run. This field is mandatory.
  • runnerImageAuth: credentials for pulling the runnerImage. See below examples foreach supported image registry.
  • environment: a key-value map of component-level variables. The SECRET[] method can be used to mark a secret value (e.g. - VAR_NAME: SECRET['secret value']).
  • build: a list of commands that will be ran in order to build the Docker image. This field is mandatory.
  • name: the name
  • gitRepo: the URL of the Git repository where the Dockerfile is located. This field is mandatory.
  • gitBranch: the branch where the Dockerfile is located. This attribute is relative to the gitRepo. This field is mandatory.
  • gitApplicationPath: the path to the application folder, relative to the branch. This field is mandatory.



If the gitRepo, gitBranch or gitApplicationPath are not provided, Bunnyshell will return an error when trying to validate your environment.

Bunnyshell must have access to the git repository through an existing Git integration (i.e. a Git account that was already connected to Bunnyshell). See the Git Providers page for more information.

The repository will be cloned entirely, not just the specified gitApplicationPath.



The image must be specified in it's full form <registry>/<repository>:<tag> except it's an image hosted on dockerhub and then it can have only <repository>:<tag>. If the tag is not present the latest tag will be assumed.

If the image you want to use is built by Bunnyshell, you have two possibilities to obtain the image full name:

  • use interpolation {{ }} if you have in the same environment another DockerImage or CustomDockerImage component named my-runner-image, which should build before this component
  • copy the image full name from previous pipeline logs if the DockerImage or CustomDockerImage that built the image is part of another environment. Go to pipeline logs, click on a Build job, then in the logs box below, check for either:
    • "create builder pod" > "pushing into: registry "<REGISTRY>" repository "<REPOSITORY>" tag "<TAG>""
    • "check image already built" > "image found <REGISTRY>/<NAME>:<TAG>"

If the runnerImage is not public and the image registry where it's stored is not yet connected to Bunnyshell (see Image Registries) you must provide runnerImageAuth object with the credentials to pull the image.



Images stored in the Bunnyshell Managed Registry cannot be used cross Organizations.


If the runnerImage is not public and the image registry is not connected to Bunnyshell (see Image Registries) you must provide the pull credentials.

Both username and password allow interpolation expression, so you can interpolate environmentVariables or even Project variables.

See below explanations and examples for each supported image registry type.

AWS private ECR

runnerImage: <AWSAccountID>.dkr.ecr.<AWSRegion>
  provider: aws
  username: "AWS Access Key ID"
  password: "AWS Secret Access Key"

Both username and password are required, and we will extract AWS Account ID and AWS Region from the runnerImage.

AWS public ECR

  provider: aws_public
  username: "AWS Access Key ID"
  password: "AWS Secret Access Key"

Sometimes is useful to provide credentials even for AWS public ECR to bypass any pull rate limit.

Both username and password are required.

Azure Container Registry

  provider: azure
  username: "Azure SP application ID / Token name"
  password: "Azure SP password / Token secret"

Both username and password are required.

Docker Hub

  provider: docker_hub
  username: "DockerHub username"
  password: "DockerHub password / Access Token"

Both username and password are required.

Google Container Registry

  provider: gcp
  password: "Google Service Account Key (JSON)"

Only password is required.

GitHub Container Registry

  provider: github
  username: "GitHub Username / Organization"
  password: "GitHub Access Token"

Both username and password are required.

GitLab Container Registry

  provider: gitlab
  username: "GitLab Username"
  password: "GitLab Access Token"

Both username and password are required.


  provider: harbor
  username: "Harbor Username / Robot Account name"
  password: "Harbor Password / Robot Account password"

Both username and password are required.

JFrog Artifactory

  provider: jfrog
  username: "JFrog Artifactory Username"
  password: "JFrog Artifactory API Key"

Both username and password are required.


Key value map with component level environment variables. They will be injected in the build scripts context. They allow interpolation expressions just like all the other environment variables in bunnyshell.yaml.



One thing different from GenericComponent (or Helm, Kubernets and Terraform) which have environment too, the environment variables injected in the build context consists only from the variables defined at component level, no environmentVariable or Project variable will be injected. They are treated more like “some build arguments”, so that’s why we keep it sandboxed, like we have on DockerImage.args, StaticApplication.buildArguments and


Build scripts will run on a Pod with runnerImage in the root folder of the specified gitRepository. The cluster where the Pod runs, the k8s resources and the maximum allowed time for the scripts to run are configured in Build Settings.

The goal of the build scripts is to push the $BNS_IMAGE_FULL_NAME in the registry. If at the end the image is not there the build job will be considered failed.

To know where to push the image and what are the push credentials Bunnyshell automatically injects the following environment variables (with example values):

so you can use them like:

  - 'echo "$BNS_IMAGE_REGISTRY_PASSWORD" | docker login --username "$BNS_IMAGE_REGISTRY_USERNAME" --password-stdin $BNS_IMAGE_REGISTRY'
  - 'docker buildx build -t $BNS_IMAGE_FULL_NAME --push .'

Value Interpolation

The built images can be used in other components using the following interpolations:

  • {{ components.NAME.image }}: contains full image name, including the tag.
    Example: nginx:latest
  • {{ components.dev_test_image.imageName }}: contains only the image name.
    Example: nginx
  • {{ components.dev_test_image.imageTag }}: contains only the image tag.
    Example: latest

The runnerImage, runnerImageAuth, environment and build allows interpolation expressions.



The CustomDockerImage component does not produce any deployed runnable resources, just the container images.

Still, the Pod itself that will build the image, will run in the cluster and with the k8s resources specified in the Build Settings.