Making use of Docker build arguments

And how to use arguments in your Dockbit pipelines

Ahmed ElGamil
Dockbit

--

One of the great things about Docker builder is that it allows you to pass arguments that can be consumed in the context of the Dockerfile. The values of those arguments are only available during build-time, so they don’t reflect in the resulting Docker image.

Build-time arguments are defined in Dockerfile using the ARG instruction. There are other useful instructions that help with dynamicity of Dockerfiles, you can get a glimpse of some use cases here.

Arguments are especially helpful when it comes to designing CI/CD (Continuous Integration and Delivery) pipelines.

Let’s assume the following scenario: You are a building a Docker image that packages your Go app (a common pattern in the Docker/Go community). The commit to be deployed is tagged in Git as v0.1.0 along with a GitHub release.

To give an example, we are going to use hacher (A simple Go-based CLI tool for caching project artifacts), it should fit the bill. Now you can use build-time arguments as such:

Using Docker build arguments

This Dockerfile uses a build-time argument named RELEASE which has a default value of master. Arguments can be used as environment variables in subsequent RUN instructions. So for instance, if we set RELEASE to v0.1.0, the instructions will:

  1. Download version v0.1.0 from GitHub releases page of hacher and unpack.
  2. Compile the Go binary.
  3. Copy the resulting artifact to /hacher.

During the image build, we can supply the argument via the --build-arg flag:

Passing a Docker build-time argument

If you are using a recent version of the Docker daemon (17.06+), you can also use multi-stage builds for minimizing the size of the final image. Effectively, packaging only the Go binary without needing to bring the entire Go build environment for the ride. Here’s how to adjust the Dockerfile above to use multi-stage builds:

Using Docker build arguments and multi-stage builds

As you may notice, the difference is that on line 13, we’re using yet another FROM instruction to create a separate light-weight Docker image based on Alpine. This happens as a new stage, then simply we copy over the hacherbinary from the previous stage.

The last missing link would be to dynamically fill the value of which release to deploy as part of the deployment. This is possible by grabbing the value of the Git tag or commit SHA via CI/CD systems, so you can pass that directly into the Docker build command.

We recently added a Docker provider to the list of natively-supported integrations on the platform. Today, we’d like to take it one step further by adding support for Docker build-time arguments. This allows modeling setups like the one mentioned earlier.

For this stage, we are setting the value of the RELEASE build argument dynamically to a Dockbit built-in variable. Dockbit will automatically translateDOCKBIT_DEPLOYMENT_REF to v0.1.0. You can also use DOCKBIT_DEPLOYMENT_SHA for filling in the value of the git commit SHA.

Supplying multiple arguments is possible by using comma as a delimiter between the argument-value pairs.

All-in-all, such setup takes your Slack (a.k.a ChatOps) command you execute by typing/dockbit deploy hacher/v0.1.0 in Slack and turns it into a Docker image via a Dockbit continuous delivery pipeline. Later stages in the pipeline can be about deployment to container schedulers such as Kubernetes.

Stay tuned for more exciting news about all things Docker 🐳

Dockbit turns your complex software deployments into simple, manageable workflows. Sign up now to get your 2 pipelines for free, connect dozens of servicestogether, and kick-off deployments with a single Slack command. 🚀

--

--

Co-Founder & Chief Architect @dockbit, DevOps, DadOps, Uplifting delivery pipelines for software teams to ship better!