Spring Boot on GCP
  • Introduction
  • Getting Started
    • Google Cloud Platform
    • Cloud Shell
    • gcloud CLI
    • Hello World!
      • Cloud Shell
      • App Engine
      • Cloud Run
      • Kubernetes Engine
      • Compute Engine
      • Cloud Functions
  • Application Development
    • Development Tools
    • Spring Cloud GCP
    • Cloud Services
      • Databases
        • Cloud SQL
        • Cloud Spanner
        • Cloud Firestore
          • Datastore Mode
          • Native Mode
      • Messaging
        • Cloud Pub/Sub
        • Kafka
      • Secret Management
      • Storage
      • Cache
        • Memorystore Redis
        • Memorystore Memcached (beta)
      • Other Services
    • Observability
      • Trace
      • Logging
      • Metrics
      • Profiling
      • Debugging
    • DevOps
      • Artifact Repository
  • Deployment
    • Runtime Environments
    • Container
      • Container Image
      • Secure Container Image
      • Container Awareness
      • Vulnerability Scanning
      • Attestation
    • Kubernetes
      • Kubernetes Cluster
      • Deployment
      • Resources
      • Service
      • Health Checks
      • Load Balancing
        • External Load Balancing
        • Internal Load Balancing
      • Scheduling
      • Workload Identity
      • Binary Authorization
    • Istio
      • Getting Started
      • Sidecar Proxy
  • Additional Resources
    • Code Labs
    • Presentations / Videos
    • Cheat Sheets
Powered by GitBook
On this page
  • Clone
  • Build
  • Enable API
  • Containerize
  • Build and Push
  • Build Locally
  • Run Locally
  • Connect Locally

Was this helpful?

  1. Deployment
  2. Container

Container Image

Build container images with tools and best practices.

PreviousContainerNextSecure Container Image

Last updated 4 years ago

Was this helpful?

Clone

git clone https://github.com/saturnism/jvm-helloworld-by-example
cd jvm-helloworld-by-example/helloworld-springboot-tomcat

Build

./mvnw package

Enable API

Enable Container Registry API to push your container images to the Container Registry.

gcloud services enable containerregistry.googleapis.com

Containerize

Typically, tutorials teach you how to write a Dockerfile to containerize a Java application. A Dockerfile can be error prone and it's hard to implement all the best practices. Rather than writing a Dockerfile, use tools such as Jib and Buildpacks to automatically create optimized container images.

Build and Push

Most tools can build and push directly into a container registry. In case of Jib, this step does not require a Docker daemon at all, and it can push changed layers directly into a remote registry. This is great for automated CI/CD pipelines.

can containerize any Java application easily, without a Dockerfile nor docker installed. Jib will push the container image directly to the remote registry.

PROJECT_ID=$(gcloud config get-value project)
./mvnw compile com.google.cloud.tools:jib-maven-plugin:2.4.0:build \
  -Dimage=gcr.io/${PROJECT_ID}/helloworld

You can configure or directly in the build file to run the Jib easier, such as ./mvnw jib:build.

can containerize applications written in different language without a Dockerfile. It does require docker installed.

  1. Install Docker locally - see .

  2. Install pack CLI - see

  3. Build container with pack, and use --publish flag to push directly to the remote registry:

# Paketo Buildpack
PROJECT_ID=$(gcloud config get-value project)
pack build \
  --builder gcr.io/paketo-buildpacks/builder:base \
  --publish \
  gcr.io/${PROJECT_ID}/helloworld

# GCP Buildpack
PROJECT_ID=$(gcloud config get-value project)
pack build \
  --builder gcr.io/buildpacks/builder:v1 \
  --publish \
  gcr.io/${PROJECT_ID}/helloworld

Learn about and .

Paketo Buildpack will calculate the minimum memory needed to run the Spring Boot application. For this Hello World example, the minimum is 1GB of RAM.

Cloud Build has built-in Buildpack support, so you can build the container image in the remote Cloud Build environment:

