Recently we started using CircleCI as our build tool and we needed to integrate it with our Google Cloud platform and specifically Google Container Registry.
Jib builds optimized Docker and OCI images for your Java applications without a Docker daemon — and without deep mastery of Docker best-practices.
Jib lets you build and publish Docker images without having to write a Dockerfile and as we will see, without access to a Docker daemon. This is great when it comes to building Docker images from Java applications since it let’s you reuse already existing dependencies from your local .m2 repository.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.4.RELEASE</version> <relativePath/> </parent> <groupId>se.predictly.build</groupId> <artifactId>build-app</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <java.version>11</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>com.google.cloud.tools</groupId> <artifactId>jib-maven-plugin</artifactId> <version>2.5.2</version> </plugin> </plugins> </build> </project>
With this in place, we can start building our Docker images by running
mvn test jib:build -Dimage=gcr.io/predictly-demo/build-app:latest
Of course, it is a bit more elaborate in our pipelines but this works for descriptive purposes.
Authenticating with Google Container Registry
This proved to be the most cumbersome task since we want to keep build times as low as possible. Locally, this was easily resolved since Jib understands and integrates with Minikube using Skaffold which we use for local development.
CircleCI Orbs
On CircleCI, the best way to keep build times down is to reuse the official orbs and executors since these Docker images are very likely to be cached on what ever server your build ends up on. This lead us to use the maven orb published by CircleCI, a build image with Java and maven installed.
Jib automatically uses docker-credential-gcr for authentication if available. Of course, this isn’t the case in the CircleCI maven orb. To resolve this, we have to install and initialize the Google Cloud CLI and authenticate towards GCR during the build. Luckily, CircleCI has also provided the gcp-gcr orb with the commands required to perform these tasks.
GCP IAM Service Account
There are a few different ways to authenticate against GCP using docker-credential-gcr and the preferred way is to use gcloud as a credential helper. We setup a GCP IAM service account and gave it the Storage Admin role which is required to push images to GCR.
We also created a key in JSON format for this service account.
CircleCI Context
With the service account and a corresponding key created, we turned to configuring a context in CircleCI. We created the following environment variables in a context named predictly-demo
GOOGLE_PROJECT_ID — name of our GCP project, predictly-demo
GOOGLE_COMPUTE_ZONE — our preferred zone, europe-north1-a
GCLOUD_SERVICE_KEY — service account key (you can just paste it in as is)
These three environment variables will contain the necessary information to configure and authenticate using docker-credential-gcr in our build.
Build configuration
Our final CircleCI configuration uses the gcp-gcr orb and the gcr-auth command from CircleCI to make sure that the necessary tools, configuration and authentication is done without us having to worry about it.
version: 2.1 orbs: maven: circleci/maven@1.0.2 gcp-gcr: circleci/gcp-gcr@0.8.0 jobs: jib-build-deploy: executor: maven/default steps: - gcp-gcr/gcr-auth - checkout - maven/with_cache: steps: - run: command: 'mvn test jib:build -Dimage=gcr.io/predictly-demo/${CIRCLE_PROJECT_REPONAME}' - maven/process_test_results: test_results_path: target/surefire-reports workflows: feature_branch: jobs: - maven/test: filters: branches: ignore: - master master: jobs: - jib-build-deploy: context: predictly-demo filters: branches: only: - master
Using this configuration, we install and initialize the GCloud CLI every time but this is very fast so we decided to keep it like this.
With this configuration, we reduced our build time from 2–4 minutes to below 1 minute. A huge improvement when it comes to reducing waste in developer productivity.
Fler insikter och blogginlägg
När vi stöter på intressanta tekniska saker på våra äventyr så brukar vi skriva om dom. Sharing is caring!
A summary of the most interesting AI Use Cases we have implemented.
Composable commerce skapar förmågan att möta kunders ändrade förväntningar snabbt och framgångsrikt.
Data Mesh is a strategy for scaling up your reporting and analysis capabilities. Learn more about the Google Cloud building blocks that enable your Data Mesh.