Skip to main content

FastAPI Google Cloud Deployment

Introduction

Deploying your FastAPI application to the cloud is a critical step in making your API accessible to users worldwide. Google Cloud Platform (GCP) offers several services that make deployment straightforward, scalable, and cost-effective. In this guide, we'll explore how to deploy FastAPI applications on Google Cloud using three popular services: Cloud Run, App Engine, and Compute Engine.

By the end of this tutorial, you'll understand:

  • The different GCP deployment options for FastAPI
  • How to prepare your FastAPI app for cloud deployment
  • Step-by-step deployment processes for each GCP service
  • Best practices for monitoring and scaling your deployed application

Prerequisites

Before we begin, make sure you have:

  • A FastAPI application ready for deployment
  • Basic knowledge of FastAPI and Python
  • A Google Cloud account
  • Google Cloud SDK installed on your local machine
  • Docker installed (for Cloud Run deployments)

Preparing Your FastAPI Application for GCP Deployment

Before deploying to any Google Cloud service, we need to properly structure our FastAPI application:

1. Project Structure

A typical FastAPI project for cloud deployment should look like this:

project_directory/
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI application
│ ├── routers/ # API routes
│ ├── models/ # Data models
│ └── dependencies/ # Shared dependencies
├── Dockerfile # For containerized deployments
├── requirements.txt # Dependencies
├── .gcloudignore # Files to ignore when deploying
└── app.yaml # For App Engine deployments

2. Create a main.py File

Here's an example of a basic FastAPI application in app/main.py:

python
from fastapi import FastAPI
import uvicorn
import os

app = FastAPI(title="My FastAPI App")

@app.get("/")
async def root():
return {"message": "Hello from Google Cloud!"}

@app.get("/health")
async def health_check():
return {"status": "healthy"}

if __name__ == "__main__":
# This is used when running locally
port = int(os.environ.get("PORT", 8080))
uvicorn.run("app.main:app", host="0.0.0.0", port=port, reload=False)

3. Create a requirements.txt File

fastapi>=0.103.1
uvicorn>=0.23.2
gunicorn>=21.2.0

Option 1: Deploying FastAPI to Google Cloud Run

Cloud Run is an excellent choice for FastAPI applications because it:

  • Is fully managed and serverless
  • Automatically scales to zero when not in use
  • Only charges for the exact resources you use
  • Supports any containerized application

Step 1: Create a Dockerfile

Create a Dockerfile in your project root:

dockerfile
# Use the official Python image as a parent image
FROM python:3.11-slim

# Set the working directory in the container
WORKDIR /code

# Copy the dependencies file to the working directory
COPY requirements.txt .

# Install dependencies
RUN pip install --no-cache-dir --upgrade -r requirements.txt

# Copy the content of the local src directory to the working directory
COPY ./app /code/app

# Specify that the container listens on port 8080
EXPOSE 8080

# Command to run the application with Gunicorn as the WSGI server
CMD exec gunicorn -k uvicorn.workers.UvicornWorker -b :8080 app.main:app --workers 2

Step 2: Build and Test Your Container Locally

bash
# Build the container
docker build -t fastapi-app .

# Run the container locally
docker run -p 8080:8080 fastapi-app

Visit http://localhost:8080 in your browser to test if your API is working.

Step 3: Deploy to Cloud Run

bash
# Enable required APIs
gcloud services enable cloudbuild.googleapis.com
gcloud services enable run.googleapis.com

# Build and deploy in one command
gcloud run deploy fastapi-service \
--source . \
--platform managed \
--region us-central1 \
--allow-unauthenticated \
--memory 512Mi

The command will build your container image using Cloud Build, push it to Google Container Registry, and deploy it to Cloud Run.

After deployment, you'll receive a URL where your API is accessible, something like: https://fastapi-service-abcdef123-uc.a.run.app

Step 4: Verify the Deployment

