Skip to content
Docs

How to migrate from Google Cloud Run to Vercel

Migrate from Cloud Run to Vercel by copying your Dockerfile to Dockerfile.vercel, aligning the PORT contract, moving secrets, and mapping jobs to cron.

Ben SabicContent Engineer

To migrate from Google Cloud Run to Vercel, copy your Dockerfile to Dockerfile.vercel at the project root and deploy. Vercel detects the file, builds the image, pushes it to Vercel Container Registry, and routes all traffic to your container, which runs as a Vercel Function on Fluid compute. The rest of the migration is contract alignment: the listening port, secrets, shutdown handling, and scheduled work.

This guide covers whether your service is a fit, how Cloud Run concepts map to Vercel, the migration steps, and what doesn't carry over.

Copy link to headingShould your app move?

Cloud Run services are the closest analog to Vercel's container model: both run stateless HTTP containers that scale to zero. If your service already lives inside that contract, the move is mostly mechanical, and you run it with less Google Cloud surface area to operate: no Artifact Registry repositories, IAM bindings, or Cloud Build triggers to maintain.

A service is a good fit when it:

  • Serves HTTP requests and keeps no state between them
  • Already tolerates scaling to zero, with no min-instances dependency
  • Treats the filesystem as scratch space, which Cloud Run enforces anyway with its in-memory filesystem
  • Runs scheduled work over HTTP rather than as long batch processes

It's a poor fit when it depends on Cloud Run jobs for long run-to-completion batch work, on warm instances held by min-instances, on GPUs, or on fixed egress IPs, since Secure Compute and Static IPs aren't yet supported with custom container images. If you're still deciding where a given workload belongs, the guide to matching your Docker workload to a platform walks through the decision.

Copy link to headingHow do Cloud Run concepts map to Vercel?

Cloud RunVercel
Service (stateless HTTP container, scales to zero by default)Container image running as a Vercel Function on Fluid compute
Artifact Registry (LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/PATH:TAG)Vercel Container Registry (vcr.vercel.com/team-slug/project-slug/my-repository:tag)
gcloud run deploy SERVICE --image IMAGE_URLvercel deploy, or push to a connected Git repository
PORT env var injected into the container, default 8080HTTP server on port 80 by default; override with a PORT environment variable in project settings
Secret Manager secrets as env vars or mounted volumesSecret environment variables in project settings
Cloud Run jobsCron jobs sending an HTTP GET to an endpoint in your service
SIGTERM, then SIGKILL after 10 secondsSIGTERM with a 30-second grace period before forced termination
Source deploys (gcloud run deploy without --image, Cloud Build)Framework detection for Express, FastAPI, Flask, Django, Go, Next.js, and more

TLS looks the same from inside the container: Cloud Run terminates TLS and proxies plain HTTP, and Vercel expects a plain HTTP server too.

Still choosing a destination? Compare Cloud Run alternatives by workload before starting the migration.

Copy link to headingMigrate a Cloud Run service in 7 steps

Copy link to heading1. Copy your Dockerfile to Dockerfile.vercel

Place a Dockerfile.vercel (or Containerfile.vercel) at the root of your project. Vercel auto-detects it, adds a rewrite that routes all traffic to the container image, and builds and pushes the image during the build step. The Dockerfile you already deploy to Cloud Run is the starting point; the contract differences are the port and the shutdown timing, handled below.

If your service deployed from source on Cloud Run (running gcloud run deploy without --image), you may not need a Dockerfile at all. Vercel's framework detection deploys Express, FastAPI, Flask, Django, Go, Next.js, and many other frameworks with minimal configuration.

Copy link to heading2. Set the port

Cloud Run injects a PORT environment variable, 8080 by default, and requires your server to listen on 0.0.0.0. Vercel expects the container to open an HTTP server on port 80 by default, and you can override that by setting a PORT environment variable in project settings. If your code already reads PORT at startup, set the variable to 8080 in project settings and it runs unchanged.

Copy link to heading3. Move Secret Manager secrets to environment variables

Cloud Run exposes Secret Manager secrets as environment variables resolved at instance startup, or as mounted volumes fetched on read, wired with flags like --set-secrets=ENV_VAR_NAME=SECRET_NAME:VERSION. On Vercel, recreate each one as a Secret environment variable in project settings. Secret values are write-only after you save them, which makes them appropriate for credentials. Google recommends pinning secrets to a version rather than latest, so copy the value of the pinned version you serve today. Secrets your code reads from a volume path need a code change to read from the environment instead; there are no mounted volumes on Vercel.

Copy link to heading4. Update shutdown handling

