Skip to main content

How to deploy FastAPI on Google Cloud Run

FastAPI is a modern Python framework for building APIs, and Google Cloud Run is a serverless platform for running containers without managing servers. In this tutorial, we will deploy a FastAPI application to Cloud Run using two practical methods: deploy directly from source code and deploy with Docker plus Artifact Registry.

How to Deploy FastAPI on Google Cloud Run: Step-by-Step Beginner Guide

FastAPI deployment on Google Cloud Run concept image
FastAPI + Cloud Run is a practical stack for deploying scalable Python APIs.

Introduction

Deploying a Python API is much easier today than before. Instead of buying a server, configuring Linux manually, installing a process manager, and maintaining infrastructure, you can package your application and deploy it to a managed service such as Google Cloud Run.

FastAPI is useful for building fast, clean, and well-documented APIs in Python. Cloud Run is useful because it runs containers, scales automatically, and can scale down when not in use.

Simple definition: Google Cloud Run lets you run containerized applications as serverless services. FastAPI provides the API framework, Docker packages the app, and Cloud Run hosts it on the web.

In this guide, we will build a small FastAPI project, test it locally, deploy it to Cloud Run, and review common problems such as port errors, container startup failures, authentication, environment variables, and logging.


Why Use FastAPI with Cloud Run?

FastAPI Benefits

  • Fast development for Python APIs.
  • Automatic interactive API documentation at /docs.
  • Strong support for JSON request and response bodies.
  • Works well with type hints and Pydantic models.
  • Good fit for microservices, AI APIs, dashboard backends, and mobile app APIs.

Cloud Run Benefits

  • Runs containerized applications without managing servers.
  • Scales automatically based on request traffic.
  • Can scale to zero when idle, which helps reduce cost for small projects.
  • Works with any language or framework that can run inside a container.
  • Integrates with Google Cloud services such as Artifact Registry, Cloud Build, Secret Manager, Cloud Logging, Pub/Sub, and Cloud SQL.
Good use cases:
AI recommendation APIs, inventory APIs, mobile app backends, webhook receivers, data-processing endpoints, chatbot backend services, internal dashboards, and small public APIs.

Two Deployment Options

There are two common ways to deploy FastAPI to Cloud Run:

Method Best For Command Style
Deploy from source Beginners and quick projects gcloud run deploy --source .
Docker + Artifact Registry Production-style deployments and teams that want full control over images Build image → push image → deploy image
Updated note: Google Container Registry is deprecated. Use Artifact Registry for new container images instead of old gcr.io Container Registry workflows.

Prerequisites

Before starting, make sure you have:

  • A Google Cloud account.
  • A Google Cloud project with billing enabled.
  • Google Cloud CLI installed and authenticated.
  • Python installed locally.
  • Docker installed if you want to use the Docker method.
  • Basic knowledge of terminal commands.

Set Your Project and Region

Replace YOUR_PROJECT_ID with your real Google Cloud project ID.

gcloud config set project YOUR_PROJECT_ID gcloud config set run/region asia-southeast1

For Thailand or Southeast Asia users, asia-southeast1 is often a practical region. You can choose another region depending on your users and project requirements.

Enable Required APIs

gcloud services enable run.googleapis.com gcloud services enable cloudbuild.googleapis.com gcloud services enable artifactregistry.googleapis.com

Project Structure

Create a project folder like this:

fastapi-cloudrun-demo/ ├── main.py ├── requirements.txt ├── Dockerfile └── .dockerignore

Step 1: Create the FastAPI Application

Create a file named main.py.

from fastapi import FastAPI from pydantic import BaseModel app = FastAPI( title="FastAPI Cloud Run Demo", description="A simple FastAPI app deployed on Google Cloud Run.", version="1.0.0", ) class MessageRequest(BaseModel): name: str = "World" @app.get("/") def read_root(): return { "message": "FastAPI is running on Google Cloud Run!" } @app.get("/healthz") def health_check(): return { "status": "ok" } @app.post("/hello") def say_hello(payload: MessageRequest): return { "message": f"Hello, {payload.name}!" }

This application gives you three useful endpoints:

  • / checks if the app is running.
  • /healthz works as a simple health check.
  • /hello accepts JSON input and returns a response.

Step 2: Create requirements.txt

Create requirements.txt.

fastapi uvicorn[standard]
Tip: For production projects, you may pin package versions after testing. For beginner tutorials, keeping the file simple makes the setup easier to follow.

Step 3: Test Locally

Create a virtual environment and install dependencies.

Windows PowerShell

python -m venv .venv .venv\Scripts\Activate.ps1 pip install -r requirements.txt uvicorn main:app --reload --host 0.0.0.0 --port 8080

macOS / Linux

python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt uvicorn main:app --reload --host 0.0.0.0 --port 8080

Open your browser:

http://localhost:8080 http://localhost:8080/docs http://localhost:8080/healthz

The /docs page is the automatic Swagger UI generated by FastAPI.


Step 4: Create a Dockerfile

Create a file named Dockerfile. This version is designed to work well with Cloud Run because it listens on the port provided by the PORT environment variable.

