Cloud Build isn’t just a CI/CD tool; it’s a fully managed, serverless platform that executes your build and deployment steps in ephemeral Docker containers.
Let’s see it in action. Imagine a simple Node.js app.
# cloudbuild.yaml
steps:
- name: 'gcr.io/cloud-builders/npm'
args: ['install']
- name: 'gcr.io/cloud-builders/npm'
args: ['test']
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'gcr.io/$PROJECT_ID/my-node-app:$COMMIT_SHA', '.']
- name: 'gcr.io/cloud-builders/docker'
args: ['push', 'gcr.io/$PROJECT_ID/my-node-app:$COMMIT_SHA']
- name: 'gcr.io/cloud-builders/gcloud'
args:
- 'run'
- 'deploy'
- 'my-node-app'
- '--image'
- 'gcr.io/$PROJECT_ID/my-node-app:$COMMIT_SHA'
- '--region'
- 'us-central1'
- '--platform'
- 'managed'
- '--allow-unauthenticated'
This cloudbuild.yaml file defines the build process. Cloud Build spins up a container for each step, runs the command, and then discards the container. The npm install and npm test steps execute within an npm builder image. The docker build and docker push steps use the Docker builder image to create a container image, tag it with the commit SHA for traceability, and push it to Google Container Registry (GCR). Finally, the gcloud run deploy step uses the gcloud builder to deploy this new container image to Cloud Run, making it a live, accessible service.
The core problem Cloud Build solves is abstracting away the infrastructure needed for CI/CD. Instead of managing Jenkins servers, build agents, or Docker daemons, you declare your build and deploy steps in a YAML file. Cloud Build handles the rest: provisioning the execution environment, running your commands, and cleaning up. This means you can focus purely on your application’s build and deployment logic.
Internally, Cloud Build orchestrates these steps using Google’s robust infrastructure. When a build is triggered (e.g., by a Git commit), Cloud Build provisions a temporary, isolated environment – a Docker container – for each step defined in your cloudbuild.yaml. It pulls the specified builder image (like gcr.io/cloud-builders/docker or gcr.io/cloud-builders/npm), mounts your source code, and executes the commands. The output of one step can be used as input for the next, and artifacts can be stored in GCS or pushed to GCR.
The real power comes from its integration with other GCP services. You can trigger builds from Cloud Source Repositories, GitHub, or Bitbucket. You can deploy directly to Compute Engine, GKE, App Engine, Cloud Functions, and Cloud Run. IAM roles and service accounts are crucial here; the Cloud Build service account needs permissions to push to GCR, deploy to Cloud Run, or whatever actions your build requires.
A common misconception is that builder images are just thin wrappers. They are fully functional Docker images with pre-installed tools. For example, the gcr.io/cloud-builders/docker image already has docker CLI installed. You can also use custom builder images by specifying a different name in your step, allowing you to package specific tools or environments your build needs. This extensibility is key to handling complex workflows beyond simple application builds.
You can also use substitution variables. $PROJECT_ID and $COMMIT_SHA are built-in, but you can define your own, like _MY_ENV=staging, which can then be used in your cloudbuild.yaml to conditionally change build or deployment behavior.
The next step often involves implementing more sophisticated deployment strategies, such as blue/green deployments or canary releases, which Cloud Build can facilitate with additional scripting and service configurations.