Both platforms send SIGTERM before stopping an instance. Cloud Run starts a 10-second period before SIGKILL; Vercel gives a 30-second grace period before forced termination. A shutdown handler written for Cloud Run gains time rather than losing it, but the period is fixed, so cleanup that can't finish in 30 seconds still needs to move out of the shutdown path. Scale-in triggers after 5 minutes without traffic in production, and after 30 seconds in preview deployments.

Copy link to heading5. Replace Cloud Run jobs with cron jobs

Cloud Run jobs run tasks to completion, must not listen on a port, and exit 0 on success. Vercel has no run-to-completion container equivalent, so scheduled jobs change shape: expose the task as an HTTP endpoint in your service, then add the schedule and path to vercel.json as a cron job. Vercel triggers each run with an HTTP GET request to the configured path on the production deployment. Requests carry the vercel-cron/1.0 user agent and an x-vercel-cron-schedule header, and schedules always run in UTC. Batch tasks that exceed Vercel's function duration limits should stay on Cloud Run.

Copy link to heading6. Test locally with vercel dev

Run vercel dev to start the container on your machine. It requires the docker CLI and a running Docker daemon. Confirm the port change here: the server should come up on the port you configured. You can also send your process a termination signal yourself to exercise the shutdown handler before deploying.

Copy link to heading7. Deploy and cut over

Deploy with vercel deploy or by pushing to a connected Git repository; every push gets a preview deployment, so you can test the migrated service on a real URL before production. During the build, the image is pushed to Vercel Container Registry, a Docker-compatible registry at vcr.vercel.com with repositories private by default. Pushed images are optimized into a precompiled snapshot format that reduces startup time on Fluid compute. Once the preview checks out, ship it to production and point your domain at Vercel.

Copy link to headingWhat doesn't map from Cloud Run

  • Cloud Run jobs. There is no run-to-completion container on Vercel: scheduled work becomes cron jobs invoking HTTP endpoints, and batch tasks longer than function duration limits should stay on Cloud Run.
  • Min instances. Vercel's container docs define no setting that holds instances warm; scale-down after idle is automatic. The precompiled snapshot format reduces startup time instead.
  • Persistent and mounted volumes. Cloud Run's filesystem is in-memory and non-persistent, so most services lose nothing here, but any volume mounts, including secret volumes, must become environment variables or external storage. Databases and caches are available through the Vercel Marketplace.
  • Fixed egress IPs. Secure Compute and Static IPs aren't yet supported with custom container images. If a downstream system allowlists your Cloud Run egress, plan a different access path before cutting over.
  • The 10-second shutdown window. It becomes 30 seconds on Vercel: more room, but fixed.
  • Sidecar containers. Cloud Run can run additional containers next to the ingress container in one instance. On Vercel, a function runs the single image built from its Dockerfile, so fold sidecar work such as proxies or log forwarding into the main image, or split it into its own service with its own Dockerfile.vercel in the same project, routed by rewrites.

Copy link to headingFrequently asked questions

Copy link to headingDoes Vercel run my container the way Cloud Run does?

Mostly, yes. Cloud Run and Vercel both run stateless containers that serve HTTP and scale to zero, so the runtime contract carries over. The differences are details: Vercel expects your server on port 80 unless you set a PORT environment variable in project settings (Cloud Run defaults to 8080), the SIGTERM grace period is 30 seconds instead of 10, and standard Vercel Functions limits on size, memory, and duration apply.

Copy link to headingWhat replaces min instances on Vercel?

Nothing does. Vercel's container docs define no setting that holds instances warm: a production function scales down after 5 minutes without traffic, and a preview deployment after 30 seconds. Vercel instead optimizes pushed images into a precompiled snapshot format to reduce startup time on Fluid compute.

Copy link to headingWhat happens to my Cloud Run jobs?

Cloud Run jobs need a new shape, because Vercel has no run-to-completion container equivalent. Scheduled work becomes a Vercel cron job: an HTTP endpoint in your service that Vercel calls with a GET request on a schedule you define in vercel.json, always in UTC. Batch tasks that run longer than Vercel's function duration limits should stay on Cloud Run.

Copy link to headingCan I keep my images in Artifact Registry?

You can keep images in Artifact Registry for other consumers, but the image Vercel serves lives in Vercel Container Registry: the build step builds your Dockerfile.vercel and pushes the result to VCR automatically. VCR is Docker-compatible, so if you want existing images copied over, docker buildx imagetools create moves multi-platform images without pulling layers locally, and repositories are private by default.

Copy link to headingHow do Secret Manager secrets move to Vercel?

Secret Manager secrets become a Secret environment variable in Vercel's project settings, which matches how Cloud Run exposes Secret Manager secrets as environment variables resolved at instance startup. Secrets your code reads from a mounted volume need a small code change to read from the environment instead, because Vercel functions have no mounted volumes.

More Vercel Services guides