# GCP Buildpack
PROJECT_ID=$(gcloud config get-value project)
gcloud alpha builds submit \
  --pack image=gcr.io/${PROJECT_ID}/helloworld

# Paketo Buildpack
PROJECT_ID=$(gcloud config get-value project)
gcloud alpha builds submit \
  --pack image=gcr.io/${PROJECT_ID}/helloworld,builder=gcr.io/paketo-buildpacks/builder:base

Since Spring Boot 2.3+, you can build container using the Spring Boot plugin.

PROJECT_ID=$(gcloud config get-value project)

# Maven with Paketo Buildpack
./mvnw spring-boot:build-image \
  -Dspring-boot.build-image.imageName=gcr.io/${PROJECT_ID}/helloworld

# Maven with GCP Buildpack
./mvnw spring-boot:build-image \
  -Dspring-boot.build-image.imageName=gcr.io/${PROJECT_ID}/helloworld \
  -Dspring-boot.build-image.builder=gcr.io/buildpacks/builder

# Gradle with Paketo Buildpack
./gradlew bootBuildImage --imageName=gcr.io/${PROJECT_ID}/helloworld

# Gradle with GCP Buildpack
./gradlew bootBuildImage --imageName=gcr.io/${PROJECT_ID}/helloworld \
  --builder=gcr.io/buildpacks/builder

After the image is built, push the docker image to Container Registry:

docker push gcr.io/${PROJECT_ID}/helloworld

Paketo Buildpack will calculate the minimum memory needed to run the Spring Boot application. For this Hello World example, the minimum is 1GB of RAM.

Build Locally

If you are running a local Docker daemon and you do not want to push straight to a remote registry, then you can build container images without pushing:

PROJECT_ID=$(gcloud config get-value project)
./mvnw compile com.google.cloud.tools:jib-maven-plugin:2.4.0:dockerBuild \
  -Dimage=gcr.io/${PROJECT_ID}/helloworld
# Paketo Buildpack
PROJECT_ID=$(gcloud config get-value project)
pack build \
  --builder gcr.io/paketo-buildpacks/builder:base \
  gcr.io/${PROJECT_ID}/helloworld

# GCP Buildpack
PROJECT_ID=$(gcloud config get-value project)
pack build \
  --builder gcr.io/buildpacks/builder:v1 \
  gcr.io/${PROJECT_ID}/helloworld
PROJECT_ID=$(gcloud config get-value project)

# Maven with Paketo Buildpack
./mvnw spring-boot:build-image \
  -Dspring-boot.build-image.imageName=gcr.io/${PROJECT_ID}/helloworld

# Maven with GCP Buildpack
./mvnw spring-boot:build-image \
  -Dspring-boot.build-image.imageName=gcr.io/${PROJECT_ID}/helloworld \
  -Dspring-boot.build-image.builder=gcr.io/buildpacks/builder

# Gradle with Paketo Buildpack
./gradlew bootBuildImage --imageName=gcr.io/${PROJECT_ID}/helloworld

# Gradle with GCP Buildpack
./gradlew bootBuildImage --imageName=gcr.io/${PROJECT_ID}/helloworld \
  --builder=gcr.io/buildpacks/builder

Run Locally

If you have Docker installed locally, you can run the docker container locally to ensure everything works. This command will run the container locally and forward localhost's port 8080 to the container instance's port 8080.

PROJECT_ID=$(gcloud config get-value project)

docker pull gcr.io/${PROJECT_ID}/helloworld
docker run -ti --rm -p 8080:8080 gcr.io/${PROJECT_ID}/helloworld

The -ti flag means allocate a TTY, and expect interaction via STDIN. The --rm flag means delete the container completely upon exit.

Connect Locally

You can connect to the container that's running locally

curl localhost:8080

Learn about and .

Jib
Jib Maven plugin
Jib Gradle plugin
Cloud Native Buildpacks
Get Docker documentation
Installing pack documentation
Paketo Buildpack
GCP Buildpack
Paketo Buildpack
GCP Buildpack