Automate Node.js Deployment to Cloud Run with Cloud Build Triggers
Set up a Cloud Build trigger that watches a GitHub repo, builds a Node.js image with Kaniko, pushes it to Artifact Registry, and rolls out a new Cloud Run revision. Includes IAM setup, verification, and rollback.
07 Sept 2025, 02:17 UTC

Desired Outcome
When a developer pushes a commit to the main branch of a GitHub repository, a Cloud Build trigger automatically:
- Builds a Docker image of the Node.js application using
kaniko. - Puts the image into an Artifact Registry repository.
- Deploys the image as a new revision of a Cloud Run service.
- Leaves the previous revision available for instant rollback.
All steps run without manual intervention, and the process is auditable through Cloud Logging.
Prerequisites
- Google Cloud Project – A project with billing enabled.
- Node.js App – A simple
package.jsonwith astartscript. - Artifact Registry Repository – Create a repository named
nodejs-repoin the same region as Cloud Run. - Dedicated Service Account – Create a service account
cloudbuild-run-saand grant it:- Cloud Run Admin (roles/run.admin)
- Artifact Registry Writer (roles/artifactregistry.writer)
- Cloud Build Editor (roles/cloudbuild.builds.editor)
- Storage Admin for the build log bucket (roles/storage.admin)
- GitHub Repository – Public or private repo with the Node.js code.
- Cloud Build API – Enabled in the project.
- Cloud Run API – Enabled in the project.
- Artifact Registry API – Enabled in the project.
Focused Procedure
1. Connect GitHub to Cloud Build
Use the Cloud Console or gcloud to create a trigger that listens to pushes on main:
gcloud beta builds triggers create github \
--name="nodejs-ci-cd" \
--repo="myorg/my-node-app" \
--branch-pattern="^main$" \
--build-config=cloudbuild.yaml \
--service-account=[contact removed]
Replace myorg/my-node-app with your GitHub org/repo. The --service-account flag ensures the trigger runs with the least‑privilege account.
2. Create cloudbuild.yaml
Place this file at the root of your repo. It instructs Cloud Build to build with Kaniko and deploy to Cloud Run:
steps:
- name: 'gcr.io/cloud-builders/kaniko'
args:
- --dockerfile=Dockerfile
- --context=.
- --destination=${_ARTIFACT_REGISTRY}/${PROJECT_ID}/nodejs-repo:${SHORT_SHA}
env:
- 'DOCKER_CONFIG=/kaniko/.docker'
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
entrypoint: 'bash'
args: ['-c', 'gcloud run deploy my-node-service --image ${_ARTIFACT_REGISTRY}/${PROJECT_ID}/nodejs-repo:${SHORT_SHA} --region=us-central1 --platform=managed --allow-unauthenticated']
substitutions:
_ARTIFACT_REGISTRY: 'us-central1-docker.pkg.dev'
options:
logging: CLOUD_LOGGING
timeout: 1200s
secrets:
- kmsKeyName: projects/${PROJECT_ID}/locations/global/keyRings/build-keys/cryptoKeys/kaniko-key
secretEnv:
KANIKO_SECRET: 'projects/${PROJECT_ID}/secrets/kaniko-secret/versions/latest'
Key points:
- Kaniko builds the image without requiring Docker on the host.
- The image tag uses
${SHORT_SHA}for unique identification. - The second step deploys the image to Cloud Run with
--allow-unauthenticated(adjust as needed). - Secrets are passed via Cloud KMS; ensure the service account has
roles/cloudkms.cryptoKeyEncrypterDecrypter.
3. Verify Build and Deployment
- Push a trivial change to
main.git commit --allow-empty -m "Deploy test" git push origin main - In Cloud Build console, confirm the trigger fired, the build succeeded, and the image was pushed.
- Check Cloud Run for a new revision named
my-node-service-00001(or similar). TheRevisioncolumn shows the new SHA. - Send an HTTP request to the service URL:
The response should include the updated code (e.g., a new version string).curl https://my-node-service-00001-uc.a.run.app - Verify the image digest:
Compare this digest with the one printed in the Cloud Build logs.gcloud run services describe my-node-service \ --region us-central1 \ --format='value(status.latestReadyRevisionName)' # Then get the image digest IMAGE_DIGEST=$(gcloud run revisions describe my-node-service-00001 \ --region us-central1 \ --format='value(template.containers[0].imageDigest)') echo $IMAGE_DIGEST
4. Rollback Procedure
If the new revision fails, you can instantly revert to the previous stable version:
gcloud run services update my-node-service \
--region us-central1 \
--revision my-node-service-00000
Replace my-node-service-00000 with the revision name of the last working build. Cloud Run keeps all revisions; no extra cleanup is required for rollback.
5. Optional Enhancements
- Automated Tests – Add a test step before deployment to catch runtime errors early.
- Retention Policy – Configure Artifact Registry lifecycle to delete images older than 30 days to control cost.
- Monitoring – Enable Cloud Monitoring metrics for Cloud Run and Cloud Build to spot failures automatically.
Expected Checks and Recovery Options
- Build Log Inspection – Cloud Build logs reveal any Dockerfile or dependency errors. If the build fails, fix the code and push again.
- Deployment Verification – A successful
curlresponse confirms the new revision is live. - Revision Availability – Cloud Run keeps all revisions; you can always roll back by specifying the old revision name.
- IAM Auditing – Cloud Logging records the service account that performed the deployment. If unauthorized activity is detected, revoke the service account’s roles and rotate keys.
- Cost Monitoring – Artifact Registry and Cloud Run usage appear in the Billing console. Set alerts for unexpected spikes.
Limitations and Practical Checks
- The trigger’s default timeout is 1200 seconds; large repos may need a higher timeout via
--timeoutin the trigger config. - Kaniko does not support
RUN apt-get updatewithout a base image that includesapt; use a minimal base image or a multi‑stage Dockerfile. - Artifact Registry storage costs apply; enable a lifecycle rule if you anticipate many images.
- If the Cloud Build service account is mis‑configured, the trigger will fail with permission errors. Verify the account has the listed roles.
Conclusion
By tying GitHub pushes to a Cloud Build trigger that builds with Kaniko and deploys to Cloud Run, you achieve a fully automated, auditable CI/CD pipeline for Node.js applications. The process is secure, leverages least‑privilege IAM, and offers instant rollback via Cloud Run revisions.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.