This example shows how to build multiple containers for a multi-module project in both Maven and Gradle.
The project consists of two microservices and a library:
name-service- responds with a nameshared-library- a project dependency used byname-servicehello-service- callsname-serviceand responds with a greeting
The Maven project is set up with a parent POM (pom.xml) that defines most of the common build configuration. The module POMs (name-service/pom.xml and hello-service/pom.xml) just define inheritance on the parent POM. However, if needed, the module POMs can define custom configuration on jib-maven-plugin specific to that module.
The Gradle project is set up with a parent build.gradle that sets some common configuration up for all projects, with each sub-project containing its own build.gradle with some custom configuration. settings.gradle defines which modules to include in the overall build.
Since dependency module builds happen with the underlying build system
(maven/gradle), we must add some extra configuration to ensure that the
resulting jar that is built conforms to our reproducibility expectations.
The module shared-library uses the Reproducible Build Maven Plugin
for maven, and some special Jar properties (preserveFileTimestamps,
reproducibleFileOrder)
in gradle to achieve this. This configuration can be seen in the
shared-library's pom.xml and build.gradle.
Care must be taken when adding custom attributes to a MANIFEST.MF.
Attributes whose values change on every build can affect reproducibility even
with the modifications outlined aboved.
Set the PROJECT_ID environment variable to your own Google Cloud Platform project:
export PROJECT_ID=$(gcloud config list --format 'value(core.project)')Run the Maven build:
# build everything
./mvnw package jib:build
# build just hello-service
./mvnw compile jib:build -pl hello-service
# build name-service (with dependency on shared-library)
# you must use "package" for jib to correctly package "shared-library" with the
# "name-service" container
./mvnw package jib:build -pl name-service -amRun the Gradle build:
# build everything
./gradlew jib
# build just hello-service
./gradlew :hello-service:jib
# build name-service (with dependency on shared-library)
./gradlew :name-service:jibYou can also run ./maven-build.sh or ./gradle-build.sh as a shorthand.
The output of the build should have the container image references highlighted in cyan. You can expect them to be at:
name-service:gcr.io/PROJECT_ID/name-service:0.1.0hello-service:gcr.io/PROJECT_ID/hello-service:0.1.0
kubernetes.yaml defines the manifests for running the two microservices on Kubernetes. Make sure to open the file and change PROJECT_ID to your own Google Cloud Platform project.
Create a Kubernetes cluster:
gcloud container clusters create jibApply to your Kubernetes cluster:
kubectl apply -f kubernetes.yamlFind the EXTERNAL-IP of the hello-service.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc/hello-service LoadBalancer 10.19.243.223 35.237.89.148 80:30196/TCP 1m
Visit the IP in your web browser and you should see:
Hello Jib Multimodule: A string from 'shared-library'