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
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, it can package 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.
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.
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 |
gcr.io Container Registry workflows.Prerequisites
Before starting, make sure to have:
- A Google Cloud account.
- A Google Cloud project with billing enabled.
- Google Cloud CLI installed and authenticated.
- Python installed locally.
- Docker installed if we want to use the Docker method.
- Basic knowledge of terminal commands.
Set the 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-southeast1For Thailand or Southeast Asia users, asia-southeast1 is often a practical region. We can choose another region depending on the users and project requirements.
Enable Required APIs
gcloud services enable run.googleapis.com
gcloud services enable cloudbuild.googleapis.com
gcloud services enable artifactregistry.googleapis.comProject Structure
Create a project folder like this:
fastapi-cloudrun-demo/
├── main.py
├── requirements.txt
├── Dockerfile
└── .dockerignoreStep 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 three useful endpoints:
/checks if the app is running./healthzworks as a simple health check./helloaccepts JSON input and returns a response.
Step 2: Create requirements.txt
Create requirements.txt.
fastapi
uvicorn[standard]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 8080macOS / Linux
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
uvicorn main:app --reload --host 0.0.0.0 --port 8080Open the browser:
http://localhost:8080
http://localhost:8080/docs
http://localhost:8080/healthzThe /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}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
.vscodeMethod A: Deploy Directly from Source Code
This is the easiest method. Cloud Run can build and deploy the service from the current folder.
gcloud run deploy fastapi-cloudrun-demo \
--source . \
--region asia-southeast1 \
--allow-unauthenticatedOn Windows PowerShell, use backticks instead of backslashes:
gcloud run deploy fastapi-cloudrun-demo `
--source . `
--region asia-southeast1 `
--allow-unauthenticatedAfter deployment finishes, Cloud Run will show a service URL. Open it in the browser and test:
https://YOUR_SERVICE_URL/
https://YOUR_SERVICE_URL/docs
https://YOUR_SERVICE_URL/healthz--source . first for learning. Use Docker + Artifact Registry when we want more control over the image build and release process.Method B: Deploy with Docker and Artifact Registry
This method gives more control. We 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:latestWindows 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.devWindows 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_URIWindows PowerShell
docker build -t $IMAGE_URI .
docker push $IMAGE_URI5. Deploy the Image to Cloud Run
macOS / Linux
gcloud run deploy $SERVICE \
--image $IMAGE_URI \
--region $REGION \
--platform managed \
--allow-unauthenticatedWindows PowerShell
gcloud run deploy $SERVICE `
--image $IMAGE_URI `
--region $REGION `
--platform managed `
--allow-unauthenticatedStep 6: Test the Cloud Run Service
After deployment, test the service URL in the browser:
https://YOUR_SERVICE_URL/
https://YOUR_SERVICE_URL/docs
https://YOUR_SERVICE_URL/healthzWe 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 $bodyExpected 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)"We can also open the Google Cloud Console:
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=productionUse Secret Manager for Sensitive Values
Do not hard-code passwords, API keys, or database credentials in the code or Dockerfile. Use Secret Manager or secure environment variable configuration.
.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 |
Optional: Add Pub/Sub Trigger
We 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-topicCreate a push subscription:
gcloud pubsub subscriptions create fastapi-sub \
--topic fastapi-topic \
--push-endpoint=https://YOUR_SERVICE_URL/hello \
--ack-deadline=10Publish a test message:
gcloud pubsub topics publish fastapi-topic --message '{"name":"PubSub"}' 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 the 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 the 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 productionConclusion
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 the 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: the 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
- Google Cloud Docs: Build and deploy a Python FastAPI web app to Cloud Run
- Google Cloud Docs: Deploy Cloud Run services from source code
- Google Cloud Docs: Cloud Run container runtime contract
- Google Cloud Docs: Configure containers for Cloud Run services
- Google Cloud Docs: Configure environment variables for Cloud Run services
- Google Cloud Docs: Transition from Container Registry to Artifact Registry
- Google Cloud Docs: Configure Docker authentication to Artifact Registry
- FastAPI Docs: FastAPI in Containers - Docker
- Google Codelabs: Hello Cloud Run with Python FastAPI

Comments
Post a Comment