FastAPI backend for my personal resume site (rubiayenyeinsan.vercel.app). Tracks unique visitors and "love" votes, backed by Firestore and deployed to Cloud Run via Cloud Build.
Part of the Cloud Resume Challenge on GCP.
Client ──► FastAPI (Cloud Run) ──► Firestore
GitHub ──(push to main)──► Cloud Build ──► Artifact Registry ──► Cloud Run
main triggers Cloud Build, which builds a Docker image, pushes it to Artifact Registry, deploys to Cloud Run, and cleans up old images.FastAPI is simple, easy, and fast to implement since the api logic for this project is not complicated.FireStore as a database since the project would mainly use the read/write, which stays within the free tier of daily 50K reads, and 20K writes, and I also delete the old IP with a cron job by calling the api endpoints(/resume/visitors/cleanup) with GitHub Actions which is not exceeded over a free tier of daily 20K deletesCI/CD as a Cloud Build and Artifact Registry to stay within the Google Cloud free tier, the pipeline includes a cleanup step that removes old container images to keep storage usage below the free limitCloud Run for hosting my backend api with cost efficiency and reliability, since Cloud Run serverless doesn't run the service if there is no request call, and a monthly free tier for CPU (per vCPU-second) and Memory (per GiB-second)All routes are prefixed with /resume and rate-limited to 2 requests per 5 seconds.
| Method | Path | Description |
|---|---|---|
| POST | /resume/visits | Record the caller's IP as a visitor |
| GET | /resume/visitor-status | Aggregate stats (total visitors, love count) |
| POST | /resume/love-votes | Increment the love counter |
| DELETE | /resume/visitors/cleanup | Delete the unused old IPs from the firstore |
.
├── main.py # FastAPI app + CORS
├── api/
│ ├── visitors.py # /resume/visits, /resume/visitor-status
│ └── loveVotes.py # /resume/love-votes
├── config/firestoreDb.py # Firestore client
├── Dockerfile
├── docker-compose.yml # local dev (builds from source)
├── docker-compose-prod.yml # pulls the deployed image from AR
├── cloudBuild.yaml # Cloud Build pipeline
├── gcp_setup.sh # one-time GCP bootstrap
└── terraform/ # infra as code
Prerequisites: Python 3.12, Docker, a GCP service account with Firestore access saved as serviceAccountKey.json.
# 1. Install deps
pip install -r requirements.txt
# 2. Run with Docker (recommended — matches prod)
docker compose up --build
# Or run directly
fastapi dev
The API is available at http://localhost:8000. Interactive docs at /docs.
Pushing to main automatically builds and deploys via Cloud Build. Manual setup:
# One-time: enable APIs, create TF state bucket
./gcp_setup.sh
# Connect the GitHub repo in Cloud Build → Triggers → Manage repositories
# Provision infra
cd terraform && terraform init && terraform apply
Changes under terraform/** on main trigger a separate terraform apply build.
asia-southeast1