Last updated: Aug 12, 2025, 01:09 PM UTC

GCP Cloud Run Deployment Guide for Sasha Studio

Generated: 2025-08-09 UTC
Version: 1.0
Platform: Google Cloud Run
Architecture: Containerized Node.js Application with WebSocket Support


Overview

This guide provides complete instructions for deploying Sasha Studio to Google Cloud Run. Cloud Run is ideal for our application because it:

  • Scales to zero: No costs when not in use
  • Automatic HTTPS: SSL certificates managed automatically
  • WebSocket support: Full duplex communication for Claude CLI
  • Container native: Works with our existing Docker setup
  • Global reach: Deploy to 35+ regions worldwide

Prerequisites

Required Tools

  • gcloud CLI: Install Guide
  • Git: For version control
  • Docker (optional): For local testing

Required Accounts

  • Google Cloud Account with billing enabled
  • Anthropic API Key for Claude CLI functionality

Estimated Costs

  • Free Tier: 2 million requests, 360,000 GiB-seconds, 180,000 vCPU-seconds per month
  • Typical Usage: $0-$10/month for light usage
  • Production: $50-$200/month depending on traffic

Architecture

graph TB subgraph "Google Cloud Platform" CR[Cloud Run Service] SM[Secret Manager] CB[Cloud Build] AR[Artifact Registry] VPC[VPC Connector] end subgraph "Application Components" UI[React Frontend] API[Express Backend] WS[WebSocket Server] CC[Claude CLI] end subgraph "External Services" AN[Anthropic API] end Users --> CR CR --> UI UI --> API API --> WS WS --> CC CC --> AN CR --> SM CB --> AR AR --> CR CR --> VPC

Quick Start

1. Clone and Navigate

git clone <your-repo>
cd sasha/claudecodeui

2. Run Setup Script

./scripts/setup-gcp-project.sh

This script will:

  • Create a new GCP project
  • Enable required APIs
  • Set up billing and budget alerts
  • Create service accounts
  • Configure Secret Manager

3. Configure Secrets

# The Anthropic API key is configured through the app's onboarding process
# Only need to create the secret placeholder (will be populated by the app)
gcloud secrets create anthropic-api-key --data-file=- <<< ""

# Generate and add session secret
echo -n "$(openssl rand -base64 32)" | gcloud secrets versions add session-secret --data-file=-

# Generate and add JWT secret
echo -n "$(openssl rand -base64 32)" | gcloud secrets versions add jwt-secret --data-file=-

4. Deploy

./scripts/deploy-gcp.sh

Detailed Setup Guide

Step 1: Project Configuration

Create a deployment.env file (created automatically by setup script):

# GCP Configuration
PROJECT_ID=sasha-studio-prod
PROJECT_NAME="Sasha Studio Production"
BILLING_ACCOUNT_ID=XXXXXX-XXXXXX-XXXXXX
ACCOUNT_EMAIL=your-email@gmail.com
REGION=us-central1
ZONE=us-central1-a
SERVICE_NAME=sasha-studio

# Resource Configuration
MEMORY=2Gi
CPU=2
MIN_INSTANCES=0
MAX_INSTANCES=10
CONCURRENCY=100

# Budget Alert
MONTHLY_BUDGET=100

Step 2: Manual Project Setup (Alternative)

If you prefer manual setup over the script:

# Create project
gcloud projects create sasha-studio-prod --name="Sasha Studio"

# Set as default
gcloud config set project sasha-studio-prod

# Link billing
gcloud billing projects link sasha-studio-prod \
    --billing-account=XXXXXX-XXXXXX-XXXXXX

# Enable APIs
gcloud services enable \
    cloudbuild.googleapis.com \
    run.googleapis.com \
    containerregistry.googleapis.com \
    secretmanager.googleapis.com \
    compute.googleapis.com \
    vpcaccess.googleapis.com

Step 3: Service Account Setup

# Create service account
gcloud iam service-accounts create sasha-studio \
    --display-name="Sasha Studio Cloud Run"