Visit your deployment URL to verify that your API is working properly. You can also check the /docs endpoint (e.g., https://fastapi-service-abcdef123-uc.a.run.app/docs) to see your API documentation.

Option 2: Deploying FastAPI to Google App Engine

Google App Engine (GAE) is another excellent choice for FastAPI applications, offering:

  • Simplified deployment without managing containers
  • Automatic scaling based on traffic
  • Integration with other Google Cloud services
  • Built-in health checks and version management

Step 1: Create an app.yaml File

Create an app.yaml file in your project root:

yaml
runtime: python311
entrypoint: gunicorn -k uvicorn.workers.UvicornWorker -b :$PORT app.main:app --workers 2

instance_class: F2

automatic_scaling:
min_instances: 0
max_instances: 10
target_cpu_utilization: 0.65

env_variables:
DEBUG: "False"

Step 2: Create a .gcloudignore File

Create a .gcloudignore file to prevent unnecessary files from being uploaded:

.git
.gitignore
.env
.venv
env/
venv/
ENV/
__pycache__/
*.py[cod]
*$py.class

Step 3: Deploy to App Engine

bash
# Enable App Engine API if you haven't already
gcloud services enable appengine.googleapis.com

# Deploy your application
gcloud app deploy

When prompted, select the region for your App Engine application. After deployment completes, you can access your API at https://[YOUR-PROJECT-ID].appspot.com.

Step 4: View Logs and Monitor

bash
# View logs
gcloud app logs tail

# Open the deployment in a browser
gcloud app browse

Option 3: Deploying FastAPI to Google Compute Engine

For maximum control over your environment, you might want to deploy FastAPI to a Compute Engine VM:

Step 1: Create a VM Instance

bash
gcloud compute instances create fastapi-vm \
--image-family=debian-11 \
--image-project=debian-cloud \
--machine-type=e2-micro \
--tags=http-server,https-server \
--metadata=startup-script='#! /bin/bash
apt-get update
apt-get install -y python3-pip git
git clone https://github.com/yourusername/your-fastapi-repo.git /opt/app
cd /opt/app
pip3 install -r requirements.txt
nohup gunicorn -k uvicorn.workers.UvicornWorker -b :8080 app.main:app --workers 2 &'

Step 2: Configure Firewall Rules

bash
gcloud compute firewall-rules create allow-http \
--allow tcp:80,tcp:8080 \
--target-tags http-server \
--description "Allow HTTP traffic"

Step 3: Set Up a Systemd Service (Alternative to startup script)

For production environments, you might want to set up a proper systemd service instead of using a startup script. SSH into your VM and create a service file:

bash
sudo nano /etc/systemd/system/fastapi.service

Add the following content:

[Unit]
Description=FastAPI application service
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/opt/app
ExecStart=/usr/local/bin/gunicorn -k uvicorn.workers.UvicornWorker -b :8080 app.main:app --workers 2
Restart=always

[Install]
WantedBy=multi-user.target

Enable and start the service:

bash
sudo systemctl enable fastapi
sudo systemctl start fastapi

Step 4: Set Up Nginx (Optional)

For a production environment, you'll want to use Nginx as a reverse proxy:

bash
sudo apt-get install -y nginx

sudo nano /etc/nginx/sites-available/fastapi

Add the following configuration:

server {
listen 80;
server_name your-domain.com;

location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

Enable the site:

bash
sudo ln -s /etc/nginx/sites-available/fastapi /etc/nginx/sites-enabled/
sudo systemctl restart nginx

Advanced Configuration and Best Practices

Environment Variables

For all deployment options, you should use environment variables to manage configurations:

python
# In your FastAPI app
import os
from pydantic_settings import BaseSettings

class Settings(BaseSettings):
debug: bool = os.environ.get("DEBUG", "True").lower() == "true"
database_url: str = os.environ.get("DATABASE_URL", "sqlite:///./test.db")

class Config:
env_file = ".env"

settings = Settings()

app = FastAPI(debug=settings.debug)

Secret Management

For sensitive information, use Google Secret Manager:

bash
# Create a secret
gcloud secrets create DATABASE_PASSWORD --replication-policy="automatic"

# Add a version with the secret value
echo -n "my-secure-password" | gcloud secrets versions add DATABASE_PASSWORD --data-file=-

# Grant access to your service
gcloud secrets add-iam-policy-binding DATABASE_PASSWORD \
--member="serviceAccount:[email protected]" \
--role="roles/secretmanager.secretAccessor"

In your FastAPI app, use the Secret Manager client:

python
from google.cloud import secretmanager

def access_secret(project_id, secret_id, version_id="latest"):
client = secretmanager.SecretManagerServiceClient()
name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}"
response = client.access_secret_version(request={"name": name})
return response.payload.data.decode("UTF-8")

# Example usage
db_password = access_secret("your-project-id", "DATABASE_PASSWORD")

Health Checks

Implement proper health checks to help Google Cloud services determine if your application is running correctly:

python
@app.get("/health")
async def health_check():
# Check database connection
try:
# Example check for a database
# db_connection_successful = check_db_connection()
db_connection_successful = True

if not db_connection_successful:
return {"status": "unhealthy", "details": "Database connection failed"}, 503

return {"status": "healthy", "version": "1.0.0"}
except Exception as e:
return {"status": "unhealthy", "details": str(e)}, 503

Continuous Deployment with Cloud Build

Implement continuous deployment using Cloud Build:

  1. Create a cloudbuild.yaml file:
yaml
steps:
# Build the container image
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'gcr.io/$PROJECT_ID/fastapi-app:$COMMIT_SHA', '.']

