In this guide we are going to show how to build and publish container images using
the oci-build task
and registry-image resource. This guide assumes you understand
how to build container images with Dockerfile's and publish
to Docker Hub or another image registry using the docker cli.
Note
This is one way of building and pushing images. There are many other ways to accomplish this same task in Concourse.
First we need a Dockerfile. You can store this in your own repo or reference
the github.com/concourse/examples repo. The rest of this post assumes you use
the examples repo. All files in this blog post can be found in the examples repo.
Alien #1: A stranger.
Alien #2: From the outside.
Aliens: Oooooooooooooooh.
Defining Pipeline Resources
Now we can start building out our pipeline. Let's declare our Resources first. We will need
one resource to pull in the repo where our Dockerfile is located, and a second resource pointing to where we want to
push the built container image to.
There are some Variables in this file that we will fill out when setting
the pipeline.
---resources:# The repo with our Dockerfile-name:concourse-examplestype:giticon:githubsource:uri:https://github.com/concourse/examples.gitbranch:main# Where we will push the image-name:simple-imagetype:registry-imageicon:dockersource:# You need to provide these variables when# setting the pipelinerepository:((image-repo-name))/simple-imageusername:((registry-username))password:((registry-password))
Create the Job
Next we will create a job that will build and push our container image.
To build the job we will need to pull in the repo where the Dockerfile is.
resources:...# omitting resource section from abovejobs:-name:build-and-pushplan:-get:concourse-examples
Build the Image
The second step in our job will build the container image.
To build the container image we are going to use the oci-build-task. The
oci-build-task is a container image that is meant to be used in a Concourse task to build other
container images. Check out the README.md in the
repo for more details on how to configure and use the oci-build-task in more complex build scenarios.
resources:...# omitting resource section from abovejobs:-name:build-and-pushplan:-get:concourse-examples-task:build-task-imageprivileged:trueconfig:platform:linuximage_resource:type:registry-imagesource:# Check out the README for oci-build-task at# https://github.com/concourse/oci-build-taskrepository:concourse/oci-build-task
Next we will add concourse-examples as an input to the build task to ensure the artifact from the get step (where our Dockerfile is fetched) is mounted in our build-image step.
resources:...# omitting resource section from abovejobs:-name:build-and-pushplan:-get:concourse-examples-task:build-task-imageprivileged:trueconfig:platform:linuximage_resource:type:registry-imagesource:# Check out the README for oci-build-task at# https://github.com/concourse/oci-build-taskrepository:concourse/oci-build-taskinputs:-name:concourse-examples
The oci-build-task outputs the built container image in a
directory called image. Let's add image as an output of our task so we can publish it in a later step.
resources:...# omitting resource section from abovejobs:-name:build-and-pushplan:-get:concourse-examples-task:build-task-imageprivileged:trueconfig:platform:linuximage_resource:type:registry-imagesource:# Check out the README for oci-build-task at# https://github.com/concourse/oci-build-taskrepository:concourse/oci-build-taskinputs:-name:concourse-examplesoutputs:-name:image
Defining the Build Context
Next we need to tell the oci-build-task what
the build context of our Dockerfile is.
The README goes over a few other methods of creating your build context.
We are going to use the simplest use-case. By specifying CONTEXT the oci-build-task assumes a Dockerfile and its
build context are in the same directory.
resources:...# omitting resource section from abovejobs:-name:build-and-pushplan:-get:concourse-examples-task:build-task-imageprivileged:trueconfig:platform:linuximage_resource:type:registry-imagesource:# Check out the README for oci-build-task at# https://github.com/concourse/oci-build-taskrepository:concourse/oci-build-taskinputs:-name:concourse-examplesoutputs:-name:imageparams:CONTEXT:concourse-examples/Dockerfiles/simpleUNPACK_ROOTFS:"true"# only needed if using image in a future steprun:path:build
Publish the Container Image
To push the container image add a put step to our job plan and tell the registry-image resource
where the tarball of the container image is.
The put step will push the container image using the information defined previously in the
resource's source.
resources:...# omitting resource section from abovejobs:-name:build-and-pushplan:-get:concourse-examples-task:build-task-imageprivileged:trueconfig:platform:linuximage_resource:type:registry-imagesource:# Check out the README for oci-build-task at# https://github.com/concourse/oci-build-taskrepository:concourse/oci-build-taskinputs:-name:concourse-examplesoutputs:-name:imageparams:CONTEXT:concourse-examples/Dockerfiles/simpleUNPACK_ROOTFS:"true"# only needed if using image in a future steprun:path:build-put:simple-imageparams:image:image/image.tar
The Entire Pipeline
Putting all the pieces together, here is our pipeline that builds and pushes a container image.
---resources:# The repo with our Dockerfile-name:concourse-examplestype:giticon:githubsource:uri:https://github.com/concourse/examples.gitbranch:main# Where we will push the image-name:simple-imagetype:registry-imageicon:dockersource:# You need to provide these variables when# setting the pipelinerepository:((image-repo-name))/simple-imageusername:((registry-username))password:((registry-password))jobs:-name:build-and-pushplan:-get:concourse-examples-task:build-task-imageprivileged:trueconfig:platform:linuximage_resource:type:registry-imagesource:# Check out the README for oci-build-task at# https://github.com/concourse/oci-build-taskrepository:concourse/oci-build-taskinputs:-name:concourse-examplesoutputs:-name:imageparams:CONTEXT:concourse-examples/Dockerfiles/simpleUNPACK_ROOTFS:"true"# only needed if using image in a future steprun:path:build-put:simple-imageparams:image:image/image.tar
You can set the pipeline with the following fly command, updating the variable values with real values the pipeline can
use to run.
Understanding what the build context is important when building container images. You can
read Dockerfile Best Practices
for more details about build contexts.
The inputs section of the oci-build-task's README has examples
on how to create a build context with multiple inputs and other complex build scenarios.