Docker and Google Cloud Build

In a Nutshell

Google Cloud Build allows us to build our Docker images and deploy them to the cloud while versioning them. We deploy our containers to Google Cloud Run, which is a fully managed and scalable environment. Going forward I will be referring to Google Cloud Build as GCB. GCB allows us to utilize docker images to run any tasks that we need. This is in contrast to other pipelines that allow us to run a set of scripts, one of which can be a docker build command. GCB makes docker images its main driving factor of each step of the pipeline.

shipping containers

Our Configuration

We can configure our pipeline via a yaml or json file. This gives us the ability to use any Google Docker image or custom image to run tasks. Generally, we would only use it to build our application images. However, we are not running tests in our repo provider’s pipeline so we will be doing this in GCB. We leverage a docker image to solely be responsible for running unit tests, linting, and integration tests. Below is a sample of the configuration for just one of our Frontend deployment configs.

  # Build the Frontend stack
  - name: 'gcr.io/cloud-builders/docker'
    args: ['build', '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME/frontend:$COMMIT_SHA', './frontend']

  # Push the Frontend Nextjs image to Container Registry
  - name: 'gcr.io/cloud-builders/docker'
    args: ['push', 'gcr.io/$PROJECT_ID/$REPO_NAME/frontend:$COMMIT_SHA']
  
  # Deploy image to Cloud Run
  - name: 'gcr.io/cloud-builders/gcloud'
    args:
      - 'run'
      - 'deploy'
      - '$BRANCH_NAME-frontend'
      - '--image'
      - 'gcr.io/$PROJECT_ID/$REPO_NAME/frontend:$COMMIT_SHA'
      - '--allow-unauthenticated'
      - '--region'
      - 'us-central1'
      - '--platform'
      - 'managed'
      - '--port'
      - '3000'
      - '--memory'
      - '512Mi'
      - '--update-env-vars'
      - 'FE_START_CMD=start, REVISION_ID=$REVISION_ID, BUILD_ID=$BUILD_ID, CONFIG_ENV=$_CONFIG_ENV'

GCB has a ‘triggers’ feature that we leverage to trigger a build in response to changes in staging, production, or feature branches. This in turn will automatically deploy to Google Cloud Run. Following this it will provide us with a link to a fully managed environment, configured and scaled to our specification in our configuration. In each trigger, we can define environment variables that will get passed to our application. We can then leverage these variables to apply dynamic application configuration. An example would be if development should fetch assets from one location, where staging and production need to pull from another location. See our Google Cloud Run Post for some small ‘gotchas’.

// Production Configs
const prodConfig = {
  cloudBucket: '...',
  ...
};

// Staging Configs
const stgConfig = {
  cloudBucket: '...',
  ...
};

// Development Configs
const devConfig = {
  cloudBucket: '...',
  ...
};

const CONFIG_MAP = {
  production: prodConfig,
  staging: stgConfig,
  development: devConfig,
};

export default CONFIG_MAP[process.env.CONFIG_ENV];

Our Current Limitations

If you are leveraging Docker in your current application GCB gets the job done. On the other hand, if your application is not Dockerized this may not be the best for you. You could leverage existing images to get your tasks done and output some sort of artifacts. Also, you could leverage GCB for some computation like:

  • Create a Docker Image that loaded some data
  • Run calculations on that dataset
  • output the results to some artifacts registry, which google also supports

We did run into another limitation due to the limited set of services that GCB’s trigger feature can integrate with. Currently, GCB can only connect to a google repo for GitHub or Bitbucket. One of our clients does not use any of these, so we had to come up with a workaround. We created a proxy server that their repo’s hosting provider would call out too. Then the proxy server pushes changes into a Cloud Source Repositories so that the triggers can pick up the changes.


Conclusion

GCB is great if you are in the Google ecosystem, meaning you are leveraging their other services such as Cloud Run, Cloud SQL, Cloud Bucker, etc. Alongside this Docker and Google Cloud Build are a great combination. To leverage this while outside of their ecosystem does not seem like a great use case. This is due to GCB being tightly integrated into the rest of their services, for better or worst. We feel there are a lot of improvements that GCB needs to undergo such as:

  • Email and Slack integrations
  • Break out of only using images to run pipeline steps

Please leave your comments below as we still are experimenting with more use cases, pros, and cons. If we have missed some points feel free to let us know below.

Thank you for reading and please feel free to share using the links below!

One Reply to “Docker and Google Cloud Build”

Leave a Reply