FROM python:3.12-slim WORKDIR /app ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONUNBUFFERED=1 COPY requirements.txt . RUN pip install --no-cache-dir --upgrade pip \ && pip install --no-cache-dir -r requirements.txt COPY . . CMD exec uvicorn main:app --host 0.0.0.0 --port ${PORT:-8080}
Important: Cloud Run expects your container to listen on 0.0.0.0 and the port provided by Cloud Run. The default request port is usually 8080, but using ${PORT:-8080} is safer.

Step 5: Create .dockerignore

Create .dockerignore to avoid copying unnecessary files into the Docker image.

.venv __pycache__ *.pyc .git .gitignore .env .DS_Store .idea .vscode

Method A: Deploy Directly from Source Code

This is the easiest method. Cloud Run can build and deploy your service from the current folder.

gcloud run deploy fastapi-cloudrun-demo \ --source . \ --region asia-southeast1 \ --allow-unauthenticated

On Windows PowerShell, use backticks instead of backslashes:

gcloud run deploy fastapi-cloudrun-demo ` --source . ` --region asia-southeast1 ` --allow-unauthenticated

After deployment finishes, Cloud Run will show a service URL. Open it in your browser and test:

https://YOUR_SERVICE_URL/ https://YOUR_SERVICE_URL/docs https://YOUR_SERVICE_URL/healthz
Beginner recommendation: Use --source . first if you are learning. Use Docker + Artifact Registry when you want more control over the image build and release process.

Method B: Deploy with Docker and Artifact Registry

This method gives you more control. You build the Docker image, push it to Artifact Registry, and deploy that image to Cloud Run.

1. Set Variables

macOS / Linux

PROJECT_ID=$(gcloud config get-value project) REGION=asia-southeast1 REPO=fastapi-repo IMAGE=fastapi-demo SERVICE=fastapi-demo IMAGE_URI=$REGION-docker.pkg.dev/$PROJECT_ID/$REPO/$IMAGE:latest

Windows PowerShell

$PROJECT_ID = gcloud config get-value project $REGION = "asia-southeast1" $REPO = "fastapi-repo" $IMAGE = "fastapi-demo" $SERVICE = "fastapi-demo" $IMAGE_URI = "$REGION-docker.pkg.dev/$PROJECT_ID/$REPO/${IMAGE}:latest"

2. Create an Artifact Registry Repository

macOS / Linux

gcloud artifacts repositories create $REPO \ --repository-format=docker \ --location=$REGION \ --description="FastAPI Docker images"

Windows PowerShell

gcloud artifacts repositories create $REPO ` --repository-format=docker ` --location=$REGION ` --description="FastAPI Docker images"

3. Authenticate Docker to Artifact Registry

macOS / Linux

gcloud auth configure-docker $REGION-docker.pkg.dev

Windows PowerShell

gcloud auth configure-docker "$REGION-docker.pkg.dev"

4. Build and Push the Docker Image

macOS / Linux

docker build -t $IMAGE_URI . docker push $IMAGE_URI

Windows PowerShell

docker build -t $IMAGE_URI . docker push $IMAGE_URI

5. Deploy the Image to Cloud Run

macOS / Linux

gcloud run deploy $SERVICE \ --image $IMAGE_URI \ --region $REGION \ --platform managed \ --allow-unauthenticated

Windows PowerShell

gcloud run deploy $SERVICE ` --image $IMAGE_URI ` --region $REGION ` --platform managed ` --allow-unauthenticated

Step 6: Test the Cloud Run Service

After deployment, test the service URL in your browser:

https://YOUR_SERVICE_URL/ https://YOUR_SERVICE_URL/docs https://YOUR_SERVICE_URL/healthz

You can also test the POST endpoint.

curl

curl -X POST "https://YOUR_SERVICE_URL/hello" \ -H "Content-Type: application/json" \ -d '{"name":"Lae TechBank"}'

Windows PowerShell

$body = @{ name = "Lae TechBank" } | ConvertTo-Json Invoke-RestMethod ` -Uri "https://YOUR_SERVICE_URL/hello" ` -Method POST ` -ContentType "application/json" ` -Body $body

Expected response:

{ "message": "Hello, Lae TechBank!" }

Step 7: View Logs

Logs are very important when debugging Cloud Run deployment problems.

gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=fastapi-demo" \ --limit 20 \ --format "value(textPayload)"

You can also open the Google Cloud Console:

Cloud Run → Select your service → Logs

Environment Variables and Secrets

Most production APIs need environment variables for database URLs, API keys, model names, feature flags, or configuration.

Set an Environment Variable

gcloud run services update fastapi-demo \ --region asia-southeast1 \ --set-env-vars APP_ENV=production

Use Secret Manager for Sensitive Values

Do not hard-code passwords, API keys, or database credentials in your code or Dockerfile. Use Secret Manager or secure environment variable configuration.

Security rule: Never commit .env files, private keys, service account JSON files, or database passwords to GitHub.

Authentication: Public API vs Private API

In beginner tutorials, --allow-unauthenticated is often used so anyone can open the API URL. This is convenient for testing, but it is not always safe for real APIs.

