Introduction
In today’s fast-paced development landscape, deploying applications in a scalable and efficient manner is crucial. Google Kubernetes Engine (GKE) offers a robust platform for deploying and managing containerized applications in the Google Cloud environment. In this blog, we will explore the process of deploying a Java application to GKE using GitHub Actions. We’ll walk through the code snippets and configuration files involved in setting up a deployment pipeline, building a Docker image, and deploying the application to a GKE cluster. So, let’s dive in and learn how to deploy your Java application to GKE.
The following technologies are used for this demo: Java 19, Docker, Kubernetes, Spring Boot
Prerequisites for deploying your app to GKE
To follow this we need the following prerequisites:
- kubectl (Kubernetes CLI to manage a cluster)
- gcloud (Google Cloud SDK)
- A Google Cloud Account (free $ 300 trial)
Once you have installed the necessary CLI tools and set up your Google Cloud account, you can proceed to create a new project in the Google Cloud console. Creating a project allows you to organize and manage your various services and applications within a unified framework.

Google will automatically assign a unique ID for your project, which we’ll need later on for pushing the Docker image to GitHub Artifact Registry.
Next, you’ll need to create your initial Kubernetes cluster. You can use either the web console for this or the gcloud
CLI. To create the cluster in your browser, open the left-side menu and navigate to Kubernetes Engine -> Clusters.

For simplicity, you can choose the Standard cluster template from Google to configure your Kubernetes cluster. In addition, you can rename the cluster, select a specific region and the Kubernetes version. You can leave the other configuration options as they are pre-configured, which are suitable for a first demonstration.
Configure the Spring Boot application for a Kubernetes deployment
The sample Spring Boot application contains one REST endpoint to send a message:
@RestController
public class Controller {
@GetMapping("/hello")
public String hello_page() {
return "hello nashtech!!!";
}
}
That’s everything required from the code perspective. As we’ll use Docker as the container engine, we need to create a Docker image containing the application. For this, I’ve used a straightforward Java 19 Dockerfile
:
FROM openjdk:19-jdk
WORKDIR /app
COPY target/demo2-0.0.1-SNAPSHOT.jar app.jar
CMD ["java", "-jar", "app.jar"]
The actual Kubernetes Deployment object is defined in a .yaml
file and contains the following configuration:
gcp_cicd_pipeline.yaml
name: Deploy to GKE
on:
push:
branches:
- main
env:
IMAGE_NAME: ghcr.io/deepak1067/myapp/myimage:latest
PROJECT_ID: ${{ secrets.PROJECT_ID }}
GKE_CLUSTER: deployment-cluster-sdk
GKE_ZONE: asia-southeast1-a
jobs:
setup-build-deploy:
name: Setup, Build, and Deploy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 19
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: 19
- run: mvn clean install --batch-mode --errors --fail-at-end
- name: Upload Artifacts
uses: actions/upload-artifact@v2
with:
name: demo2-0.0.1-SNAPSHOT.jar
path: target/
build-docker-image:
name: build-docker
needs: setup-build-deploy
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v2
- name: Retrieve saved jar
uses: actions/download-artifact@v2
with:
name: demo2-0.0.1-SNAPSHOT.jar
path: target/
- name: Set up Docker Build
uses: docker/setup-buildx-action@v1
- name: Build and push Docker image
env:
USERNAME: ${{ secrets.GITHUB_USERNAME }}
PASSWORD: ${{ secrets.GITHUB_PASSWORD }}
run: |
echo $GITHUB_PASSWORD | docker login ghcr.io -u $GITHUB_USERNAME --password-stdin
docker build --tag $IMAGE_NAME .
docker push $IMAGE_NAME
deploy-to-gke:
needs: build-docker-image
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: kubectl - Google Cloud GKE cluster.
uses: ameydev/gke-kubectl-action@master
env:
PROJECT_ID: ${{ secrets.PROJECT_ID }}
APPLICATION_CREDENTIALS: ${{ secrets.GCLOUD_AUTH }}
CLUSTER_NAME: ${{ secrets.CLUSTER_NAME }}
ZONE_NAME: asia-southeast1-a
with:
args: apply -f k8s/
Here is the deploy.yaml config in the k8s directory for creating the container.
apiVersion: apps/v1
kind: Deployment
metadata:
name: demoapp
spec:
replicas: 1
selector:
matchLabels:
app: demoapp
template:
metadata:
labels:
app: demoapp
spec:
containers:
- name: demoapp
image: ghcr.io/deepak1067/myapp/myimage:latest
ports:
- containerPort: 8080
imagePullSecrets:
- name: dockerconfigjson-github-com
here is the service.yaml config to expose the service to the target port.
apiVersion: v1
kind: Service
metadata:
name: demoapp-service
spec:
selector:
app: demoapp
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer
Deploy the application to GKE
After committing the changes to the main branch the jobs will start to run the deployment in Github Action.

Afterward, you can check if the pods (instances) are up and running:

When querying for all available services, you will receive the public IP address. Please note that assigning the IP address may require a short delay.

For this example, the application is now available at http://34.87.120.208/hello
and returns the following output:

Conclusion
Deploying a Java application to Google Kubernetes Engine (GKE) can be made easier and automated using GitHub Actions. By following the steps outlined in this blog, you can set up a deployment pipeline, build Docker images, and deploy your Java application to a GKE cluster with ease. Leveraging the power of containerization and orchestration, you can ensure scalability, reliability, and efficient management of your application in a cloud-native environment. So, get started with GKE and streamline your deployment process today!
You can find the whole codebase on my GitHub.