Google Cloud Adapter
Installation
Section titled “Installation”npm install @cruzjs/adapter-gcpCloud Run
Section titled “Cloud Run”Best for: Containerized apps with auto-scaling, moderate-to-high traffic.
import { GCPCloudRunAdapter } from '@cruzjs/adapter-gcp';
export default createCruzApp({ schema, modules: [/* your modules */], adapter: new GCPCloudRunAdapter({ databaseUrl: process.env.DATABASE_URL, gcsBucket: process.env.GCS_BUCKET, cpuAlwaysAllocated: true, // Enable background work }), pages: () => import('virtual:react-router/server-build'),});Cloud Functions
Section titled “Cloud Functions”Best for: Simple serverless APIs, event-driven workloads.
import { GCPCloudFunctionsAdapter } from '@cruzjs/adapter-gcp';
export default createCruzApp({ schema, modules: [/* your modules */], adapter: new GCPCloudFunctionsAdapter({ databaseUrl: process.env.DATABASE_URL, gcsBucket: process.env.GCS_BUCKET, }), pages: () => import('virtual:react-router/server-build'),});Service Mapping
Section titled “Service Mapping”| CruzJS Binding | GCP Service |
|---|---|
| Database | Cloud SQL (Postgres/MySQL), AlloyDB |
| Cache | Memorystore (Redis) |
| Storage | Cloud Storage (GCS) |
| Queue | Pub/Sub, Cloud Tasks |
| AI | Vertex AI, Gemini API |
Database Setup (Cloud SQL)
Section titled “Database Setup (Cloud SQL)”Cloud SQL PostgreSQL
Section titled “Cloud SQL PostgreSQL”Create a Cloud SQL instance and configure the connection. For Cloud Run, use the built-in Cloud SQL connector:
DATABASE_URL=postgresql://cruzuser:password@/cruzdb?host=/cloudsql/project-id:region:instance-nameFor Cloud Functions, use the same Unix socket path:
DATABASE_URL=postgresql://cruzuser:password@/cruzdb?host=/cloudsql/project-id:us-central1:my-cruz-dbCreating a Cloud SQL Instance
Section titled “Creating a Cloud SQL Instance”# Create a PostgreSQL instancegcloud sql instances create my-cruz-db \ --database-version=POSTGRES_16 \ --tier=db-f1-micro \ --region=us-central1 \ --root-password=your-password
# Create the databasegcloud sql databases create cruzdb --instance=my-cruz-db
# Create an application usergcloud sql users create cruzuser \ --instance=my-cruz-db \ --password=your-app-passwordAlloyDB
Section titled “AlloyDB”For production workloads requiring high performance:
DATABASE_URL=postgresql://cruzuser:password@10.x.x.x:5432/cruzdbAlloyDB requires VPC access. Configure your Cloud Run service with a VPC connector.
Cache Setup (Memorystore Redis)
Section titled “Cache Setup (Memorystore Redis)”Memorystore provides managed Redis that maps to CruzJS’s CacheBinding interface.
Creating a Memorystore Instance
Section titled “Creating a Memorystore Instance”gcloud redis instances create my-cruz-cache \ --size=1 \ --region=us-central1 \ --redis-version=redis_7_0 \ --network=defaultConfiguration
Section titled “Configuration”new GCPCloudRunAdapter({ databaseUrl: process.env.DATABASE_URL, redisUrl: process.env.REDIS_URL, // ...})REDIS_URL=redis://10.x.x.x:6379VPC Connector
Section titled “VPC Connector”Memorystore runs inside a VPC. Your Cloud Run service needs a VPC connector:
# Create a VPC connectorgcloud compute networks vpc-access connectors create cruz-connector \ --region=us-central1 \ --network=default \ --range=10.8.0.0/28
# Deploy Cloud Run with the connectorgcloud run deploy my-cruz-app \ --vpc-connector=cruz-connector \ --vpc-egress=private-ranges-onlyStorage Setup (Cloud Storage)
Section titled “Storage Setup (Cloud Storage)”GCS maps to CruzJS’s storage binding for file uploads and media.
Creating a Bucket
Section titled “Creating a Bucket”gcloud storage buckets create gs://my-cruz-uploads \ --location=us-central1 \ --uniform-bucket-level-accessConfiguration
Section titled “Configuration”new GCPCloudRunAdapter({ databaseUrl: process.env.DATABASE_URL, gcsBucket: process.env.GCS_BUCKET, // ...})GCS_BUCKET=my-cruz-uploadsCORS Configuration
Section titled “CORS Configuration”For direct client uploads, configure CORS on the bucket:
[ { "origin": ["https://myapp.com"], "method": ["GET", "PUT", "POST"], "responseHeader": ["Content-Type"], "maxAgeSeconds": 3600 }]gcloud storage buckets update gs://my-cruz-uploads --cors-file=cors.jsonQueue Setup (Pub/Sub)
Section titled “Queue Setup (Pub/Sub)”Pub/Sub maps to CruzJS’s QueueBinding interface for asynchronous message processing.
Creating a Topic and Subscription
Section titled “Creating a Topic and Subscription”# Create a topicgcloud pubsub topics create cruz-jobs
# Create a push subscription (for Cloud Run)gcloud pubsub subscriptions create cruz-jobs-sub \ --topic=cruz-jobs \ --push-endpoint=https://my-cruz-worker-xxxx.run.app/process \ --ack-deadline=60
# Or create a pull subscription (for Cloud Functions)gcloud pubsub subscriptions create cruz-jobs-sub \ --topic=cruz-jobs \ --ack-deadline=60Configuration
Section titled “Configuration”new GCPCloudRunAdapter({ databaseUrl: process.env.DATABASE_URL, pubsubTopic: process.env.PUBSUB_TOPIC, gcpProjectId: process.env.GCP_PROJECT_ID, // ...})PUBSUB_TOPIC=cruz-jobsGCP_PROJECT_ID=my-gcp-projectCloud Tasks (Alternative)
Section titled “Cloud Tasks (Alternative)”For task-level control with retries and scheduling:
gcloud tasks queues create cruz-tasks \ --max-dispatches-per-second=10 \ --max-concurrent-dispatches=5 \ --max-attempts=3Environment Variables Reference
Section titled “Environment Variables Reference”| Variable | Required | Description |
|---|---|---|
DATABASE_URL | Yes | Cloud SQL connection string (with Unix socket path) |
REDIS_URL | No | Memorystore Redis endpoint |
GCS_BUCKET | No | Cloud Storage bucket name |
PUBSUB_TOPIC | No | Pub/Sub topic for background jobs |
GCP_PROJECT_ID | No | GCP project ID (auto-detected on GCP) |
GOOGLE_CLOUD_REGION | No | Region for API calls |
OPENAI_API_KEY | No | OpenAI API key (or use Vertex AI) |
AUTH_SECRET | Yes | Session encryption key |
Deployment with gcloud CLI
Section titled “Deployment with gcloud CLI”Cloud Run
Section titled “Cloud Run”# Build the CruzJS appcruz build
# Build the Docker imagedocker build -t gcr.io/my-project/cruz-app .
# Push to Container Registrydocker push gcr.io/my-project/cruz-app
# Deploy to Cloud Rungcloud run deploy my-cruz-app \ --image=gcr.io/my-project/cruz-app \ --platform=managed \ --region=us-central1 \ --allow-unauthenticated \ --add-cloudsql-instances=my-project:us-central1:my-cruz-db \ --set-env-vars="DATABASE_URL=postgresql://cruzuser:password@/cruzdb?host=/cloudsql/my-project:us-central1:my-cruz-db" \ --set-env-vars="GCS_BUCKET=my-cruz-uploads" \ --set-env-vars="AUTH_SECRET=$(openssl rand -base64 32)" \ --vpc-connector=cruz-connector \ --min-instances=0 \ --max-instances=10 \ --memory=512Mi \ --cpu=1Cloud Functions
Section titled “Cloud Functions”# Build the CruzJS appcruz build
# Deploy as a Cloud Functiongcloud functions deploy my-cruz-app \ --gen2 \ --runtime=nodejs20 \ --region=us-central1 \ --trigger-http \ --allow-unauthenticated \ --entry-point=handler \ --source=./build \ --set-env-vars="DATABASE_URL=postgresql://..." \ --memory=512MB \ --timeout=60sDockerfile for Cloud Run
Section titled “Dockerfile for Cloud Run”FROM node:20-alpine AS builderWORKDIR /appCOPY package*.json ./RUN npm ciCOPY . .RUN npx cruz build
FROM node:20-alpineWORKDIR /appCOPY --from=builder /app/build ./buildCOPY --from=builder /app/node_modules ./node_modulesCOPY --from=builder /app/package.json ./EXPOSE 3000CMD ["node", "build/server/index.js"]Runtime Type
Section titled “Runtime Type”- Cloud Run:
container— Auto-scaling containers.waitUntil()is fire-and-forget whencpuAlwaysAllocatedis true. - Cloud Functions:
serverless— Scale-to-zero functions.waitUntil()must be flushed before response returns.