GCP CI/CD Pipeline: Build Docker images after commits to a repo branch (Google Cloud Source Repositories)
Tags: gcp, cloud, cicd, docker
Published: 2022-09-23 18:09:40

In this article we will learn how to connect GCP's code versioning service ([Cloud Source Repositories](https://cloud.google.com/source-repositories/docs/create-code-repository#:~:text=Cloud%20Source%20Repositories%20are%20private,version%20control%20for%20your%20code.)) to [Cloud Build](https://cloud.google.com/build) to automate building Docker images and pushing them to [GCP Container Registry](https://cloud.google.com/container-registry).

Cloud and containers have truly revolutionized deployment and management of web infrastructure. Ability to build docker images triggered by a push or a pull request allows developers focus more on code and less on infrastructure.

The process of setting up this pipeline will follow these steps:
1. Create a repository in Cloud Source Repositories
2. Push source code files to our repo
3. Create a trigger in Cloud Build service
4. Set trigger to build a Docker image when there is a new commit to the specified branch

&nbsp;

### 1. Creating a repository in Cloud Source Repositories
Navigate to Cloud Source Repositories using sidebar or a search bar at the top.

Verify that you are creating your repository in the correct project and then click `Add repository` button in the top right corner:

![GCP CI/CD Pipeline for Docker images with Cloud Source Repositories. Creating a Cloud Source Repository pt1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jb0vaejhklw6v3oopvtw.png)

Since we will be using GCP's version control we need to select `Create new repository` option and click `Continue`:


![GCP CI/CD Pipeline for Docker images with Cloud Source Repositories. Creating a Cloud Source Repository  pt2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vt0jc2fnq6naojpzs4uz.png)

Next we will need to enter the name of our repo and select the project. Click `Create` button after you are done:


![GCP CI/CD Pipeline for Docker images with Cloud Source Repositories. Creating a Cloud Source Repository  pt3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mmxrdtkerfniz3d59ynk.png)

For the final step we will clone our newly created repository to our local machine using the instructions provided:


![GCP CI/CD Pipeline for Docker images with Cloud Source Repositories. Creating a Cloud Source Repository  pt4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wz2sxk01a7c2ksr5v0o6.png)

You can upload your code to the repo using either SSH (1st option) or using gcloud CLI. I will let reader decide which option to use. 

&nbsp;

### 2. Source files

For this project we will have 2 sources files:

`Dockerfile`:
```docker
FROM python:3.7-slim
RUN pip install flask
WORKDIR /myapp
COPY main.py /myapp/main.py
CMD ["python", "/myapp/main.py"]
```

`main.py`:
```python
from flask import Flask

app = Flask(__name__)


@app.route('/')
def index():
    return 'CI/CD pipeline with GCP Cloud Source Repositories and Docker'


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)
```

Following the instructions push these files to the repo and verify that they are uploaded:


![GCP CI/CD Pipeline for Docker images with Cloud Source Repositories. Setting up repository](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vqurv4gwkhe169qk1l50.png)

&nbsp;

### 3. Creating a Cloud Build trigger

If you are using Cloud Build for the first time you will be asked to enable the API first. Click `Enable` to activate this API. It might take a minute, it is normal.

Click on `Triggers` in the sidebar:

![GCP CI/CD Pipeline for Docker images with Cloud Source Repositories. Creating a build trigger pt1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h2pawhrbphq71zos8rx0.png)

To create a new trigger click on the `Create new trigger` button at the bottom of the page:

![GCP CI/CD Pipeline for Docker images with Cloud Source Repositories. Creating a build trigger pt2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bslq8l29axwo7pqpzil6.png)

On the trigger creation page we will need to pay attention to 4 important parts:
1. Trigger name
2. Event that will trigger the action (I left it as default `Push to a branch`)
3. Source repository (click on the dropdown and select your repo and the branch that this trigger will monitor)
4. Configuration type (select `Dockerfile`)

After you are done click `Create` to finish setting up the trigger.

To test our trigger we will first invoke it manually by clicking `RUN` button:

![GCP CI/CD Pipeline for Docker images with Cloud Source Repositories. Running the trigger manually pt1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hqmhqqp5vrdxcnb640ix.png)

A popup will appear asking for confirmation. Click `Run trigger`:

![GCP CI/CD Pipeline for Docker images with Cloud Source Repositories. Running the trigger manually pt2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sznydklipa8qg0j24qzf.png)

If we click the `History` option in the sidebar on the left we can see the build history:


![GCP CI/CD Pipeline for Docker images with Cloud Source Repositories. Running the trigger manually pt3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w50aj9d967wnoldhenwi.png)


My build has succeeded:

![GCP CI/CD Pipeline for Docker images with Cloud Source Repositories. Running the trigger manually pt4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bo1frsj26xau60jnmos5.png)

&nbsp;

### 4. Verifying that Dockerimage is built automatically

GCP has a service for storing container image called Container Registry.

Navigate to Contianer Registry and you should see your image there:

![GCP CI/CD Pipeline for Docker images with Cloud Source Repositories. Docker image from manual trigger](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/po0piakta586y41vrkmm.png)


And finally, lets do a test with a test push. Let's modify our `main.py` file and push changes to the repository. I modified the text a little and added `v2.0`:
```python
from flask import Flask

app = Flask(__name__)


@app.route('/')
def index():
    return 'CI/CD pipeline with GCP Cloud Source Repositories and Docker v2.0'


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)
```

Commit and push new changes to the repo. It should run the trigger automatically. You should see a running process in the History tab (mine completed really fast):

![GCP CI/CD Pipeline for Docker images with Cloud Source Repositories. Docker image from automated trigger pt1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nqqw2awahhgjnjnytf6r.png)


Let's go to the container registry and verify that the new image there:
![GCP CI/CD Pipeline for Docker images with Cloud Source Repositories. Docker image from automated trigger pt2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z3gz007m191p74mscgdg.png)

There will be two images, one from running the trigger manually and the second one from pushing code to the tracked branch.
And yes, as we can see the new image is there!

![GCP CI/CD Pipeline for Docker images with Cloud Source Repositories. Docker image from automated trigger pt3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yabk3fcxzfs5cxvolem4.png)

&nbsp;

That's it. You have created a CI/CD pipeline that builds a Docker image when new code is committed to the tracked branch!