# Push the container image to Container Registry
- name: 'gcr.io/cloud-builders/docker'
args: ['push', 'gcr.io/$PROJECT_ID/fastapi-app:$COMMIT_SHA']

# Deploy container image to Cloud Run
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
entrypoint: gcloud
args:
- 'run'
- 'deploy'
- 'fastapi-service'
- '--image'
- 'gcr.io/$PROJECT_ID/fastapi-app:$COMMIT_SHA'
- '--region'
- 'us-central1'
- '--platform'
- 'managed'
- '--allow-unauthenticated'

images:
- 'gcr.io/$PROJECT_ID/fastapi-app:$COMMIT_SHA'
  1. Set up a GitHub or GitLab trigger in Cloud Build to automatically deploy on code changes.

Monitoring and Logging

Use Google Cloud's built-in monitoring tools:

  1. Cloud Monitoring and Logging:
python
# Add structured logging to your FastAPI app
import logging
import json
from fastapi import FastAPI, Request
from starlette.middleware.base import BaseHTTPMiddleware

app = FastAPI()

class LoggingMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
response = await call_next(request)

log_dict = {
"remote_addr": request.client.host,
"method": request.method,
"path": request.url.path,
"status_code": response.status_code,
}

print(json.dumps(log_dict)) # Cloud Run/App Engine will capture stdout

return response

app.add_middleware(LoggingMiddleware)
  1. View logs in Google Cloud Console:
    • For Cloud Run: Navigate to Cloud Run > Your Service > Logs
    • For App Engine: Navigate to App Engine > Versions > Logs
    • For Compute Engine: Navigate to Compute Engine > VM Instances > Logs

Summary

In this guide, we've covered three methods for deploying FastAPI applications on Google Cloud Platform:

  1. Cloud Run: Best for containerized, serverless deployment with automatic scaling to zero.
  2. App Engine: Simplest deployment method with good scaling and no container management.
  3. Compute Engine: Maximum flexibility and control over your environment.

Each approach has its pros and cons, and the right choice depends on your specific requirements:

  • Choose Cloud Run for modern, containerized workloads with variable traffic patterns
  • Choose App Engine for the simplest deployment experience
  • Choose Compute Engine when you need full control over the infrastructure

Remember to implement proper health checks, environment configuration, secret management, and monitoring to ensure your FastAPI application runs reliably in production.

Additional Resources

Practice Exercises

  1. Deploy a FastAPI application with a database connection (e.g., Postgres on Cloud SQL) to Cloud Run.
  2. Set up a CI/CD pipeline using Cloud Build and GitHub for automatic deployments.
  3. Create a more complex FastAPI application with authentication and deploy it to App Engine.
  4. Implement a custom domain name for your deployed FastAPI service.
  5. Set up monitoring alerts for your application's performance metrics.

By completing these exercises, you'll gain hands-on experience deploying and managing FastAPI applications on Google Cloud Platform, preparing you for real-world development scenarios.



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)