Deploying My .NET Blog Site to Google Cloud Run

Deploying My .NET Blog to Google Cloud Run

I moved my personal blog from a slow host to Google Cloud Platform because I wanted faster load times and some real cloud deployment experience. Here is how it went, warts and all.

Setting up the project

I created a new project in GCP and enabled the services I needed:

  • Cloud Run for hosting the container
  • Artifact Registry to store Docker images
  • IAM roles so my account could actually deploy

I also installed the Google Cloud SDK and checked I could talk to GCP from the command line.

Getting the app ready

My blog is a .NET app, so the first step was making sure it would run inside a container. The gotcha: Cloud Run expects your app to listen on port 8080 (or whatever is in the PORT environment variable).

  • My app was originally set to run on port 5000 for no good reason.

I updated Program.cs so it uses the provided port:

var port = Environment.GetEnvironmentVariable("PORT") ?? "8080";
app.Urls.Add($"http://0.0.0.0:{port}");
app.Run();

Before pushing anything, I checked the container locally:

docker build -t myblog-app .
docker run -p 8080:8080 -e PORT=8080 myblog-app

Everything worked at http://localhost:8080.

Pushing to Artifact Registry

I originally tried pushing to Container Registry (GCR) but ran into 403 permission errors on Windows. I fought with OAuth and IAM for a while, then switched to Artifact Registry to get unstuck:

docker tag myblog-app europe-west2-docker.pkg.dev/my-blog-website-470819/myblog-app-repo/myblog-app:latest
docker push europe-west2-docker.pkg.dev/my-blog-website-470819/myblog-app-repo/myblog-app:latest

Deploying to Cloud Run

Once the image was in Artifact Registry, deployment was straightforward:

gcloud run deploy myblog-app \
  --image europe-west2-docker.pkg.dev/my-blog-website-470819/myblog-app-repo/myblog-app:latest \
  --platform managed \
  --region europe-west2 \
  --allow-unauthenticated \
  --min-instances 1

Cloud Run handles scaling, HTTPS, and keeping instances warm if you want that.

After a few minutes, the blog was live.

Cost tweaks

I noticed it was costing around 9p for 12 hours with one instance always running. That is tiny, but it adds up if you leave it on for months.

  • CPU and memory: I dropped the instance size from 1 vCPU / 512MB to 0.25 vCPU / 256MB. The blog is light, so it did not need the bigger size.
  • Minimum instances: If I set it to zero I save money, but the first request after idle gets a cold start. Keeping one small instance warm gives me faster load times for a small baseline cost.

Right now I am experimenting with the best balance.

What I learned

  • Port config matters: Cloud Run provides $PORT and you need to bind to it.
  • Local testing helps: running the container locally saved me a lot of headache.
  • Artifact Registry is easier: less OAuth pain on Windows (for me, anyway).

Next steps

I want to:

  • Set up a custom domain
  • Trim the Docker image size to speed up cold starts
  • Add logging and monitoring so I can see traffic and errors properly

Overall this was fun, and my blog is definitely quicker now.

Comments

No comments yet.

Add a comment