# Grant permissions
PROJECT_ID=sasha-studio-prod
SA_EMAIL=sasha-studio@${PROJECT_ID}.iam.gserviceaccount.com

gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member="serviceAccount:$SA_EMAIL" \
    --role="roles/secretmanager.secretAccessor"

Step 4: Build and Deploy

Using Cloud Build (Recommended)

# Submit build
gcloud builds submit --config=cloudbuild.yaml

Direct Deployment

# Build image
gcloud builds submit --tag gcr.io/$PROJECT_ID/sasha-studio:latest

# Deploy to Cloud Run
gcloud run deploy sasha-studio \
    --image gcr.io/$PROJECT_ID/sasha-studio:latest \
    --region us-central1 \
    --platform managed \
    --allow-unauthenticated \
    --min-instances 0 \
    --max-instances 10 \
    --memory 2Gi \
    --cpu 2 \
    --port 8080 \
    --set-secrets "ANTHROPIC_API_KEY=anthropic-api-key:latest"

Configuration Details

Environment Variables

Cloud Run automatically sets:

  • PORT: Dynamic port assignment (usually 8080)
  • K_SERVICE: Service name
  • K_REVISION: Revision name
  • K_CONFIGURATION: Configuration name

Our application sets:

  • NODE_ENV=production
  • DEPLOYMENT_PLATFORM=google-cloud-run
  • RUNNING_IN_DOCKER=true
  • CONFIG_DIR=/tmp/config (writable storage)
  • DB_PATH=/tmp/sasha.db (SQLite in memory)

Note: The Anthropic API key is NOT set as an environment variable during deployment. Instead, it's configured through the application's onboarding interface when you first access the deployed app. This provides better security and user control.

File Storage

Cloud Run has a read-only filesystem except for /tmp:

  • Database: /tmp/sasha.db
  • Uploads: /tmp/uploads/
  • Config: /tmp/config/
  • Workspaces: /tmp/workspaces/

Important: /tmp is ephemeral and cleared between container instances.

WebSocket Configuration

Cloud Run supports WebSocket with these considerations:

  • Maximum connection duration: 60 minutes
  • Idle timeout: 10 minutes
  • Use session affinity for better performance

🚦 Health Monitoring

Health Check Endpoint

The application exposes /api/health:

{
  "status": "healthy",
  "timestamp": "2025-08-09T10:30:00Z",
  "uptime": 3600,
  "platform": "google-cloud-run",
  "checks": {
    "claudeCli": true,
    "database": "healthy"
  },
  "memory": {
    "heapUsed": "45MB",
    "heapTotal": "118MB",
    "rss": "156MB"
  }
}

Monitoring Commands

# View logs
gcloud run services logs read sasha-studio --region=us-central1

# Stream logs
gcloud alpha run services logs tail sasha-studio --region=us-central1

# View metrics
gcloud monitoring metrics-descriptors list --filter="metric.type:run.googleapis.com"

Deployment Workflows

Standard Deployment

./scripts/deploy-gcp.sh

Local Testing

./scripts/deploy-gcp.sh --local-test

Direct Deployment (Skip Cloud Build)

./scripts/deploy-gcp.sh --direct

Rollback

./scripts/deploy-gcp.sh --rollback

Blue-Green Deployment

# Deploy new version without routing traffic
gcloud run deploy sasha-studio --no-traffic --tag=blue

# Test the new version
curl https://blue---sasha-studio-xxxxx.run.app

# Switch traffic
gcloud run services update-traffic sasha-studio --to-tags=blue=100

Troubleshooting

Common Issues

1. Container Fails to Start

# Check logs
gcloud run services logs read sasha-studio --region=us-central1

# Common causes:
# - Missing PORT environment variable
# - Missing secrets
# - Memory limits too low

2. Claude CLI Not Working

# Verify API key is set
gcloud secrets versions list anthropic-api-key

