Build
Building Docker images in Codefresh pipelines
Use Docker to build an image and store it in Codefresh.
Purpose of build steps
In Codefresh, docker containers are first-class citizens
and special typed steps are offered for the most usual docker commands. Build steps are a secure replacement for docker build
commands.
Therefore, this command on your local workstation:
docker build . -t my-app-image:1.0.1
will become in Codefresh the following build step.
BuildMyImage:
title: Building My Docker image
type: build
image_name: my-app-image
tag: 1.0.1
Usage
YAML
step_name:
type: build
title: Step Title
description: Free text description
working_directory: ${{clone_step_name}}
dockerfile: path/to/Dockerfile
image_name: owner/new-image-name
tag: develop
build_arguments:
- key=value
target: stage1
no_cache: false
no_cf_cache: false
tag_policy: original
fail_fast: false
metadata:
set:
- qa: pending
when:
condition:
all:
noDetectedSkipCI: "includes('${{CF_COMMIT_MESSAGE}}', '[skip ci]') == false"
on_success:
...
on_fail:
...
on_finish:
...
retry:
...
Fields
Field | Description | Required/Optional/Default |
---|---|---|
title |
The free-text display name of the step. | Optional |
description |
A basic, free-text description of the step. | Optional |
stage |
Parent group of this step. See using stages for more information. | Optional |
working_directory |
The directory in which the build command is executed. It can be an explicit path in the container’s file system, or a variable that references another step. The default is ${{main_clone}} . This only changes the Docker build context and is unrelated to the WORKDIR inside the Dockerile |
Default |
dockerfile |
The path to the Dockerfile from which the image is built. The default is Dockerfile . |
Default |
image_name |
The name for the image you build. | Required |
region |
Relevant only for Amazon ECR integrations using either service accounts or explicit credentials. The names of the regions for which to perform cross-region replication. The names of the source region and the destination region name must be defined in separate steps. | Optional |
tag |
The tag that is assigned to the image you build. The default is the name of the branch or revision that is built. |
Default |
tags |
Multiple tags under which to push the image. Use either this or tag . This is an array, so should be of the following style:
|
Optional |
registry |
The registry logical name of one of the inserted registries from the integration view. The default value will be your default registry if you have more than one. |
Optional |
registry_contexts |
Advanced property for resolving Docker images when working with multiple registries with the same domain | Optional |
disable_push |
Do not push to any registry automatically. | Optional |
tag_policy |
Push the tag name without change or lowercase it automatically. By default tag: MixedCase will be pushed as image_name:mixedcase . Possible options are original and lowercase . Default is lowercase |
Default |
no_cache |
Disable Docker engine cache for the build more info | Optional |
no_cf_cache |
Disable Codefresh build optimization for the build more info | |
build_arguments |
A set of Docker build arguments to pass to the build process. | Optional |
target |
target stage in a multistage build (build will run until this stage) | Optional |
fail_fast |
If a step fails, and the process is halted. The default value is true . |
Default |
when |
Define a set of conditions that need to be satisfied in order to execute this step. You can find more information in the Conditional Execution of Steps article. |
Optional |
metadata |
Annotate the built image with key-value metadata. | Optional |
on_success , on_fail and on_finish |
Define operations to perform upon step completion using a set of predefined Post-Step Operations. | Optional |
retry |
Define retry behavior as described in Retrying a step. | Optional |
buildkit |
Set to true to enable Buildkit and all of its enhancements |
Optional |
Exported resources:
- Working Directory
- Image ID
Examples
Build an image using a Dockerfile in the root project folder:
codefresh.yml
version: '1.0'
steps:
BuildMyImage:
title: Building My Docker image
image_name: my-app-image
type: build
Build an image using a different Dockerfile and a specific version tag
codefresh.yml
version: '1.0'
steps:
BuildMyImage:
title: Building My Docker image
type: build
image_name: my-app-image
dockerfile: my-custom.Dockerfile
tag: 1.0.1
Build an image using a different Dockerfile and push multiple tags to the default registry.
codefresh.yml
version: '1.0'
steps:
BuildMyImage:
title: Building My Docker image
type: build
image_name: my-app-image
dockerfile: my-custom.Dockerfile
tags:
- latest
- ${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}
- v1.1
Build an image and automatically push to the registry with name my-registry
.
codefresh.yml
version: '1.0'
steps:
BuildMyImage:
title: Building My Docker image
type: build
image_name: my-app-image
dockerfile: my-custom.Dockerfile
tag: 1.0.1
registry: my-registry
Build two images in two different folders using Codefresh variables as tags.
codefresh.yml
version: '1.0'
steps:
BuildNodeImage:
title: Building My Node app
type: build
image_name: my-department/my-team/my-node-image
dockerfile: Dockerfile
working_directory: ./project1
tag: ${{CF_BRANCH_TAG_NORMALIZED}}-${{CF_SHORT_REVISION}}
BuildGoImage:
title: Building My Go app
type: build
image_name: my-company/my-go-image
dockerfile: Dockerfile
working_directory: ./project2
tag: ${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}
It also possible to build Docker images in parallel for faster builds.
Inline Dockerfile
If your project does not already have a Dockerfile, you can also define one within the pipeline:
codefresh.yml
version: '1.0'
steps:
BuildingDockerImage:
title: Building Docker Image
type: build
image_name: my-own-go-app
working_directory: ./
tag: '${{CF_BRANCH_TAG_NORMALIZED}}'
dockerfile:
content: |-
# ---
# Go Builder Image
FROM golang:1.8-alpine AS builder
# set build arguments: GitHub user and repository
ARG GH_USER
ARG GH_REPO
# Create and set working directory
RUN mkdir -p /go/src/github.com/$GH_USER/$GH_REPO
# copy file from builder image
COPY --from=builder /go/src/github.com/$GH_USER/$GH_REPO/dist/myapp
/usr/bin/myapp
CMD ["myapp", "--help"]
Use this technique only as a last resort. It is better if the Dockerfile exists as an actual file in source control.
Automatic pushing
All images built successfully with the build step, will be automatically pushed to the default Docker registry in your account. This behavior is completely automatic and happens without any extra configuration on your part. If you want to disable this then add the disable_push
property in your build step.
Notice that the push step in Codefresh is optional and is only needed if you want to push to external Docker registries.
Buildkit support
Codefresh also allows you to use buildkit with all its enhancements and experimental features.
Using buildkit you can get:
- Improved build output logs
- Mounting of external secrets that will never be stored in the image
- Access to SSH keys and sockets from within the Dockerfile
- Use cache and bind-mounts at build time
These capabilities are offered as extra arguments in the build step and using any of them will automatically enable buildkit. You can utilize the different mount-options for the Dockerfile instruction RUN
as long as buildkit is enabled for your build step. Mounts of type cache
work out of the box and are persisted between pipeline runs.
The simplest way to use buildkit is by enabling it explicitly:
codefresh.yml
version: '1.0'
steps:
BuildMyImage:
title: Building My Docker image
image_name: my-app-image
type: build
buildkit: true
Buildkit is also automatically enabled if you use any of its features such as the progress
property:
codefresh.yml
version: '1.0'
steps:
BuildMyImage:
title: Building My Docker image
image_name: my-app-image
type: build
progress: tty
Possible values for progress
are tty
and plain
.
For secrets you can either mention them in a single line:
codefresh.yml
version: '1.0'
steps:
BuildMyImage:
title: Building My Docker image
image_name: my-app-image
type: build
secrets:
- id=secret1,src=./my-secret-file1.txt
- id=secret2,src=./my-secret-file2.txt
or multiple lines:
codefresh.yml
version: '1.0'
steps:
BuildMyImage:
title: Building My Docker image
image_name: my-app-image
type: build
secrets:
- id: secret1
src: ./my-secret-file1.txt
- id: secret2
src: ./my-secret-file2.txt
For the SSH connection you can either use the default:
codefresh.yml
version: '1.0'
steps:
BuildMyImage:
title: Building My Docker image
image_name: my-app-image
type: build
ssh: default
or define different keys:
codefresh.yml
version: '1.0'
steps:
BuildMyImage:
title: Building My Docker image
image_name: my-app-image
type: build
ssh:
- github=~/.ssh/github_rsa
- bitbucket=~/.ssh/bitbucket_rsa
You might want to use an environment variable to store and retrieve a ssh key. This can be achieved by converting you ssh key into a one-line string:
tr '\n' ',' < /path/to/id_rsa
Copy the output and place it an environment variable. To make the SSH key availabe to the build step, you can write it to the codefresh volume:
codefresh.yml
version: '1.0'
steps:
SetupSshKeys:
title: Setting up ssh key
image: alpine:latest
commands:
- mkdir /codefresh/volume/keys
- echo "${SSH_KEY}" | tr ',' '\n' > /codefresh/volume/keys/github_rsa
BuildMyImage:
title: Building My Docker image
image_name: my-app-image
type: build
tag: latest
ssh:
- github=/codefresh/volume/keys/github_rsa
You can combine all options (ssh
, progress
, secrets
) in a single build step if desired.