Deploy Containerised Plotly Dash App with CI/CD (P2: GCP)

Author:Murphy  |  View: 21391  |  Time: 2025-03-23 20:03:21
Photo by Dominik Lückmann on Unsplash

After Heroku changed to paid tiers for their dynos, I wanted to try Google Cloud Platform (GCP) for deploying the same container, previously deployed to Heroku with CI/CD as described in Part 1.

Example app deployed on GCP using Github Actions CI/CD Pipeline, image by author. Note the latest action includes testing

Note: This guide will use billable components within GCP, costs will remain minimal after initial Deployment (below 1 euro in most cases). We will cover limiting and stopping costs at the end.

For the initial setup (Github, app and deploying to Heroku) please see P1 of this guide.

Here in P2 we zoom in on the deployment part for GCP and what you will need, thus changing step 5 and 6 from P1:

  1. File Structure
  2. Create Plotly Dash App
  3. Create a Dockerfile, Run Locally
  4. Build Docker Image with Github Actions
  5. Create and configure GCP project
  6. Deploy to Google Cloud Run through Github Actions

You can find the repo here on Github and the app on https://docker-dash-example.com/.

5. Create and configure GCP project

Within GCP everything is organized through projects in which you can enable services like Cloud Storage and Cloud Run. Create your Google Cloud account and project through the console and enable billing. Afterwards, be sure to install the gcloud CLI so you can interact with GCP through gcloud commands from your local machine.

Following the steps from this tutorial (step: Cloud Run) setup your service account, enable access to the services needed (run, storage, iam) and generate a key.json you'll need for authentication later.

Note: keep the key.json somewhere secure, perhaps not within your git repo.

6. Deploy to Google Cloud Run through Github Actions

6.1 push container

6.2 write deployment part in pipeline

6.3 limit billing and cleanup

6.1 Manual deployment on GCP

Before automating the process, let's manually deploy your app on Google Cloud Run (GCRu) through Google Container Register (GCRe). Following Google's guide to push your image to GCRe you'll finally run:

docker push HOSTNAME/PROJECT-ID/IMAGE:TAG

Note that when using Apple's Mx chip you'll need an additional flag for the build:

— platform linux/amd64

Navigate to your project's GCRe to see the image you just pushed. To deploy this image on GCRu we can use the following command (assuming all permissions are ok):

gcloud run deploy SERVICE --image IMAGE_URL

Where the SERVICE is your project_id and the IMAGE_URL contains the HOSTNAME/PROJECT-ID/IMAGE:TAG we filled during the docker push command before. Check if your container runs through Cloud Run by following the URL on top of your app's GCRu page.

GCRe (left) GCRu (right) containing the folder with Docker images and the app to be run in Cloud Run, screenshots by author

6.2 CI/CD for deployment on GCP

If your app works through manual deployment let's automate the process and incorporate a deployment step within the pipeline from part 1. As a brief recap, part 1 focused on deploying your Plotly Dash app through Github Actions on Heroku. Now deployment to Heroku is swapped with deployment to GCP within the Github Workflow.

Start by setting up the Github Secrets needed for the deployment pipeline:

  • GCP_EMAIL: the email from the service account you created, formatted like: $ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com
  • GCP_PROJECT_ID: your project name
  • GCP_CREDENTIALS: your key.json (copy paste the content)
  • GCP_APP_NAME: the name of your app (for within the GCRe)

With these secrets we can build the CI/CD workflow through Github Actions. Note that the initial build step of the workflow remains unchanged as we push and build the container within Github Packages first, please find the full explanation for the build part in part 1.

Build step (unchanged):

Deploy step (changed to GCP):

  • (lines: 1–24) The start is similar to deployment to Heroku, however, within the environment we now define the IMAGE_NAME as the location of your image within GCRe. We checkout master then pull and build the image from Github Packages.
  • ‘Login to Google Cloud': Using Google's defined workflow action we authenticate to Google Cloud. Here we use the GCP_CREDENTIALS secret from Github Secrets.
  • ‘Configure Docker': Within Google's guide for pushing and pulling images they also need you to setup authentication for Docker. This step configures authentication in the image during deployment.
  • ‘Push to registry': Push your image to GCRe
  • ‘Deploy': Using Google's defined workflow action for deploying to GCRu we deploy the pushed container through Cloud Run like we did manually before.
  • Notes: — port=8080 is the port I expose within my container, this can be different for your container. — allow-unauthenticated allows requests to your Cloud Run application without a valid authentication token. I use this flag to have my app publicly accessible, please use this flag as you see fit for your app.

6.3 Limit billing and cleanup

For the app to run we have activated multiple services. Take a look at the services described below and how to monitor and limit costs.

  • Google Cloud Storage ([GCS](https://cloud.google.com/storage)) costs, GCRe is storing the images of your containers within GCS. With a GB costing around 2 cents per month (in Europe) this should not cost you much if you keep the GCRe clean. We can make sure no old images linger in your GCRe by adding the following line that removes images without the ‘latest' tag:
- name: Clean up old images
  run: gcloud container images list-tags ${{ env.IMAGE_NAME }} --filter='-tags:*' --format="get(digest)" --limit=10 > tags && while read p; do gcloud container images delete "${{ env.IMAGE_NAME }}@$p" --quiet; done < tags
  • Google Cloud Run costs, having your apps operative costs computing power that you will be charged for. If your app is not used extensively this should also be below 1 or 2 dollar every month.

To keep track of these costs we can use the Google Cloud Billing center that keeps track of all the costs spend. Here, you can set an alert for costs of your account or more specifically for a project or service.

In addition, you can limit the original resources Google allocates to your GCRu using GCP quotas. Here you can limit the resources Google Cloud Run can use.

Conclusion

This taught me a lot about the advantages of containerizing an application to lift & shift it to another cloud platform. Make sure to monitor your Google Billing Overview and set alarms if you leave your app publicly accessible. If it is your first time using GCP you might still be eligible for their initial _$_300 of free credits.


Thanks for reading!

Please don't hesitate to reach out with any questions or comments.

Happy to connect on LinkedIn!

Some of my other projects.


Things to Improve

  • There can (and should) be a testing step in between the building and the deployment steps of the CI/CD pipeline (done in the latest update to the repo).
  • Using multi-step building can speed up deployment.
  • The docker image can be made smaller with the right tweaks, meaning faster building and deployment (Alpine base image, skip pip cache etc.).

Additional Things to try

Tags: Ci Cd Pipeline Deployment DevOps Docker Google Cloud Platform

Comment