Skip to main content
Ask your AI

Deploy walkerOS to GCP Cloud Run

This guide deploys a walkerOS flow to Google Cloud Run, forwarding events to BigQuery.

Prerequisites

1. Set Up BigQuery

Follow the GCP BigQuery setup to:

For local testing, download a service account key. Production uses Workload Identity.

Enable Cloud Run API

gcloud services enable run.googleapis.com

2. Bundle the Flow

The example flow at https://www.walkeros.io/flows/gcp-bigquery.json receives events with the Express source on /collect and writes them to BigQuery:

{
"version": 4,
"flows": {
"server": {
"config": { "platform": "server" },
"sources": {
"express": {
"package": "@walkeros/server-source-express",
"config": {
"settings": { "paths": ["/collect"], "port": 8080 }
}
}
},
"destinations": {
"bigquery": {
"package": "@walkeros/server-destination-gcp",
"import": "destinationBigQuery",
"config": {
"settings": {
"projectId": "$env.GCP_PROJECT_ID",
"datasetId": "$env.BQ_DATASET:walkerOS",
"tableId": "$env.BQ_TABLE:events",
"location": "$env.BQ_LOCATION:EU"
}
}
}
}
}
}
}

Install the CLI and bundle the flow into dist/:

npm install -g @walkeros/cli

walkeros bundle https://www.walkeros.io/flows/gcp-bigquery.json -o dist/

This creates dist/flow.mjs, dist/package.json, and dist/node_modules/. The CLI adds the packages named in package to the bundle, so the flow needs no separate package list.

Environment variables

In a server flow, $env.NAME is read from the environment when the container starts, not at bundle time. Required: GCP_PROJECT_ID. Optional with defaults: BQ_DATASET (walkerOS), BQ_TABLE (events), BQ_LOCATION (EU). See Reference Syntax.

3. Test Locally with Docker

Before deploying, verify everything works locally:

# Run locally (uses key file for auth)
docker run --rm \
-p 8080:8080 \
-v $(pwd)/dist:/app/flow:ro \
-v $(pwd)/sa-bigquery.json:/app/sa-bigquery.json:ro \
-e GOOGLE_APPLICATION_CREDENTIALS=/app/sa-bigquery.json \
-e GCP_PROJECT_ID=your-project-id \
walkeros/flow:latest

In another terminal, send a test event:

curl -X POST http://localhost:8080/collect \
-H "Content-Type: application/json" \
-d '{
"name": "page view",
"data": {
"title": "Test Page",
"path": "/test"
}
}'

Expected response:

{ "success": true, "timestamp": 1234567890 }

Check BigQuery for the event:

bq query --use_legacy_sql=false \
"SELECT * FROM walkerOS.events WHERE DATE(timestamp) = CURRENT_DATE() ORDER BY timestamp DESC LIMIT 5"

4. Deploy to Cloud Run

Create dist/Dockerfile so Cloud Run builds an image from the runtime image plus your bundle. The runtime image expects the bundle at /app/flow/flow.mjs:

FROM walkeros/flow:latest
COPY . /app/flow/

Cloud Run uses Workload Identity, so no credentials file is needed in the image.

Deploy with the service account attached and the project ID set as an environment variable:

cd dist

gcloud run deploy walkeros-flow \
--source . \
--port 8080 \
--region europe-west1 \
--allow-unauthenticated \
--service-account=walkeros-flow@YOUR_PROJECT_ID.iam.gserviceaccount.com \
--set-env-vars GCP_PROJECT_ID=YOUR_PROJECT_ID \
--memory 512Mi \
--cpu 1 \
--min-instances 0 \
--max-instances 10

Note the service URL from the output (e.g., https://walkeros-flow-xxx-ew.a.run.app).

5. Verify Deployment

Health Check

curl https://walkeros-flow-xxx-ew.a.run.app/health

Send Test Event

curl -X POST https://walkeros-flow-xxx-ew.a.run.app/collect \
-H "Content-Type: application/json" \
-d '{
"name": "page view",
"data": {
"title": "Production Test",
"path": "/"
}
}'

Query BigQuery

bq query --use_legacy_sql=false \
"SELECT name, data, timestamp FROM walkerOS.events WHERE DATE(timestamp) = CURRENT_DATE() ORDER BY timestamp DESC LIMIT 5"

Next Steps

Cleanup

To remove all created resources:

  • Delete the Cloud Run service (gcloud run services delete walkeros-flow --region europe-west1)
  • Clean up BigQuery resources
  • Delete local files (dist/, sa-bigquery.json)
💡 Need implementation support?
elbwalker offers hands-on support: setup review, measurement planning, destination mapping, and live troubleshooting. Book a 2-hour session (€399)