Skip to main content

Develop, test & deploy on Cloud Run

Exam guide§2.1

Before an app goes live on Cloud Run there is a short arc: decide whether it fits, turn source into a running container, honor the runtime contract, pick an execution environment, reach your data, and test it locally. This page walks that arc. The runtime states a container passes through (starting, idle, shutting down) are on Cloud Run container lifecycle.

Is your app a good fit for Cloud Run?​

NumbersFit checklist - every criterion must be true
  • Serves requests, streams, or events over HTTP, HTTP/2, WebSockets, or gRPC - or runs to completion as a job.
  • Needs no local persistent disk - a local ephemeral (in-memory) or network file system is enough.
  • Is built to run as multiple instances simultaneously (stateless, horizontally scalable).
  • Needs at most 8 CPU and 32 GiB memory per instance.
  • Is containerized, or written in Go, Java, Node.js, Python, or .NET (so it can be containerized for you), or you can otherwise containerize it.
GotchaAll of the criteria, not any

An app is a good fit only if it meets every criterion. The 8 CPU / 32 GiB ceiling and the no persistent local disk rule are the two that most often disqualify an otherwise-portable app.

From source to a running service​

Two paths get your code to a running service, and both end at a container Cloud Run runs:

  • Container path - you build and package the image yourself (any language), push it to Artifact Registry, then deploy. This is the deploy loop on the section overview.
  • Source-based path - skip the Dockerfile. Deploy your source and let Cloud Run build the image for you with Buildpacks.
</>Source codeBuildpacksContainer imageCloud Run service
Source-based deploy: with no Dockerfile, Cloud Run uses Buildpacks to build your source into a container image and deploy it - build and deploy are a single `gcloud run deploy --source` step.

Source-based deploy supports Go, Node.js, Python, Java, .NET Core, and Ruby. If a Dockerfile is present it is used; if not, Buildpacks packages your app and its dependencies into a container image.

GotchaBuilding a container image is optional

You never have to write a Dockerfile. gcloud run deploy --source (or the equivalent in Cloud Code) hands your source to Buildpacks, which produces the image and deploys it in one step.

Container runtime contract​

Whatever language or base image you use, the container must honor Cloud Run's runtime contract. Executables must be compiled for Linux 64-bit; images may be Docker Image Manifest V2 (schema 1 or 2) or OCI format.

NumbersService contract
  • Listen for requests on the correct port - default 8080, configurable via $PORT.
  • Send a response within the request timeout (max 1 hour), including container startup time, or the request ends with a 504.
  • Do not implement TLS yourself.
NumbersJob contract
  • Exit with code 0 on success, a non-zero exit code on failure.
  • Do not listen on a port or start a web server - jobs do not serve requests.
GotchaCloud Run terminates TLS for you

Never implement transport-layer security in your container. Cloud Run terminates TLS for HTTPS and gRPC, then proxies plain HTTP/1 or gRPC to your container. For HTTP/2, handle requests in HTTP/2 cleartext (h2c).

Execution environments​

Cloud Run runs services and jobs in one of two execution environments. Services default to first generation and can be switched; jobs always use second generation and cannot be changed.

First generationSecond generation
Default forServices (changeable)Jobs (cannot be changed)
Cold startFaster - shorter cold startsSlower cold starts
Linux compatibilityEmulates most, but not all, system callsFull Linux - all syscalls, namespaces, cgroups
Network file systemNot supportedSupported (required for NFS / Filestore)
CPU & networkStandardFaster CPU, faster network under packet loss
Best whenScale out fast, spiky or infrequent traffic, < 512 MiB memorySteady traffic, CPU-intensive work, NFS needed, or gen-1 syscall gaps
GotchaSecond generation is required for network file systems

To mount a network file system (Filestore, or Cloud Storage via Cloud Storage FUSE) on a service, you must deploy it in the second generation environment. Jobs already run on gen 2.

File system and data storage access​

ContainerClient libraryApplication codeIn-memory file systemephemeralpersistentCloud data storageCloud StorageMemorystoreCloud SQLFilestoreFirestoreBigQuerySpanner
A Cloud Run container writes to a writable in-memory (ephemeral) file system that vanishes when the instance stops. For data that must persist, connect to Google Cloud data storage services.

Every container gets a writable in-memory file system. Writes consume the instance's allocated memory and do not persist past the instance - treat it as a per-request cache or scratch space, not storage.

For durable data:

  • Standard file semantics - use Filestore or another self-managed network file system, which needs the second generation environment. Cloud Storage FUSE mounts a bucket as a file system.
  • No file system needed (simplest) - use cloud data storage client libraries to talk directly to Firestore, Cloud SQL, Spanner, Cloud Storage, Memorystore, and BigQuery.
NumbersIn-memory file system facts
  • Writable, backed by the instance's allocated memory.
  • Not persisted - data is gone when the instance stops.
  • Default 512 MiB memory per instance (writes count against it); configurable up to 32 GiB.

Local development and testing​

Run and test the container on your machine before deploying. Three options:

Cloud Code​

Cloud Code is a set of IDE plugins for building, deploying, and integrating apps with Google Cloud.

FactsWhat Cloud Code gives you
  • Plugins for VS Code, IntelliJ, and Cloud Shell.
  • Create and deploy Kubernetes and Cloud Run apps from sample templates.
  • Run and debug locally in a Cloud Run emulator (configure CPU/memory, env vars, Cloud SQL connections).
  • Log streaming and viewing.

Local testing options​

Cloud Codegcloud CLIDocker
HowCloud Run emulator inside your IDELocal dev environment that emulates Cloud Rundocker run the image locally
Builds withThe emulatorDockerfile if present, else BuildpacksYour Dockerfile
Auto-rebuild on changeYesYesNo
Test URLURL shown in IDE outputhttp://localhost:8080/http://localhost:<PORT>/
Best forIDE-integrated run + debugCLI workflowYou already use Docker

Recap​

NumbersNumbers to remember
  • Resource ceiling: 8 CPU, 32 GiB memory per instance.
  • Default port: 8080 (configurable via $PORT).
  • Request timeout: up to 1 hour, else a 504.
  • Job result: exit 0 = success, non-zero = failure.
  • Network file system (Filestore / Cloud Storage FUSE) requires the second generation environment.
DECISIONContainer image or source-based deploy?

Build the image yourself when you need a specific base image or full control of the build. Choose source-based (--source, Buildpacks) when you want Cloud Run to build and deploy from source in one step - supported for Go, Node.js, Python, Java, .NET Core, and Ruby.

Pick this when: Dockerfile or full control over the build = build the image yourself; no Dockerfile, let Google build it = source-based with Buildpacks