Custom Docker Image
Build component for Docker images
Introduction
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
.
Usecases
Example
-
kind: CustomDockerImage
name: my-app-image
gitRepo: 'https://gitlab.com/example/my-app.git'
gitBranch: master
gitApplicationPath: /
runnerImage: openjdk:17-jdk-alpine
environment:
ENV: bunnyshell
build:
- 'echo "building $BNS_IMAGE_FULL_NAME ..."'
- './gradlew :jib --image="$BNS_IMAGE_FULL_NAME" -Djib.to.auth.username="$BNS_IMAGE_REGISTRY_USERNAME" -Djib.to.auth.password="$BNS_IMAGE_REGISTRY_PASSWORD" --debug'
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. TheSECRET[]
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 namegitRepo
: 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.
Note
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.
runnerImage
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
{{ components.my-runner-image.image }}
if you have in the same environment another DockerImage or CustomDockerImage component namedmy-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.
Note
Images stored in the Bunnyshell Managed Registry cannot be used cross Organizations.
runnerImageAuth
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>.amazonaws.com/my-image:my-tag
runnerImageAuth:
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
runnerImage: public.ecr.aws/123abc/my-image:my-tag
runnerImageAuth:
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
runnerImageAuth:
provider: azure
username: "Azure SP application ID / Token name"
password: "Azure SP password / Token secret"
Both username
and password
are required.
Docker Hub
runnerImageAuth:
provider: docker_hub
username: "DockerHub username"
password: "DockerHub password / Access Token"
Both username
and password
are required.
Google Container Registry
runnerImageAuth:
provider: gcp
password: "Google Service Account Key (JSON)"
Only password
is required.
GitHub Container Registry
runnerImageAuth:
provider: github
username: "GitHub Username / Organization"
password: "GitHub Access Token"
Both username
and password
are required.
GitLab Container Registry
runnerImageAuth:
provider: gitlab
username: "GitLab Username"
password: "GitLab Access Token"
Both username
and password
are required.
Harbor
runnerImageAuth:
provider: harbor
username: "Harbor Username / Robot Account name"
password: "Harbor Password / Robot Account password"
Both username
and password
are required.
JFrog Artifactory
runnerImageAuth:
provider: jfrog
username: "JFrog Artifactory Username"
password: "JFrog Artifactory API Key"
Both username
and password
are required.
environment
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.
Note
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 Application.dockerCompose.build.args
build
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):
BNS_IMAGE_REGISTRY=904643107945.dkr.ecr.eu-west-1.amazonaws.com
BNS_IMAGE_NAME=bns-abc123_1-1-765674709-e16cb4d98d554e20133d6b459a5cb6e6
BNS_IMAGE_TAG=d0c51431f847b8b4bd69f7b8249d86d28e5152e0
BNS_IMAGE_FULL_NAME=904643107945.dkr.ecr.eu-west-1.amazonaws.com/bns-abc123_1-1-765674709-e16cb4d98d554e20133d6b459a5cb6e6:d0c51431f847b8b4bd69f7b8249d86d28e5152e0
BNS_IMAGE_REGISTRY_USERNAME=AWS
BNS_IMAGE_REGISTRY_PASSWORD=abcd1234
so you can use them like:
build:
- '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 .'
build:
- './gradlew :jib --image="$BNS_IMAGE_FULL_NAME" -Djib.to.auth.username="$BNS_IMAGE_REGISTRY_USERNAME" -Djib.to.auth.password="$BNS_IMAGE_REGISTRY_PASSWORD"'
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.
Resources
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.
Updated 9 months ago