Building This Website with AI — What Actually Happened
I built this website in a single session with Claude Code as my pair programmer. Not "AI helped me write some code" — I mean I drove the entire thing through conversation. Here's what actually happened, including the parts that didn't work.
The Stack
- Next.js 16 — app router, static generation for blog posts
- Tailwind CSS — styling
- GCP Cloud Run — hosting (serverless, scales to zero)
- Cloud Build — CI/CD pipeline
- Artifact Registry — Docker image storage
- Cloudflare — domain, DNS proxy, and CDN
Why Cloud Run
The short answer: it costs nothing for a low-traffic personal site.
Cloud Run scales to zero when there's no traffic. A personal site gets a few hundred requests a month — that's a few hundred vCPU-seconds, well inside the permanent free tier (180,000 vCPU-seconds/month). I've been running this for weeks and the Cloud Run line on my GCP bill is $0.00.
The alternatives I considered:
- Cloud Run with
--min-instances=1— eliminates cold starts, but that instance runs 24/7, adding ~$3–5/month. Not worth it for a blog. - GCP Global HTTPS Load Balancer — the fully native way to attach a custom domain to Cloud Run. Costs ~$18/month just for the load balancer, more than the rest of the stack combined. Hard no.
- GKE / Compute Engine — more control, but you pay for idle nodes. Overkill for a static-ish website.
- Vercel / Netlify — simpler setup, but I wanted to stay in GCP and keep the infrastructure skills current.
Cloud Run also gave me container-based deploys, which means the same image could run locally, in staging, or in prod without any environment-specific tooling changes.
Why Cloudflare
Cloudflare solved two problems for free that would have cost money elsewhere.
Problem 1: Custom domain on Cloud Run. GCP's native domain mapping is deprecated and doesn't work in australia-southeast1. The alternative — a Global HTTPS Load Balancer — costs $18/month. Cloudflare's proxy sits in front of my Cloud Run URL, handles SSL termination, and rewrites the Host header so Cloud Run recognises the request. Zero cost.
Problem 2: Domain registration. Cloudflare Registrar sells domains at cost with no markup — ruokai.me was ~$10/year, WHOIS privacy included by default. Most registrars charge extra for privacy.
On top of that, Cloudflare's CDN caches static assets at edge locations globally, so page loads are fast regardless of where Cloud Run's container wakes up. There's also basic DDoS protection out of the box.
The combination of Cloudflare (free) + Cloud Run (free tier) means the entire hosting stack currently costs ~$10/year — just the domain.
What I Asked AI to Do
I started with a blank Next.js project and worked through everything conversationally:
- Set up the GCP infrastructure — Cloud Build pipeline, Artifact Registry, IAM permissions
- Write the deployment scripts and Makefile
- Add a billing protection Cloud Function that auto-disables billing if costs exceed budget
- Add SEO — sitemap, robots.txt, Open Graph tags, JSON-LD structured data
- Update the site content from my LinkedIn export
- Help me navigate buying a domain and connecting it to Cloud Run
I didn't write a single line of infrastructure code myself.
What Worked Well
Infrastructure as conversation. Instead of reading through GCP docs, I described what I wanted and got working gcloud commands back. The billing stop function was a good example — it deployed a Cloud Function, created a Pub/Sub topic, and linked it to my billing budget, all wired together automatically.
Catching my own gaps. When I asked "how much will this cost?", the answer wasn't just a number — it surfaced that Cloud Run has a permanent free tier, that Artifact Registry images accumulate over time, and that a Global Load Balancer would cost ~$18/month (more than the site itself). That kind of holistic answer is hard to get from docs alone.
SEO in one pass. Adding sitemap.ts, robots.ts, Open Graph metadata, and JSON-LD structured data to a Next.js app took one conversation. It read the Next.js 16 docs from node_modules, used the right APIs, and verified everything with a build check.
What Broke
Turbopack. The dev server kept causing the browser to endlessly refresh. Turned out to be a Turbopack panic — a bug in Next.js 16's new bundler. The fix was switching to --webpack for local dev. Claude diagnosed it by reading the dev server output logs directly.
Cloud Run domain mapping. My first instinct was to use GCP's native domain mapping feature. It doesn't work in australia-southeast1 — the region I deployed to. We tried it anyway, got a 501 error, and pivoted to a Cloudflare Worker that proxies requests to the Cloud Run URL instead. Free, and works fine.
LinkedIn profile fetching. I asked Claude to read my LinkedIn profile directly from the URL. LinkedIn blocks automated fetches. The workaround was downloading my LinkedIn data export (a zip file), which gave clean CSVs for profile, positions, education, skills, and certifications.
On Using AI This Way
A few honest observations:
It's fast, but you need to stay engaged. When I just approved things without reading them, I ended up with mismatched flags (--no-turbopack instead of --webpack) and had to debug. When I understood what was being proposed, the session moved much faster.
It's good at knowing what it doesn't know. When something was region-specific or version-specific, it would try the command, read the error, and adapt. That loop — try, fail, diagnose, retry — happened several times and mostly resolved without me having to look anything up.
Documentation reading is underrated. The AGENTS.md in this project tells Claude to read the Next.js docs from node_modules before writing any code. That one instruction prevented several version-mismatch bugs.
The billing stop function is the most important thing here. Cloud Run scales to zero and the free tier covers a personal site easily, but mistakes happen. Having a function that cuts off billing if costs spike is the kind of safety net that takes 10 minutes to set up and could save hundreds of dollars.
What's Next
The site is live. The pipeline works. Now I need to actually write things worth reading.
That part, AI can't do for me.