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
  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}} .
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
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
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

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 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}}
         

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 existing as an actual file in source control.

Automatic pushing

All images built successfully with the build step, will be automatically pushed to the internal Codefresh registry. This behavior is completely automatic and happens without any extra configuration on your part.

Notice that the push step in Codefresh is optional and is only needed for external Docker registries.

Docker Images pushed automatically

Docker Images pushed automatically

Buildkit support

Codefresh also allows you to use builkit with all its enhancements.

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

These capabilities are offered as extra arguments in the build step and using any of them will automatically enable buildkit.

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 can combine all options (ssh, progress, secrets) in a single build step if desired.