Deploy apps to Google Cloud Run
This guide shows you how to deploy a Shopify app to Google Cloud Run, making your app available to merchants in production. Deploying to Google Cloud Run provides a scalable, managed hosting solution that handles the infrastructure so you can focus on your app's functionality.
This guide focuses on deploying a Shopify app to Google Cloud Run as it generalizes well to many common frameworks used to develop apps. Consult the deployment documentation if you'd rather deploy to another supported provider, or follow general guidelines to manually deploy elsewhere.
This tutorial demonstrates deploying a CLI-scaffolded React Router app to Google Cloud Run using simplified permissions and default service accounts. These settings work for learning and development but are likely over-permissive for production environments.
Review and adjust IAM permissions and service accounts to match your organization's security requirements before deploying production apps.
Anchor to What you'll learnWhat you'll learn
In this guide you'll learn how to do the following tasks:
- Retrieve sensitive configuration details about your Shopify app needed to deploy.
- Configure a Cloud Run project to host a Shopify app, including providing access to secrets specific to your Shopify app.
- Deploy your app's code to either a single or multiple regions on Google Cloud Run, depending on your needs.
- Test your deployment by reconfiguring your development store to use your new deployment.
References in this guide assume you're deploying a Shopify app built with Shopify React Router, which automatically handles key deployment requirements such as authentication, session management, webhook handling, and environment configuration.
Anchor to How it worksHow it works
When you deploy a Shopify app, you're making your code available to merchants. This involves:
- Moving your code from your local development environment to a hosting service
- Connecting your hosted app to Shopify through the Partner Dashboard
- Managing app extensions and configurations separately through app versions
Your hosting service manages the app's runtime environment and handles incoming requests through authenticated connections set up in the Partner Dashboard.
This guide focuses on the first step - moving code from your local development environment to a hosting service. You will set up a very basic project on Google Cloud Run, and deploy your app there.
Anchor to RequirementsRequirements
- Scaffold and then Build a Shopify app.
- Test your app functionality in a development environment
- Install the
gcloudCLI and authenticate with your account.
Anchor to Step 1: Gather app configurationStep 1: Gather app configuration
Gather the configuration details and credentials from your local development environment that you'll need to deploy your app to a hosting service.
-
Use the Shopify CLI to export the API token, API secret, and scopes from your Shopify app into the terminal session by running the following command:
eval $(shopify app info --web-env)shopify app info --web-env | Invoke-ExpressionMac/Linux (bash)
eval $(shopify app info --web-env)Windows (PowerShell)
shopify app info --web-env | Invoke-Expression -
Generate a
shopify.app.tomlconfiguration file for the version of your app you're going to deploy by running theapp config linkcommand below (if you haven't done so already):Terminal
shopify app config link
Anchor to Step 2: Create and connect a projectStep 2: Create and connect a project
In this step you will create project to act as a production workspace for this tutorial, as well as a service that will contain your actual running app code.
-
Create identifying environment variables for both the service and the project you will reuse throughout this tutorial:
export PROJECT_ID="my-app-name-project" && export SERVICE_NAME="my-app-name-service"$env:PROJECT_ID="my-app-name-project"; $env:SERVICE_NAME="my-app-name-service"Mac/Linux (bash)
export PROJECT_ID="my-app-name-project" && export SERVICE_NAME="my-app-name-service"Windows (PowerShell)
$env:PROJECT_ID="my-app-name-project"; $env:SERVICE_NAME="my-app-name-service" -
Create a project on Google Cloud Run:
Terminal
gcloud projects create $PROJECT_ID -
Connect your repository to the new project so that all the commands that follow in this tutorial will apply to the project:
Terminal
gcloud config set project $PROJECT_ID
Anchor to Step 3: Configure your projectStep 3: Configure your project
With the project created, you'll now need to configure the project with the necessary APIs and permissions to deploy and run your Shopify app.
-
Enable the required APIs for deployment (Cloud Run Admin API, Cloud Build API, Secret Manager API, and the Artifact Registry API), using the
services enablecommand:Terminal
gcloud services enable run.googleapis.com cloudbuild.googleapis.com \secretmanager.googleapis.com artifactregistry.googleapis.com -
Export your Google Cloud account email address to the environment variable
$USER_EMAIL:export USER_EMAIL="salma.ayad@example.com"$env:USER_EMAIL="salma.ayad@example.com"Mac/Linux (bash)
export USER_EMAIL="salma.ayad@example.com"Windows (PowerShell)
$env:USER_EMAIL="salma.ayad@example.com" -
Grant yourself the necessary roles by running the following command:
for role in "roles/run.developer" "roles/secretmanager.admin" "roles/iam.serviceAccountUser" "roles/cloudbuild.builds.editor"; dogcloud projects add-iam-policy-binding $PROJECT_ID --member="user:$USER_EMAIL" --role="$role"doneforeach ($role in @("roles/run.developer", "roles/secretmanager.admin", "roles/iam.serviceAccountUser", "roles/cloudbuild.builds.editor")) {gcloud projects add-iam-policy-binding $env:PROJECT_ID --member="user:$env:USER_EMAIL" --role="$role"}Mac/Linux (bash)
for role in "roles/run.developer" "roles/secretmanager.admin" "roles/iam.serviceAccountUser" "roles/cloudbuild.builds.editor"; do gcloud projects add-iam-policy-binding $PROJECT_ID --member="user:$USER_EMAIL" --role="$role" doneWindows (PowerShell)
foreach ($role in @("roles/run.developer", "roles/secretmanager.admin", "roles/iam.serviceAccountUser", "roles/cloudbuild.builds.editor")) { gcloud projects add-iam-policy-binding $env:PROJECT_ID --member="user:$env:USER_EMAIL" --role="$role" }
Anchor to Step 4: Manage secretsStep 4: Manage secrets
In order for your Shopify app to run successfully on Cloud Run, it needs access to the environment variables you defined at the beginning of this tutorial. This involves defining secrets for each variable, and configuring them so that can be accessed at runtime.
In Cloud Run, this means first granting access to a service account (in this case, the Compute Engine default service account) that will handle your deployments. Later in Step 5 you'll run another command that will actually make the variables accessible at runtime.
-
Create secrets in Secret Manager, using the API key and API secret environment variables you created earlier to create secrets for each of them:
echo $SHOPIFY_API_KEY | gcloud secrets create shopify-api-key --data-file=-echo $SHOPIFY_API_SECRET | gcloud secrets create shopify-api-secret --data-file=-API key
echo $SHOPIFY_API_KEY | gcloud secrets create shopify-api-key --data-file=-API secret
echo $SHOPIFY_API_SECRET | gcloud secrets create shopify-api-secret --data-file=-You can verify that the secrets were created successfully by running the command below:
Terminal
gcloud secrets list -
Run the command below to find and export the unique
PROJECT_NUMBERassociated with your project:PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")$env:PROJECT_NUMBER = gcloud projects describe $env:PROJECT_ID --format="value(projectNumber)"Mac/Linux (bash)
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")Windows (PowerShell)
$env:PROJECT_NUMBER = gcloud projects describe $env:PROJECT_ID --format="value(projectNumber)" -
Use
PROJECT_NUMBERto build the default service account email address associated with your project, and then give it access to the secrets you defined previously through the Secret Manager Secret Accessor role:Terminal
gcloud projects add-iam-policy-binding $PROJECT_ID \--member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \--role="roles/secretmanager.secretAccessor"
Anchor to Step 5: Deploy your app to Cloud RunStep 5: Deploy your app to Cloud Run
Deploy your app code to Cloud Run and configure it with the necessary environment variables to make it accessible online. Note that in the steps below, it's expected that the first deployment will fail.
This section outlines commands and requirements for deploying your Shopify app to a single region on Google Cloud Run. Alternatively, your actual requirements (for example, high availability or serving a global user base) may require you instead to deploy to multiple regions.
In that case, skip ahead to Deploy to multiple regions if you need multi-region support.
-
Define the region location your app will be deployed to. Run the command below, substituting the region example with one of your choosing:
export SERVICE_REGION="us-central1"$env:SERVICE_REGION="us-central1"Mac/Linux (bash)
export SERVICE_REGION="us-central1"Windows (PowerShell)
$env:SERVICE_REGION="us-central1" -
Deploy your code to the Cloud Run service you've defined by running the command below from your Shopify app's project directory:
Terminal
gcloud run deploy $SERVICE_NAME \--source . \--region $SERVICE_REGION \--set-secrets="SHOPIFY_API_KEY=shopify-api-key:latest,SHOPIFY_API_SECRET=shopify-api-secret:latest" \--set-env-vars="SCOPES=$SCOPES" \--port 3000 \--allow-unauthenticatedThis first deployment will fail with the error
The user-provided container failed to start, and this is expected. The Shopify app fails at runtime when it's unable to locate the expectedSHOPIFY_APP_URLenvironment variable, which you haven't yet defined.This variable corresponds to the unique URL of the service you've just deployed, but you couldn't access until it was deployed.
NoteBy default, Shopify React Router built apps run on port 3000 defined in their
Dockerfile, while the Cloud Run service uses port 8088. This behavior is overwritten in the passed--portflag in the command above.Update the command if you have overwritten this default port, or if your app has a different one.
The
--source .flag uses Google Cloud's buildpacks and Cloud Build to automatically build container images from your source code. An Artifact Registry Docker repository will be built automatically for you in yourSERVICE_REGION. For production deployments, consider building and submitting custom container images and passing the--imageflag instead. -
Run the following command to retrieve the service URL now that the service has deployed:
Command
SHOPIFY_APP_URL=$(gcloud run services list --filter="metadata.name:$SERVICE_NAME" --format="get(URL)") -
Rerun the deploy command again, now including the expected
SHOPIFY_APP_URLenvironment variable in that command:Command
gcloud run deploy $SERVICE_NAME \--source . \--region $SERVICE_REGION \--set-secrets="SHOPIFY_API_KEY=shopify-api-key:latest,SHOPIFY_API_SECRET=shopify-api-secret:latest" \--set-env-vars="SCOPES=$SCOPES,SHOPIFY_APP_URL=$SHOPIFY_APP_URL" \--port 3000 \--allow-unauthenticated -
Visit
SHOPIFY_APP_URLor run the command below to verify the service is functioning correctly:Command
gcloud run services describe $SERVICE_NAME --region $SERVICE_REGION
Anchor to Step 6: Set up a production databaseStep 6: Set up a production database
The default SQLite database used in local development won't work for your deployed app on Cloud Run long term. Sessions and data would be lost on every deployment.
To fix this, you'll set up a persistent PostgreSQL database using Cloud SQL and configure your app to use it in production while keeping SQLite for local development.
-
Create a
prisma/schema.prod.prismafile for your production schema with the following content:prisma/schema.prod.prisma
generator client {provider = "prisma-client-js"}datasource db {provider = "postgresql"url = env("DATABASE_URL")}model Session {id String @idshop Stringstate StringisOnline Boolean @default(false)scope String?expires DateTime?accessToken StringuserId BigInt?firstName String?lastName String?email String?accountOwner Boolean @default(false)locale String?collaborator Boolean @default(false)emailVerified Boolean @default(false)}model QRCode {id Int @id @default(autoincrement())title Stringshop StringproductId StringproductHandle StringproductVariantId Stringdestination Stringscans Int @default(0)createdAt DateTime @default(now())}The new file should be identical to your existing
prisma/schema.prismafile, with only thedatasource dbconfiguration changing to now suit the PostgreSQLprovider. -
Update your
Dockerfileto match the following contents:Dockerfile
FROM node:20-alpineRUN apk add --no-cache openssl curl# Download Cloud SQL Auth ProxyRUN curl -o /cloud-sql-proxy https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.14.1/cloud-sql-proxy.linux.amd64RUN chmod +x /cloud-sql-proxyEXPOSE 3000WORKDIR /appENV NODE_ENV=productionCOPY package.json package-lock.json* ./RUN npm ci --omit=dev && npm cache clean --forceCOPY . .# Use production schema for PostgreSQLRUN cp prisma/schema.prod.prisma prisma/schema.prisma# Delete SQLite migrations (incompatible with PostgreSQL)RUN rm -rf prisma/migrationsRUN npm run build# Copy and set permissions for startup scriptRUN chmod +x start.shCMD ["sh", "start.sh"]Notice what's changed here:
- [4-6] Download Cloud SQL Auth Proxy: The Cloud SQL Proxy creates a standard TCP endpoint at
localhost:5432inside the container, allowing Prisma to connect using familiar TCP connections. - [20-21] Use production schema for PostgreSQL: Prisma requires the database
providerto be hardcoded at build time. Instead of changing the local behavior of this app, these lines overwrite the schema using PostgreSQL only in the production context. - [23-24] Delete SQLite migrations (incompatible with PostgreSQL): SQLite migrations would fail when applied to a PostgreSQL database, so they are deleted. You will use
prisma db pushto create tables directly from the schema instead in a later step in this tutorial. - [28-31] Copy and set permissions for startup script: Because app requires that the database connection is available when Prisma interacts with it, running the multiple commands required to make this work is simpler when included in a dedicated script.
- [4-6] Download Cloud SQL Auth Proxy: The Cloud SQL Proxy creates a standard TCP endpoint at
-
Create a
start.shscript in your project root containing the following:start.sh
#!/bin/sh# Start Cloud SQL Proxy in background/cloud-sql-proxy --port 5432 ${INSTANCE_CONNECTION_NAME} &# Wait for proxy to be readysleep 3# Run production setup and start the appnpm run setup:prod && npm run startThis script launches the Cloud SQL Proxy before the app starts, ensuring the database connection is available when Prisma tries to generate the client and sync the schema.
-
Add a
setup:prodscript to yourpackage.jsonfile to specifically handle migrations in the production context:package.json
"setup:prod": "prisma generate && prisma db push" -
Enable the Cloud SQL Admin API on the project:
Terminal
gcloud services enable sqladmin.googleapis.com -
Create a password for your database:
Terminal
export DB_PASSWORD="your-secure-password" -
Create a PostgreSQL database instance that will persist across deployments:
Terminal
gcloud sql instances create ${SERVICE_NAME}-db \--database-version=POSTGRES_15 \--tier=db-f1-micro \--region=$SERVICE_REGION \--root-password=$DB_PASSWORDNoteThis command can take as long as 10 minutes to complete.
You can verify the instance is running correctly at this point by running the following command:
Terminal
gcloud sql instances describe ${SERVICE_NAME}-db --format="get(state)"NoteThis command should return
RUNNABLE. -
Create an application database called
shopify_appin the instance:Terminal
gcloud sql databases create shopify_app --instance=${SERVICE_NAME}-db -
Retrieve the Service Account you've configured in this tutorial:
Terminal
SERVICE_ACCOUNT=$(gcloud run services describe $SERVICE_NAME --region=$SERVICE_REGION --format="value(spec.template.spec.serviceAccountName)") -
Grant the Cloud SQL Client role for the Service Account:
Terminal
gcloud projects add-iam-policy-binding $PROJECT_ID \--member="serviceAccount:${SERVICE_ACCOUNT}" \--role="roles/cloudsql.client" -
Get the Cloud SQL connection name:
Terminal
CONNECTION_NAME=$(gcloud sql instances describe ${SERVICE_NAME}-db --format="get(connectionName)") -
Build the DATABASE_URL connection string:
Terminal
DATABASE_URL="postgresql://postgres:${DB_PASSWORD}@localhost:5432/shopify_app" -
Update the Cloud Run service with all configurations:
Terminal
gcloud run services update $SERVICE_NAME \--region=$SERVICE_REGION \--add-cloudsql-instances=$CONNECTION_NAME \--update-env-vars="DATABASE_URL=$DATABASE_URL,INSTANCE_CONNECTION_NAME=$CONNECTION_NAME,SHOPIFY_APP_URL=$SHOPIFY_APP_URL" -
Deploy the updated application:
Terminal
gcloud run deploy $SERVICE_NAME \--source . \--region=$SERVICE_REGION \--allow-unauthenticated
Anchor to Step 7: Connect your app to ShopifyStep 7: Connect your app to Shopify
Connect your deployed app to Shopify by updating your app configuration with the new service URL and testing the integration.
-
Update your
shopify.app.tomlfile with the Cloud Run service URL:shopify.app.toml
application_url = "https://gcp-test-app-xyz123-uc.us-central1.run.app" -
Push your configuration to your Shopify development store to verify the service is now accessible:
Terminal
shopify app deploy -
Test that the core functionality of your app is still working, now that your store is communicating with the Cloud Run service rather than your local installation.
Anchor to Optional: Deploy to multiple regionsOptional: Deploy to multiple regions
Your app may serve a global user base, require high availability, or otherwise have regionally-specific performance considerations. In these cases, you can deploy to multiple regions, then use a global load balancer to route traffic to the nearest region.
Multi-region deployment adds complexity and cost (load balancer fees). For most apps, single-region deployment is sufficient. Consult Step 5 if you don't need multi-region support.
Make sure to complete steps 1-6 in the tutorial above before proceeding.
Anchor to Step 1: Deploy to regionsStep 1: Deploy to regions
-
Choose your target regions from the available Cloud Run locations. In this guide, we'll use
us-central1(United States),europe-west1(Belgium), andasia-northeast1(Tokyo). Replace in the subsequent commands with your real world requirements. -
Deploy your app to each region using the command below:
for region in us-central1 europe-west1 asia-northeast1; dogcloud run deploy $SERVICE_NAME-$region \--source . \--region $region \--set-secrets="SHOPIFY_API_KEY=shopify-api-key:latest,SHOPIFY_API_SECRET=shopify-api-secret:latest" \--set-env-vars="SCOPES=$SCOPES,DATABASE_URL=$DATABASE_URL,INSTANCE_CONNECTION_NAME=$CONNECTION_NAME" \--add-cloudsql-instances=$CONNECTION_NAME \--port 3000 \--no-allow-unauthenticateddoneforeach ($region in @("us-central1", "europe-west1", "asia-northeast1")) {gcloud run deploy "$env:SERVICE_NAME-$region" `--source . `--region $region `--set-secrets="SHOPIFY_API_KEY=shopify-api-key:latest,SHOPIFY_API_SECRET=shopify-api-secret:latest" `--set-env-vars="SCOPES=$env:SCOPES,DATABASE_URL=$env:DATABASE_URL,INSTANCE_CONNECTION_NAME=$env:CONNECTION_NAME" `--add-cloudsql-instances=$env:CONNECTION_NAME `--port 3000 `--no-allow-unauthenticated}Mac/Linux (bash)
for region in us-central1 europe-west1 asia-northeast1; do gcloud run deploy $SERVICE_NAME-$region \ --source . \ --region $region \ --set-secrets="SHOPIFY_API_KEY=shopify-api-key:latest,SHOPIFY_API_SECRET=shopify-api-secret:latest" \ --set-env-vars="SCOPES=$SCOPES,DATABASE_URL=$DATABASE_URL,INSTANCE_CONNECTION_NAME=$CONNECTION_NAME" \ --add-cloudsql-instances=$CONNECTION_NAME \ --port 3000 \ --no-allow-unauthenticated doneWindows (PowerShell)
foreach ($region in @("us-central1", "europe-west1", "asia-northeast1")) { gcloud run deploy "$env:SERVICE_NAME-$region" ` --source . ` --region $region ` --set-secrets="SHOPIFY_API_KEY=shopify-api-key:latest,SHOPIFY_API_SECRET=shopify-api-secret:latest" ` --set-env-vars="SCOPES=$env:SCOPES,DATABASE_URL=$env:DATABASE_URL,INSTANCE_CONNECTION_NAME=$env:CONNECTION_NAME" ` --add-cloudsql-instances=$env:CONNECTION_NAME ` --port 3000 ` --no-allow-unauthenticated }In this tutorial, all regions connect to the same Cloud SQL instance. The database remains in the original
$SERVICE_REGION, which may add latency for distant regions. Like the single region deployment in previous steps, this command will fail for each region until we provide the load balancer URL in a later step.NoteWe use
--no-allow-unauthenticatedbecause the load balancer will handle public access. -
Create a Network Endpoint Group (NEG) for each regional Cloud Run service:
for region in us-central1 europe-west1 asia-northeast1; dogcloud compute network-endpoint-groups create $SERVICE_NAME-neg-$region \--region=$region \--network-endpoint-type=serverless \--cloud-run-service=$SERVICE_NAME-$regiondoneforeach ($region in @("us-central1", "europe-west1", "asia-northeast1")) {gcloud compute network-endpoint-groups create "$env:SERVICE_NAME-neg-$region" `--region=$region `--network-endpoint-type=serverless `--cloud-run-service="$env:SERVICE_NAME-$region"}Mac/Linux (bash)
for region in us-central1 europe-west1 asia-northeast1; do gcloud compute network-endpoint-groups create $SERVICE_NAME-neg-$region \ --region=$region \ --network-endpoint-type=serverless \ --cloud-run-service=$SERVICE_NAME-$region doneWindows (PowerShell)
foreach ($region in @("us-central1", "europe-west1", "asia-northeast1")) { gcloud compute network-endpoint-groups create "$env:SERVICE_NAME-neg-$region" ` --region=$region ` --network-endpoint-type=serverless ` --cloud-run-service="$env:SERVICE_NAME-$region" }
Anchor to Step 2: Configure load balancerStep 2: Configure load balancer
-
Create a backend service that will route traffic to your regional services:
Terminal
gcloud compute backend-services create $SERVICE_NAME-backend \--global \--load-balancing-scheme=EXTERNAL_MANAGED -
Add each NEG as a backend:
for region in us-central1 europe-west1 asia-northeast1; dogcloud compute backend-services add-backend $SERVICE_NAME-backend \--global \--network-endpoint-group=$SERVICE_NAME-neg-$region \--network-endpoint-group-region=$regiondoneforeach ($region in @("us-central1", "europe-west1", "asia-northeast1")) {gcloud compute backend-services add-backend $env:SERVICE_NAME-backend `--global `--network-endpoint-group="$env:SERVICE_NAME-neg-$region" `--network-endpoint-group-region=$region}Mac/Linux (bash)
for region in us-central1 europe-west1 asia-northeast1; do gcloud compute backend-services add-backend $SERVICE_NAME-backend \ --global \ --network-endpoint-group=$SERVICE_NAME-neg-$region \ --network-endpoint-group-region=$region doneWindows (PowerShell)
foreach ($region in @("us-central1", "europe-west1", "asia-northeast1")) { gcloud compute backend-services add-backend $env:SERVICE_NAME-backend ` --global ` --network-endpoint-group="$env:SERVICE_NAME-neg-$region" ` --network-endpoint-group-region=$region } -
Create a URL map to route all traffic to your backend service:
Terminal
gcloud compute url-maps create $SERVICE_NAME-url-map \--default-service=$SERVICE_NAME-backend -
Reserve a static external IP address for your load balancer:
Terminal
gcloud compute addresses create $SERVICE_NAME-ip \--global -
Retrieve the IP address:
Terminal
LOAD_BALANCER_IP=$(gcloud compute addresses describe $SERVICE_NAME-ip \--global \--format="get(address)") -
In your domain registrar, create an A record pointing to the load balancer IP address:
Type: AName: app (or your subdomain)Value: [LOAD_BALANCER_IP]Going forward, your load balancer URL will be
https://app.yourdomain.com(or your chosen subdomain). -
Wait for DNS propagation (typically 5-15 minutes) and verify the command below returns your load balancer IP address:
Terminal
nslookup app.yourdomain.com -
Create a managed SSL certificate for your domain:
Terminal
gcloud compute ssl-certificates create $SERVICE_NAME-ssl-cert \--domains=app.yourdomain.com \--global -
Create an HTTPS target proxy:
Terminal
gcloud compute target-https-proxies create $SERVICE_NAME-https-proxy \--url-map=$SERVICE_NAME-url-map \--ssl-certificates=$SERVICE_NAME-ssl-cert -
Create a global forwarding rule using the reserved IP:
Terminal
gcloud compute forwarding-rules create $SERVICE_NAME-forwarding-rule \--global \--address=$SERVICE_NAME-ip \--target-https-proxy=$SERVICE_NAME-https-proxy \--ports=443 -
Check SSL certificate provisioning status:
Terminal
gcloud compute ssl-certificates describe $SERVICE_NAME-ssl-cert \--global \--format="get(managed.status)"Wait for status to change from
PROVISIONINGtoACTIVEbefore testing. This can take up to 60 minutes.
Anchor to Step 3: Redeploy and verifyStep 3: Redeploy and verify
-
Grant public access to each regional service so the load balancer can route traffic to them:
Terminal
for region in us-central1 europe-west1 asia-northeast1; dogcloud run services add-iam-policy-binding $SERVICE_NAME-$region \--region=$region \--member="allUsers" \--role="roles/run.invoker"done -
Export the newly defined load balancer URL:
Terminal
export LOAD_BALANCER_URL="https://app.yourdomain.com" -
Redeploy each regional service with the load balancer URL:
for region in us-central1 europe-west1 asia-northeast1; dogcloud run deploy $SERVICE_NAME-$region \--source . \--region $region \--update-env-vars="SHOPIFY_APP_URL=$LOAD_BALANCER_URL"done$env:LOAD_BALANCER_URL="https://app.yourdomain.com"foreach ($region in @("us-central1", "europe-west1", "asia-northeast1")) {gcloud run deploy "$env:SERVICE_NAME-$region" `--source . `--region $region `--update-env-vars="SHOPIFY_APP_URL=$env:LOAD_BALANCER_URL"}Mac/Linux (bash)
for region in us-central1 europe-west1 asia-northeast1; do gcloud run deploy $SERVICE_NAME-$region \ --source . \ --region $region \ --update-env-vars="SHOPIFY_APP_URL=$LOAD_BALANCER_URL" doneWindows (PowerShell)
$env:LOAD_BALANCER_URL="https://app.yourdomain.com" foreach ($region in @("us-central1", "europe-west1", "asia-northeast1")) { gcloud run deploy "$env:SERVICE_NAME-$region" ` --source . ` --region $region ` --update-env-vars="SHOPIFY_APP_URL=$env:LOAD_BALANCER_URL" } -
Verify that your load balancer is routing traffic correctly:
Terminal
curl -I https://app.yourdomain.comYou can test from different geographic locations using services like Global Ping to verify regional routing.
-
Update your
shopify.app.tomlfile with your load balancer URL:shopify.app.toml
application_url = "https://app.yourdomain.com" -
Push your configuration to your Shopify development store to verify the service is now accessible:
Terminal
shopify app deploy -
Test that the core functionality of your app is still working, now that your store is communicating with the Cloud Run services rather than your local installation.
Anchor to Next stepsNext steps
Now that your app is deployed and connected to Shopify, you can explore these related topics:
- Launch your app to learn about app distribution and the review process.