This lab-based tutorial walks you through deploying a simple Node.js app on Google Kubernetes Engine (GKE). You’ll containerize your app with Docker, push it to Artifact Registry, deploy it to a Kubernetes cluster, expose it to the internet, scale it, and finally upgrade it — all with hands-on commands and clear explanations.
By the end of this guide, you’ll be comfortable:
- Writing and containerizing a Node.js app
- Creating a GKE cluster
- Deploying and scaling applications
- Rolling out updates in Kubernetes
Prerequisites
- Basic terminal experience
- A Google Cloud project with billing enabled
- gcloud CLI and Docker installed
- Familiarity with kubectl and Cloud Shell
Task 1: Create a Simple Node.js App
Let’s begin by writing a basic HTTP server in Node.js:
vim server.js
Paste this into the file:
var http = require('http');
var handleRequest = function(request, response) {
response.writeHead(200);
response.end("Hello World!");
}
var www = http.createServer(handleRequest);
www.listen(8080);
Save and exit (ESC, then :wq).
You can test it locally using:
node server.js
Preview it via port 8080 in Cloud Shell. Don’t forget to stop it after testing (CTRL+C).
Task 2: Build a Docker Image
Create a Dockerfile:
cat > Dockerfile <<EOF
FROM node:18
EXPOSE 8080
COPY server.js .
CMD ["node", "server.js"]
EOF
Build and tag the image:
docker build -t hello-node:v1 .
Test it locally:
docker run -d -p 8080:8080 hello-node:v1
curl http://localhost:8080
Stop the container:
docker ps
docker stop <CONTAINER_ID>
Push to Artifact Registry:
gcloud artifacts repositories create my-docker-repo \
--repository-format=docker \
--location=europe-west1
gcloud auth configure-docker
docker tag hello-node:v1 europe-west1-docker.pkg.dev/YOUR_PROJECT_ID/my-docker-repo/hello-node:v1
docker push europe-west1-docker.pkg.dev/YOUR_PROJECT_ID/my-docker-repo/hello-node:v1
Task 3: Create a GKE Cluster
gcloud container clusters create hello-world \
--num-nodes=2 \
--machine-type=e2-medium \
--zone=europe-west1-b
Task 4: Deploy to Kubernetes
kubectl create deployment hello-node \
--image=europe-west1-docker.pkg.dev/YOUR_PROJECT_ID/my-docker-repo/hello-node:v1
kubectl get deployments
kubectl get pods
Task 5: Expose the App
Make the app accessible:
kubectl expose deployment hello-node --type="LoadBalancer" --port=8080
kubectl get services
Wait for the EXTERNAL-IP to appear, then visit:
http://<EXTERNAL-IP>:8080
Task 6: Scale the Service
kubectl scale deployment hello-node --replicas=4
kubectl get deployments
kubectl get pods
Kubernetes will ensure 4 pods are running.
Task 7: Roll Out an Upgrade
Edit server.js:
response.end("Hello Kubernetes World!");
Rebuild, retag, and push:
docker build -t hello-node:v2 .
docker tag hello-node:v2 europe-west1-docker.pkg.dev/YOUR_PROJECT_ID/my-docker-repo/hello-node:v2
docker push europe-west1-docker.pkg.dev/YOUR_PROJECT_ID/my-docker-repo/hello-node:v2
Update the deployment:
kubectl edit deployment hello-node
Change the image to:
image: europe-west1-docker.pkg.dev/YOUR_PROJECT_ID/my-docker-repo/hello-node:v2
Save and exit. Kubernetes will rollout the upgrade with zero downtime.
Summary & What’s Next?
You’ve just:
- Written a Node.js app
- Dockerized and tested it
- Published it to Artifact Registry
- Deployed it to GKE
- Scaled it horizontally
- Rolled out a new version seamlessly
If you’re new to Kubernetes and want a deeper conceptual introduction, check out this post:
👉 Kubernetes 101 — From Container Chaos to Cloud Control
Next, you could explore:
- Adding readiness and liveness probes
- Managing configs with ConfigMaps and Secrets
- Routing with Ingress controllers
- Automating with CI/CD and GitOps workflows
Want more tutorials like this one?
Subscribe to NotSoStatic for hands-on labs, DevOps guides, and stories from real-world cloud projects.