API Type Access Setting Example
Public API Allow unauthenticated access Public demo endpoint or public webhook receiver
Private API Require IAM authentication Internal business API or admin backend
Partner API Use API keys, OAuth, JWT, or gateway protection Mobile app backend or partner integration
Production advice: Use authentication and authorization for APIs that access private data, user records, inventory records, health data, or business systems.

Optional: Add Pub/Sub Trigger

You can also use Cloud Run as a service that receives messages from Pub/Sub. This is useful for background processing, event-driven workflows, and asynchronous jobs.

gcloud pubsub topics create fastapi-topic

Create a push subscription:

gcloud pubsub subscriptions create fastapi-sub \ --topic fastapi-topic \ --push-endpoint=https://YOUR_SERVICE_URL/hello \ --ack-deadline=10

Publish a test message:

gcloud pubsub topics publish fastapi-topic --message '{"name":"PubSub"}'
Important: For production Pub/Sub push subscriptions, configure authentication properly instead of leaving sensitive endpoints public.

Best Practices for FastAPI on Cloud Run

Best Practice Why It Matters
Listen on 0.0.0.0 and PORT Cloud Run routes traffic to the container port. Listening only on localhost can break deployment.
Add a health endpoint Makes testing and monitoring easier.
Keep the image small Smaller images can reduce build time and cold-start overhead.
Use Artifact Registry It is the recommended container image storage service on Google Cloud.
Use Secret Manager Protects credentials and API keys.
Write logs to stdout and stderr Cloud Logging can capture container logs automatically.
Set max instances Helps control cost and protects downstream services such as databases.
Use CI/CD for real projects Automates testing, building, and deployment after code changes.

Common Errors and Fixes

Error / Problem Likely Cause How to Fix
Container failed to start and listen on PORT=8080 Wrong host, wrong port, or app startup failed. Use --host 0.0.0.0 and --port ${PORT:-8080}. Check logs for Python errors.
ModuleNotFoundError or import error Wrong file name or missing dependency. Make sure main.py contains app = FastAPI() and requirements.txt includes all packages.
/healthz returns 404 No health route exists. Add @app.get("/healthz") to your FastAPI app.
Docker push fails Docker is not authenticated to Artifact Registry or repository does not exist. Run gcloud auth configure-docker REGION-docker.pkg.dev and create the repository.
Permission denied during deployment Missing IAM permissions. Check project roles for Cloud Run, Cloud Build, Artifact Registry, and service account permissions.
Unexpected cost Too many instances, high traffic, or background workloads. Set max instances, review logs, reduce unnecessary calls, and monitor billing.
API is public when it should be private Used --allow-unauthenticated. Remove public access and use IAM or API gateway protection.

Production Checklist

Before using your FastAPI Cloud Run service in production, review this checklist:

Checklist Item Status
FastAPI app has /healthz endpoint.
Container listens on 0.0.0.0 and PORT.
Secrets are stored outside code.
Authentication is configured correctly.
Logs are visible in Cloud Logging.
Cloud Run memory, CPU, concurrency, and max instances are reviewed.
Artifact Registry is used for Docker images.
CI/CD pipeline is planned for future updates.
Billing alerts are enabled.

Cloud Run Deployment Flow Summary

Write FastAPI app ↓ Test locally with Uvicorn ↓ Create Dockerfile or use source deployment ↓ Deploy to Cloud Run ↓ Open service URL ↓ Test /docs and API endpoints ↓ Monitor logs and performance ↓ Add auth, database, secrets, and CI/CD for production

Conclusion

Deploying FastAPI on Google Cloud Run is a practical way to publish Python APIs without managing servers. FastAPI gives you a modern API framework, Docker makes your app portable, and Cloud Run provides serverless container hosting with automatic scaling.

For beginners, the easiest path is gcloud run deploy --source .. For production-style workflows, Docker plus Artifact Registry gives more control over image versioning and deployment.

The most important Cloud Run rule is simple: your app must listen on 0.0.0.0 and the correct PORT. If you follow that rule, keep secrets secure, use Artifact Registry, and monitor logs, you can deploy reliable FastAPI APIs on Google Cloud Run.

Keywords: FastAPI deployment, Cloud Run FastAPI, deploy FastAPI on Google Cloud Run, Docker FastAPI, Google Cloud Run tutorial, Python FastAPI Cloud Run, serverless FastAPI, containerize FastAPI, Artifact Registry FastAPI, gcloud run deploy, FastAPI Dockerfile, Cloud Run troubleshooting

References

  1. Google Cloud Docs: Build and deploy a Python FastAPI web app to Cloud Run
  2. Google Cloud Docs: Deploy Cloud Run services from source code
  3. Google Cloud Docs: Cloud Run container runtime contract
  4. Google Cloud Docs: Configure containers for Cloud Run services
  5. Google Cloud Docs: Configure environment variables for Cloud Run services
  6. Google Cloud Docs: Transition from Container Registry to Artifact Registry
  7. Google Cloud Docs: Configure Docker authentication to Artifact Registry
  8. FastAPI Docs: FastAPI in Containers - Docker
  9. Google Codelabs: Hello Cloud Run with Python FastAPI

Related Reading

Comments