Skip to content

Files

multi-module

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
Mar 24, 2020
Jan 7, 2020
Nov 15, 2019
Jan 28, 2022
Nov 15, 2019
Sep 1, 2023
Mar 12, 2025
Aug 1, 2018
Jan 7, 2020
Jan 7, 2020
Aug 1, 2018
Nov 15, 2019
Aug 1, 2018
Oct 5, 2018
Mar 12, 2025
Nov 15, 2019

Multi-module example

This example shows how to build multiple containers for a multi-module project in both Maven and Gradle.

How the example is set up

The project consists of two microservices and a library:

  1. name-service - responds with a name
  2. shared-library - a project dependency used by name-service
  3. hello-service - calls name-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.

Reproducibility of dependency module shared-library

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.

How to run

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.

Where are the containers

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

How to run on Kubernetes

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'