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-service
hello-service
- callsname-service
and 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 above.
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 -am
Run 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:jib
You 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.0
hello-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 jib
Apply to your Kubernetes cluster:
kubectl apply -f kubernetes.yaml
Find 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'