Ultra cheap website on GCP
Tags: googlecloud, django, serverless, docker
Published: 2023-01-19 09:40:37

A few years ago, I wanted to test an idea with a YouTube aggregator site for a specific user group and following the lean methodology, I wanted to test the idea at a small RUN cost.
**Google Cloud Platform** (GCP) had launched a few years ago the Cloud Run service which could run a serverless docker container to respond to web requests; hence, I launched on a journey to launch my website using Cloud Run and the GCP ecosystem. In this article, we would see :

1. The goal of the project
2. The different technical components I ended up using - The technical architecture

## (i) The goal of the project

- Go through the different YouTube channels, grab the latest videos depending on some decision criteria and present them in a library format
- Evidently, at a cheap cost of run

A website with an image carousal linking to the different selected videos, categorized into different sections.
![Image carousal liking to the videos](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i6jk04vqcp0oena0b79f.png)

## (ii) The different technical components

The website is written in _Python Django_ and the batch process to pull data from YouTube was written in plain Python.


![Architecture diagram](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vz35vabtveqr1kdr6816.png)
*Archi diagram*

Here is an explanation of the overall architecture:
1) The Django application is hosted in _GitHub_ and mirrored to the _GCP Source repository_

![Code repo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sx03qx67l9kou503cn19.png)

2) _Cloud Build_ is used to build the application into a docker image, push the image to the GCP _Container registry_. We can have multiple options to trigger the build, for example on a push to branch, a webhook event etc.. And for how to build the image, I used a Cloud Build configuration yaml file

``` yaml
steps:
  # build the container image
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'gcr.io/${_DEV_REGION}/twsite', '.']
  # push the container image to Container Registry
- name: 'gcr.io/cloud-builders/docker'
  args: ['push', 'gcr.io/${_DEV_REGION}/twsite']
  # Deploy container image to Cloud Run
- name: 'gcr.io/cloud-builders/gcloud'
  args: ['beta', 'run', 'deploy', 'twsite', '--image', 'gcr.io/${_DEV_REGION}/twsite', '--region', 'us-central1', '--platform', 'managed']
images:
- gcr.io/${_DEV_REGION}/twsite
substitutions:
    _DEV_REGION: twsite-dev
```

3) To make the image a runnable container, we are using the serverless - _Cloud Run_ service. The service accepts web requests and provides enough Free tier to test our website. Pay attention to the auth requirement to invoke the website and the port requirements as per the application. Serverless applications have a delayed response time when invoked for the first time, called the 'cold start', it is important to keep this in mind for this solution. The service account used in the Cloud Run settings should have access to the Cloud Datastore as the application uses the implicit access to access the data - which gives us more control and audit in the GCP platform.

![Cloud Run](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jrpzy8glf9geqcv50am0.png)

4) The batch process is written in the _Cloud Functions_ and is triggered once a day using the _Cloud Scheduler_. The Python code combs through a number of YouTube channels and pulls the most interesting videos to be saved in the Cloud Datastore. Many a time the timeout of the Cloud Functions was hit, and I had to break down the functions into smaller functions to fit inside the budgeted limits.

![Cloud Functions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v0ouxebsos8c9wf6gf5z.png)

The selection of a NoSQL database as the _Cloud Datastore_ helped in the evolution of the schema multiple times during the development phase. 

5) Another key service which comes in handy to save the day or to give us a slap in the face is the logging service attached to each of the cloud services used. Many a time we face issues - regarding the necessary access to use a service, mismatch of a port number, a secret not initialized correctly - to name a few

![Meme logging](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/91k1ad5ryml861vk5qp0.png)

After running the website for almost 6 months, I was not happy with the traction it built (or the lack of traction) and shut down the website. The maximum bill amount would have been less than $2 to which the Cloud Scheduler service was the major contributor and for the meak demand, the serverless components were well within the free tier.
 

> The fun of building the website from the ground up, the design decisions, adapting the code & design for new requirements and tweaking the GCP services for the new needs are something I will cherish.

Hoping this article trickles your curiosity, Happy tinkering!