# Check if secret is accessible
gcloud run services describe sasha-studio --region=us-central1 \
    --format="value(spec.template.spec.containers[0].env[?(@.name=='ANTHROPIC_API_KEY')])"

3. WebSocket Connection Issues

# Enable session affinity
gcloud run services update sasha-studio \
    --session-affinity \
    --region=us-central1

4. High Latency

# Check cold start frequency
gcloud logging read "resource.type=cloud_run_revision \
    resource.labels.service_name=sasha-studio \
    textPayload:'Cold start'" --limit=50

# Solution: Set min-instances to 1
gcloud run services update sasha-studio --min-instances=1

Cost Optimization

Strategies

  1. Scale to Zero

    gcloud run services update sasha-studio --min-instances=0
    
  2. Optimize Resources

    # Reduce memory if not needed
    gcloud run services update sasha-studio --memory=1Gi
    
    # Reduce CPU
    gcloud run services update sasha-studio --cpu=1
    
  3. Set Concurrency Limits

    gcloud run services update sasha-studio --concurrency=50
    
  4. Use Budget Alerts

    gcloud billing budgets create \
        --billing-account=$BILLING_ACCOUNT_ID \
        --display-name="Sasha Studio Budget" \
        --budget-amount=100USD \
        --threshold-rule=percent=50,75,90,100
    

Security Best Practices

1. Use Secret Manager

Never hardcode secrets. Always use Secret Manager:

gcloud run services update sasha-studio \
    --set-secrets="API_KEY=api-key-secret:latest"

2. Enable VPC Connector

For private networking:

gcloud compute networks vpc-access connectors create serverless-connector \
    --region=us-central1 \
    --subnet=default \
    --subnet-range=10.8.0.0/28

gcloud run services update sasha-studio \
    --vpc-connector=serverless-connector \
    --vpc-egress=private-ranges-only

3. Implement Authentication

For production:

# Require authentication
gcloud run services update sasha-studio --no-allow-unauthenticated

# Grant specific users access
gcloud run services add-iam-policy-binding sasha-studio \
    --member="user:email@example.com" \
    --role="roles/run.invoker"

4. Enable Cloud Armor

Protect against DDoS:

gcloud compute security-policies create sasha-studio-policy \
    --description="Security policy for Sasha Studio"

Performance Tuning

Optimize Cold Starts

  1. Use smaller base images
  2. Minimize dependencies
  3. Set min-instances for critical services
  4. Use Cloud Run warmup requests

Memory Configuration

# Monitor memory usage
gcloud monitoring read \
    "resource.type=cloud_run_revision AND \
     metric.type=run.googleapis.com/container/memory/utilizations" \
    --start-time=2024-01-01T00:00:00Z \
    --format=table

# Adjust based on usage
gcloud run services update sasha-studio --memory=4Gi

CPU Configuration

# For CPU-intensive workloads
gcloud run services update sasha-studio --cpu=4

# For I/O bound workloads
gcloud run services update sasha-studio --cpu=1

CI/CD Integration

GitHub Actions

name: Deploy to Cloud Run

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      
      - uses: google-github-actions/auth@v1
        with:
          credentials_json: ${{ secrets.GCP_SA_KEY }}
      
      - uses: google-github-actions/setup-gcloud@v1
      
      - name: Build and Deploy
        run: |
          gcloud builds submit --config=cloudbuild.yaml

Additional Resources


Support

For issues specific to this deployment:

  1. Check the Troubleshooting section
  2. Review Cloud Run logs
  3. Check the health endpoint
  4. Verify all secrets are configured

For Cloud Run issues:


Deployment Checklist

Before deploying to production:

  • All secrets configured in Secret Manager
  • Budget alerts set up
  • Health check endpoint tested
  • WebSocket connections verified
  • Claude CLI functionality confirmed
  • Monitoring and logging configured
  • Security policies applied
  • Backup strategy defined
  • Rollback procedure tested
  • Documentation updated

Last Updated: 2025-08-09
Maintained By: Sasha Studio Team