In this blog post, you’ll learn how to use Google Cloud Build to build a Docker image using a build configuration file.
This post is part of the Dockerized Django Back-end API with Angular Front-end Tutorial. Check out all the parts of the tutorial there.
In the last part of the tutorial, we’ve learned how to prepare an Angular app for production in Docker. In this blog post, we’ll learn how to build the Docker image in our repository using Google Cloud Build, as we want to deploy our image to Google Cloud Platform (GCP).
If you’re not already aware, the code for the tutorial is found in my GitHub repository.
To get the code to where we left off in the last blog post, use:
$ git checkout v1.16
Background
If you’re new to this tutorial series, let’s clarify a bit where we’re at and what’s next to come.
The goal is to build and deploy a simple Todo application.
On the back-end, we have a REST API made with Django REST Framework (DRF). On the front-end, we have an Angular app through which we interact with the API.
For the rest of the tutorial series, you’ll learn how to deploy this stack as a Docker container on GCP.
How to Deploy a Docker Container on GCP
There are quite a few steps we need to do in order to build a Docker image and deploy it as a container on GCP. For this reason, I’ve broken down the process in a number of articles to make the information easier to digest.
Here are the high-level steps we need to tackle in the upcoming articles:
- build the Docker image using Cloud Build – we’ll build our image using Cloud Build. Specifically, we’ll build the Django Docker image using the Dockerfile found in
django/Dockerfile
, in the repository. There’s also a Dockerfile in the angular
directory in the repo, but we’ll use that only locally to build the Angular app. After we have the Angular static files, we’ll serve them from Google Cloud Storage. Therefore, we’re containerising only the Django REST API in the production deployment.
- access private repositories using Cloud Build (optional) – if your code is in a private GitHub/Bitbucket repo, then you need to grant Cloud Build the rights to access your repository.
- connect the Django API to Cloud SQL – we’ll configure the Django DRF API to use a PostgreSQL database hosted on Google Cloud SQL.
- deploy container on a Virtual Machine – after you’ve built your Docker image, the next step is to deploy the container on a Google Compute Engine Virtual Machine.
- serve the Angular app from Google Cloud Storage – we’ll serve the Angular app’s static files from a Cloud Storage bucket, as we want the Django app server to deal exclusively with dynamic requests.
Building the Docker Image Using a Build Config File in Cloud Build
We use Cloud Build to build Docker images on GCP.
Typically, after you’ve built the image, you’ll then push it to Container Registry.
Container Registry is simply a private container image registry similar to Docker Hub, which means that you can use it to store different Docker images there.
You have two ways of building a Docker image:
- using simply a Dockerfile
- using a build configuration file – you want to use this for builds involving custom steps.
Since we want to clone the repository from GitHub/Bitbucket, we need to go for the build configuration file option.
GCP Preparation
Before we begin, follow these steps first to set up a project on GCP:
-
In the GCP Console, go to the Manage resources page and select or create a new project.
-
Ensure that billing is enabled for your project by using this link.
-
Enable the Cloud Build API using this link.
-
Install and initialise the Google Cloud SDK.
-
Authorise the gcloud
command-line tool to access your project:
$ gcloud auth login
- Configure your project for the
gcloud
tool, where [PROJECT_ID]
is the GCP project ID created or selected in step 1.
$ gcloud config set project [PROJECT_ID]
Create a build config file
Let’s proceed to create a build configuration file to build our Docker image.
-
Create a build_gcp.yaml
file in the repository root.
-
Add the steps
field. This field will contain the build steps that Cloud Build will perform.
steps:
- Add the first step. Add a
name
field under steps
. This tells Cloud Build which container image to use in this build step.
Below we’re using the git
builder gcr.io/cloud-builders/git
, which is a container image running Git.
steps:
- name: 'gcr.io/cloud-builders/git'
- Add step arguments. Add the
args
field to the step to pass a list of arguments to the builder image under name
.
The code below will clone a shallow copy of our repository. Using the --depth 1
option, we’ll only copy the latest revision of everything in the repository.
steps:
- name: 'gcr.io/cloud-builders/git'
args:
- clone
- '--depth'
- '1'
- https://github.com/dnstanciu/drf-angular-docker-tutorial.git
Replace https://github.com/dnstanciu/drf-angular-docker-tutorial.git
with your own repository link.
-
Optionally, you could include additional fields for the step such as timeout
to specify that this step should be timed-out after a number of seconds. A list of all available steps can be found here.
-
Add more steps. You can add any number of build steps by including additional name
fields with corresponding cloud builders.
Let’s build and tag the Django images using a docker
builder:
# Build and tag the image.
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'gcr.io/yourproject/version1', './drf-angular-docker-tutorial/django']
Here, we’re building the image using the Dockerfile
in the ./drf-angular-docker-tutorial/django
directory. Therefore, we’re building ONLY the Django image from the repository. As said previously, we’ll serve the Angular files from Cloud Storage, which we’ll generate locally.
We’re also giving the image the gcr.io/yourproject/version1
tag. Replace yourproject
with the project ID of the project you’re working with in GCP.
- Add additional build configuration. You could include other fields to further configure the build. For a complete list, see the Build Configuration Overview.
In the below code snippet, we’ll use the images
field to publish our tagged image to the Container Registry:
# Publish the image to Container Registry.
images: ['gcr.io/yourproject/version1']
In the end, our build_gcp.yaml
file will look like this:
How to Start the Build Manually
Now that we have our build config file, we need to learn how to start a build manually.
For this, we’ll use the gcloud builds submit
command which has the following structure:
gcloud builds submit --config [BUILD_CONFIG] [SOURCE_LOCATION]
Where:
[BUILD_CONFIG]
is the build configuration file.
[SOURCE_LOCATION]
is the location (local or URL) of the source code.
To submit the build using the file we’ve created in the previous section, just run the following command from within the repo root:
$ gcloud builds submit --config build_gcp.yaml .
Alternatively, you can also go to the Cloud Console and in a new Cloud Shell, you can create a build_gcp.yaml
file and copy-paste the contents from the file on your computer there. To create the file, you can just use nano
from the Cloud Shell:
$ nano build_gcp.yaml
Make sure the project name set in the Cloud Shell is the same as the one you’ve written in your build_gcp.yaml
file.
At the end of the build process, you should see something like this in the terminal:
ID CREATE_TIME DURATION SOURCE IMAGES STATUS
71b1ed25-52a9-4b6d-bacd-2232846a4ca4 2019-01-12T10:55:18+00:00 1M18S gs://yourproject_cloudbuild/source/1547290515.89-4d61f43495c64c2ca7d0a72f9f93cbe8.tgz gcr.io/yourproject/version1 (+1 more) SUCCESS
View the Build
If you now go to the Cloud Build page in the GCP Console, you can select your project and view the Build history page.
Then, click a build and you’ll see the Build details page.
The Image link will tell you the name of your image in the Container Registry.
If there are problems building your image, these should show up in the logs on the Build details page.
To get the code to this stage, see my git commit or use:
$ git checkout v1.17
Let me know in the comments if you’ve had any problems following these steps.
Summary
In this part of the tutorial, we’ve learned how to build a Docker image using a build configuration file in Google Cloud Build. We’ve seen how to fetch the repository from GitHub and how to submit the build to Cloud Build.
In the next part of the tutorial, we’ll see how to configure Cloud Build to access private repositories on GitHub or Bitbucket.
Credit: For this tutorial, I’ve used the following resources: