Deploy a SvelteKit App on Google Cloud Run Always Free

Cloud Provider: gcp • Difficulty: intermediate Estimated Time: 60-120 minutes

What you’ll build

A production-ready SvelteKit application deployed to Google Cloud Run.

This recipe uses:

  • Cloud Run to host the app
  • Cloud Build to build the container image
  • Artifact Registry to store the image
  • Google-managed HTTPS on the generated Cloud Run URL

The result is a serverless deployment that can scale down to zero when nobody is using it.

Why this recipe matters

This is one of the cleanest ways to host a modern web app on GCP without managing virtual machines.

You get a real HTTPS endpoint, automatic scaling, low operational overhead, and a free-tier model that is friendly to small learning projects, demos, and personal sites.

It is also a strong contrast to the OCI VM recipe:

  • OCI shows the classic VM + Nginx path
  • GCP Cloud Run shows the modern container + serverless path

Why this fits the free tier

Cloud Run includes an always-free monthly allowance for requests and compute, and Cloud Build includes a daily free build allowance for small projects.

That makes this pattern a good fit for lightweight web apps, demos, internal tools, and low-traffic public sites.

What you need before you start

Accounts and access

  • A Google Cloud account
  • A Google Cloud project
  • Billing enabled on the project
  • Permission to create Cloud Run, Cloud Build, Artifact Registry, and IAM resources

Local software

  • Node.js 20 or newer
  • Git
  • Google Cloud CLI installed
  • A working local copy of your SvelteKit app

Assumptions

This recipe assumes:

  • your SvelteKit app already works locally
  • you are comfortable using the terminal
  • you want a production deployment path with minimal infrastructure management
  • you are fine with the app running on a generated Cloud Run URL first, with optional custom domain mapping later

High-level architecture

Your laptop
  |
  | source code
  v
Cloud Build
  |
  | builds container image
  v
Artifact Registry
  |
  | deploy image
  v
Cloud Run service
  |
  | HTTPS
  v
Public web app

Step 1 - Confirm the SvelteKit app works locally

Before deploying anything, make sure the app builds and runs locally.

From your project root:

npm install
npm run build
npm run preview

Open the preview URL and confirm:

  • the homepage loads
  • routing works
  • assets load correctly
  • there are no obvious hydration or runtime errors

If the app is broken locally, fix that first.

Step 2 - Confirm adapter configuration for production

For Cloud Run, use the Node adapter in svelte.config.js.

Example:

import adapter from '@sveltejs/adapter-node';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';

/** @type {import('@sveltejs/kit').Config} */
const config = {
  preprocess: [vitePreprocess()],
  kit: {
    adapter: adapter()
  }
};

export default config;

Then rebuild locally:

npm run build

Step 3 - Create a Dockerfile

In the project root, create a file named Dockerfile with this content:

FROM node:20-slim AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-slim
WORKDIR /app
COPY --from=build /app/package*.json ./
RUN npm ci --omit=dev
COPY --from=build /app/build ./build
ENV PORT=8080
ENV HOST=0.0.0.0
CMD ["node", "build"]

This builds the app in one stage and runs only the production output in the final image.

Step 4 - Create a .dockerignore file

Create a file named .dockerignore in the project root:

node_modules
.svelte-kit
build
.git
.vscode
.env
.env.*
npm-debug.log

This keeps the build context smaller and cleaner.

Step 5 - Authenticate with Google Cloud

In a terminal:

gcloud auth login
gcloud config set project YOUR_PROJECT_ID

Confirm the active project:

gcloud config get-value project

Step 6 - Enable required Google Cloud services

Enable the services this recipe uses:

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

Step 7 - Deploy directly from source

From the project root, deploy with one command:

gcloud run deploy freetierlife   --source .   --region us-central1   --allow-unauthenticated

This command does several things:

  • uploads source to Google Cloud
  • builds a container image with Cloud Build
  • stores the image in Artifact Registry
  • deploys the image to Cloud Run
  • returns a live HTTPS service URL

Step 8 - Test the generated Cloud Run URL

After deployment, Google Cloud will print a service URL.

Open it in the browser and verify:

  • homepage loads
  • routes work
  • assets load
  • the app responds over HTTPS

You can also test it with curl:

curl YOUR_CLOUD_RUN_URL

Step 9 - Set environment variables if needed

If your app needs a production origin, update the service environment variables:

gcloud run services update freetierlife   --region us-central1   --update-env-vars ORIGIN=YOUR_CLOUD_RUN_URL

If you later map a custom domain, change ORIGIN to that domain.

Step 10 - Verify logs

If something fails, inspect Cloud Run logs.

View logs in the console or run:

gcloud run services logs read freetierlife --region us-central1

Look for:

  • startup failures
  • missing environment variables
  • build failures
  • runtime exceptions

Step 11 - Understand Cloud Run scaling behavior

Cloud Run automatically scales based on inbound traffic.

For small projects, the big win is that it can scale down to zero, which means you do not pay for an always-on VM just to keep a low-traffic site alive.

That is one of the main reasons this recipe is interesting for FTL.

Step 12 - Optional custom domain mapping

Once the base deployment works, you can add a custom domain to the Cloud Run service.

In the console or with the CLI, map your domain and then create the DNS records Google requests.

If your domain is already managed elsewhere, that is fine — you only need to add the required DNS records.

Step 13 - Optional production hardening

Once the basic deployment works, common next steps include:

  • adding a custom domain
  • storing secrets in Secret Manager
  • pinning a specific region
  • tightening IAM permissions
  • adding a CI/CD workflow from GitHub

Do not do all of that on day one unless you have to. First, get the deployment stable.

Step 14 - Validation checklist

  • local build works
  • Dockerfile builds logically
  • gcloud run deploy succeeds
  • Cloud Run URL responds over HTTPS
  • homepage loads correctly
  • routes work
  • logs are clean or explain errors clearly
  • environment variables are set correctly if needed

Step 15 - Compare this recipe to the OCI VM recipe

This recipe and the OCI SvelteKit VM recipe solve the same basic problem in different ways.

OCI VM recipe strengths:

  • classic infrastructure model
  • full control over server configuration
  • easy to colocate other services on the same host

Cloud Run recipe strengths:

  • no VM management
  • autoscaling
  • scale-to-zero
  • built-in HTTPS on the generated URL

That is one reason both recipes belong on FTL.

Step 16 - What to do next

Once this works, you can build on it in several directions:

  1. add a custom domain
  2. connect a managed database or API
  3. build a shared deployment workflow from GitHub
  4. compare cost and operational tradeoffs against OCI hosting

Source links