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
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 nameK_REVISION: Revision nameK_CONFIGURATION: Configuration name
Our application sets:
NODE_ENV=productionDEPLOYMENT_PLATFORM=google-cloud-runRUNNING_IN_DOCKER=trueCONFIG_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
Scale to Zero
gcloud run services update sasha-studio --min-instances=0Optimize Resources
# Reduce memory if not needed gcloud run services update sasha-studio --memory=1Gi # Reduce CPU gcloud run services update sasha-studio --cpu=1Set Concurrency Limits
gcloud run services update sasha-studio --concurrency=50Use 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
- Use smaller base images
- Minimize dependencies
- Set min-instances for critical services
- 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
- Cloud Run Documentation
- Cloud Build Documentation
- Secret Manager Documentation
- Pricing Calculator
- Cloud Run Samples
Support
For issues specific to this deployment:
- Check the Troubleshooting section
- Review Cloud Run logs
- Check the health endpoint
- 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