How to Deploy a Python API alongside your Firebase Project

Deploy a Python API alongside Firebase

Firebase is an awesome tool, but it's possible to go a little far down the BaaS rabbit hole and forget that not every app is a good fit to be stitched together with Cloud Functions, or custom code in your app bundle.

Sometimes you need a real backend. Luckily, if you have a Firebase project already, there's a really simple way to deploy an API alongside it.

To it, we'll use Google Cloud Run

Cloud Run is a service designed to spin up Docker containers in a serverless environment, allowing you to deploy an API and let Google manage all the heavy lifting in terms of server maintainance and scaling. You can even set the number of instances to zero, meaning the app will automatically sleep when not in use.

Python is my language of choice, due to its simple yet powerful nature, but you can apply this method to any language at all.

You'll need the project ID, which you can get from the Firebase console. Choose a GCP region, whichever is likely closest to your users. Choose a service name so you can identify the running API service. And choose a YAML environment-variables file, remembering that you ideally have at least two, one for development and one for production.

This process is far easier in the terminal, and these commands work for bash. This will work out of the box in Mac and Linux, but for Windows you'll need to also install something like Git Bash.

First you'll need to install the gcloud CLI tool, which you can grab from Google by following the install instructions.

Here are the commands to use:

      
        
# Login to google cloud
gcloud auth login

# Add your project id and choose a value for the other fields here
PROJECT_ID=<your project id>
REGION=us-central1
SERVICE_NAME=<give the deployment a name>
ENV_FILE=.env.yaml

# Set the current project
gcloud config set project $PROJECT_ID
gcloud auth application-default set-quota-project $PROJECT_ID

# Get the project number
PROJECT_NUMBER=`gcloud projects describe $(gcloud config get-value project) --format="value(projectNumber)"`

# Run the first deploy with the env variables. Subsequent deploys can be done via Github Actions (if set up)
gcloud run deploy $SERVICE_NAME --source . --region=$REGION --platform=managed --allow-unauthenticated --service-account="[email protected]" --env-vars-file $ENV_FILE

      
    

It's a good idea to run these commands one at a time, to address any errors, but if you like, you can run the whole script all at once.


Automated API deployments

Github is a very well known platform for storing code under version control. It's recommended to use git locally to version your code in general, and Github is a nice platform to compliment that workflow and keep your code safe in the cloud. When you push the code to Github, it triggers "Github Actions" defined in the .github/workflows/ folder.

Go ahead and add an actions file, we'll call it .github/workflows/gcp-deploy.yaml.

      
        
name: Deploy to Cloud Run

on:
  push:
    branches:
      - develop
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout repository
      uses: actions/checkout@v3

    - name: Authenticate with Google Cloud
      env:
        GCLOUD_SERVICE_KEY: ${{ secrets.GCLOUD_SERVICE_KEY }}
      run: |
        echo $GCLOUD_SERVICE_KEY | base64 --decode > $HOME/gcloud-key.json
        gcloud auth activate-service-account --key-file=$HOME/gcloud-key.json
        gcloud config set project ${{ secrets.GCLOUD_PROJECT_DEV }}

    - name: Deploy to Cloud Run
      run: |
        gcloud run deploy <deploy name> --source . --region europe-west1 --platform managed --allow-unauthenticated

      
    

To get the Action working, you'll need to add secrets. These can be set in the Github dashboard under Settings > Secrets & Variables > Actions.

First, you need to set GCLOUD_SERVICE_KEY. It also a good idea to set up separate versions of this for dev and prod. Run the following commands to get the secret. It's base64 encoded to make it more portable.

      
        
# Create a credentials keyfile for the service account that will be in charge of deployments
gcloud iam service-accounts keys create keyfile.json --iam-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com

# Copy the base64 string from this command and paste it into Github actions
cat keyfile.json | base64 -w 0

      
    

After doing the above, DELETE THE KEYFILE or at least keep it somewhere safe elsewhere. DO NOT ACCIDENTALLY ADD IT TO THE REPOSITORY OR COMMIT IT TO GIT.

Once you've added GCLOUD_SERVICE_KEY as secret with the value that comes from the cat command, you're done! Now any pushes to either the main or develop branch will trigger a deploy of your API.