It’s a common and recommended practice to migrate your App Engine services to Cloud Run, as Google’s own documentation states:
“Cloud Run is the latest evolution of Google Cloud Serverless, building on the experience of running App Engine for more than a decade.”
WHY to Migrate From App Engine to Cloud Run
- App Engine Flexible can’t scale to zero; Cloud Run scales to zero automatically, saving idle costs
- App Engine standard doesn’t support container images; Cloud Run supports both container and source deployments
- App Engine can’t use sidecar containers; Cloud Run allows sidecars for proxies, logging, etc.
- App Engine lacks granular CPU/memory control; Cloud Run lets you configure exact resources per service
- App Engine’s secret access requires client libraries; Cloud Run injects secrets directly via env vars or volumes
- App Engine doesn’t support global HTTP load balancing; Cloud Run integrates with multi-region global load balancing
- App Engine standard lacks per-service IAM access; Cloud Run supports fine-grained IAM control per revision
…and many more
Cloud Run serves applications more effectively than traditional App Engine by offering greater flexibility, portability, and control. It supports any language via containers, enables scale-to-zero for cost efficiency, and provides fine-grained resource allocation. Unlike App Engine, it integrates natively with IAM, Cloud Armor, and Secret Manager, and supports modern DevOps workflows with seamless CI/CD integration. Its support for VPC connectivity, global load balancing, provides concurrency requests up to 80 which is just 10 in App Engine and sidecar containers makes it a more robust and cloud-native platform for modern application development.
First Step
Before starting the migration, we conduct a discovery phase that involves questions like what components are part of the current setup, how services interact and depend on each other, how data is stored, accessed, and backed up, and what the existing network topology looks like—including VPCs, subnets, firewalls, and peering.
We also assess IAM roles and access policies, CI/CD pipelines, monitoring and logging systems, third-party integrations, and any compliance or security requirements such as PCI-DSS or HIPAA. This helps define the target architecture, identify potential risks, and plan a seamless cutover strategy.
Getting Started
We begin by enabling the Cloud Run and Artifact Registry APIs, if they aren’t already enabled. Next, we check for a user-managed service account specific to Cloud Run. If it doesn’t exist, we create one and assign the relevant IAM permissions—such as access to Service Accounts, Cloud SQL, Secret Manager, etc.—based on application requirements.
Migrating from App Engine Standard
Applications in App Engine Standard are deployed directly from source code, so there’s no need to containerize them before deploying. The same approach can be leveraged in Cloud Run, even though it runs containerized images. Cloud Run uses Buildpacks and Cloud Build to automatically build a container image from source code.
If the source code already contains a functional Dockerfile
, Cloud Run uses it directly; otherwise, we can specify one.
- We deploy the Cloud Run from the source code with this following gcloud command and press ENTER:
gcloud run deploy NAME_OF_CLOUD_RUN --source PATH_OF_SOURCE_CODE \
--allow-unauthenticated \
--set-secrets ENV_NAME=SECRET_NAME:latest \
--set-env-vars ENV_NAME="VALUE"
--source:
Points to the application’s source code
--allow-unauthenticated:
Allows public access to the Cloud Run service
--set-secrets:
Maps an environment variable to a secret stored in Secret Manager
--set-env-vars:
Maps an environment variable to a value
We use different flags based on the requirements like –allow-authentication to keep the cloud run for authorised users, etc.
- After pressing ENTER, we will be prompted to enter the name of the service which is the Cloud Run service for the application.
- Next, if we are prompted to enable any required API we press y for Yes.
- Once that is done, a message will display with the name of the Cloud Run service as follows:
Service [your-cloud-run-service-name] revision [your-cloud-run-service-name-00000-xxx] has been deployed and is serving 100 percent of traffic. Service URL: https://sample.run.app
That indicates that we have successfully Migrated our App Engine Standard in Cloud Run.
Migrating from App Engine Flexible
Like Cloud Run, App Engine Flexible also supports both container-based and source-based deployments. We will see both the methods of deployments here:
Container based deployment:
We will already have access to the container image that was used by the App Engine Flexible.
- The images are stored inside a repository of Artifact Registry.
- Copy the image url / path.
- Run the following command:
gcloud run deploy NAME_OF_CLOUD_RUN --image IMAGE_URL \
--allow-unauthenticated \
--set-secrets ENV_NAME=SECRET_NAME:latest \
--set-env-vars ENV_NAME="VALUE"
--image →
This flag points at the image-url.
--allow-unauthenticated →
To allow all public access to the Cloud Run service
--set-secrets →
This maps an environment variable to a confidential value saved inside the secret manager without exposing it.
--set-env-vars →
This flag maps the environment variable with the value.
Source based deployment:
For deploying App Engine Flexible with help of its source, we will just follow the same step that we follow for Migrating App Engine Standard in Cloud Run.
And this is how you Migrate seamlessly from App Engine to Cloud Run!