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
:
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:
# 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
# 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
# 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:
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
# 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
# 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
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
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:
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:
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:
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:
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:
# 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:
# 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:
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:
@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:
- Create a
cloudbuild.yaml
file:
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'
- 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:
- Cloud Monitoring and Logging:
# 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)
- 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:
- Cloud Run: Best for containerized, serverless deployment with automatic scaling to zero.
- App Engine: Simplest deployment method with good scaling and no container management.
- 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
- FastAPI Official Documentation
- Google Cloud Run Documentation
- Google App Engine Documentation
- Google Compute Engine Documentation
- Cloud Build Continuous Deployment
Practice Exercises
- Deploy a FastAPI application with a database connection (e.g., Postgres on Cloud SQL) to Cloud Run.
- Set up a CI/CD pipeline using Cloud Build and GitHub for automatic deployments.
- Create a more complex FastAPI application with authentication and deploy it to App Engine.
- Implement a custom domain name for your deployed FastAPI service.
- 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! :)