Deployment

GCP Cloud Run Deployment

Deploy thinnestAI to Google Cloud Platform using Cloud Run, Cloud SQL, Memorystore, and Secret Manager.

GCP Cloud Run Deployment

This guide walks you through deploying thinnestAI to Google Cloud Platform for a production-ready setup with managed databases, auto-scaling, and secure secret management.

Architecture

┌──────────────────────────────┐
│   Cloud Run (Backend API)    │
│   - Auto-scales 0 to N      │
│   - HTTPS with custom domain│
└──────────┬───────────────────┘

     ┌─────┼─────────────┐
     ▼     ▼             ▼
┌────────┐ ┌───────────┐ ┌──────────────┐
│Cloud   │ │Memorystore│ │Secret Manager│
│SQL     │ │(Redis)    │ │              │
│(Postgres)│           │ │(API keys,   │
│+ pgvector│           │ │ credentials) │
└────────┘ └───────────┘ └──────────────┘

┌──────────────────────────────┐
│  Cloud Run Jobs (Workers)    │
│  - Email Worker              │
│  - Phone Billing Worker      │
│  - Campaign Orchestrator     │
│  - Auto-Topup Worker         │
└──────────────────────────────┘

Prerequisites

  • A GCP account with billing enabled.
  • Google Cloud CLI (gcloud) installed.
  • Docker installed (for building images).
  • A domain name (optional, for custom domain).

Using the Deploy Script

thinnestAI includes an automated deployment script that handles the entire setup:

cd scripts/gcp-deploy
chmod +x deploy.sh
./deploy.sh

The script presents a menu:

thinnestAI GCP Deployment
========================
1. Full Deployment (everything)
2. Setup Infrastructure Only
3. Build & Deploy Only
4. Configure Secrets
5. Run Database Migrations
6. Backup Database
7. View Logs
8. Verify Deployment
9. Cleanup (destroys everything)

Option 1: Full Deployment

For a fresh deployment, choose option 1. This will:

  1. Enable required GCP APIs.
  2. Create a Cloud SQL instance with pgvector.
  3. Create a Memorystore Redis instance.
  4. Store secrets in Secret Manager.
  5. Build and push Docker images.
  6. Deploy the backend to Cloud Run.
  7. Deploy workers as Cloud Run jobs.
  8. Run database migrations.
  9. Verify the deployment.

The full process takes approximately 15-20 minutes.

Step-by-Step Manual Setup

If you prefer to set things up manually, follow these steps.

1. Enable GCP APIs

gcloud services enable \
  run.googleapis.com \
  sqladmin.googleapis.com \
  redis.googleapis.com \
  secretmanager.googleapis.com \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com

2. Create Cloud SQL Instance

# Create PostgreSQL instance
gcloud sql instances create thinnestai-db \
  --database-version=POSTGRES_15 \
  --tier=db-f1-micro \
  --region=us-central1 \
  --storage-size=20GB \
  --storage-auto-increase

# Create database
gcloud sql databases create agno --instance=thinnestai-db

# Set password
gcloud sql users set-password postgres \
  --instance=thinnestai-db \
  --password=YOUR_SECURE_PASSWORD

Enable pgvector

Connect to the database and enable the extension:

gcloud sql connect thinnestai-db --user=postgres
CREATE EXTENSION IF NOT EXISTS vector;

3. Create Memorystore Redis

gcloud redis instances create thinnestai-redis \
  --size=1 \
  --region=us-central1 \
  --redis-version=redis_7_0 \
  --network=default

Note the Redis host IP from the output — you'll need it for configuration.

4. Store Secrets

# Store each secret
echo -n "sk-your-openai-key" | \
  gcloud secrets create OPENAI_API_KEY --data-file=-

echo -n "your-encryption-key" | \
  gcloud secrets create ENCRYPTION_KEY --data-file=-

# Repeat for all sensitive values

5. Build and Push Docker Image

# Create Artifact Registry repository
gcloud artifacts repositories create thinnestai \
  --repository-format=docker \
  --location=us-central1

# Build and push
gcloud builds submit \
  --tag us-central1-docker.pkg.dev/YOUR_PROJECT/thinnestai/backend:latest \
  --dockerfile Dockerfile.backend

6. Deploy to Cloud Run

gcloud run deploy thinnestai-backend \
  --image us-central1-docker.pkg.dev/YOUR_PROJECT/thinnestai/backend:latest \
  --region us-central1 \
  --platform managed \
  --memory 2Gi \
  --cpu 2 \
  --min-instances 0 \
  --max-instances 10 \
  --set-env-vars "ENVIRONMENT=production" \
  --add-cloudsql-instances YOUR_PROJECT:us-central1:thinnestai-db \
  --set-secrets "OPENAI_API_KEY=OPENAI_API_KEY:latest,ENCRYPTION_KEY=ENCRYPTION_KEY:latest" \
  --allow-unauthenticated

7. Deploy Workers

gcloud run deploy thinnestai-workers \
  --image us-central1-docker.pkg.dev/YOUR_PROJECT/thinnestai/workers:latest \
  --region us-central1 \
  --platform managed \
  --memory 1Gi \
  --cpu 1 \
  --min-instances 1 \
  --max-instances 5 \
  --add-cloudsql-instances YOUR_PROJECT:us-central1:thinnestai-db \
  --set-secrets "OPENAI_API_KEY=OPENAI_API_KEY:latest" \
  --no-allow-unauthenticated

8. Run Migrations

# Using the deploy script
bash scripts/gcp-deploy/deploy.sh
# Choose option 5: Run database migrations

# Or manually
gcloud run jobs execute thinnestai-migrate --region us-central1

Cloud SQL Configuration

Connection

Cloud Run connects to Cloud SQL via a Unix domain socket. The connection string uses this format:

PG_DB_URL=postgresql://postgres:PASSWORD@/agno?host=/cloudsql/PROJECT:REGION:INSTANCE

Backups

Enable automated backups:

gcloud sql instances patch thinnestai-db \
  --backup-start-time=03:00 \
  --enable-point-in-time-recovery

Manual backup:

bash scripts/gcp-deploy/06-backup-database.sh

Scaling

For production workloads, upgrade from db-f1-micro:

gcloud sql instances patch thinnestai-db \
  --tier=db-custom-2-8192

Memorystore (Redis) Configuration

Connection

Cloud Run connects to Memorystore via the VPC network. Set the Redis URL:

REDIS_URL=redis://REDIS_HOST_IP:6379

Monitoring

View Redis metrics in the GCP Console under Memorystore > Redis > Instances > thinnestai-redis.

Secret Manager

All sensitive configuration is stored in Secret Manager. Never put secrets in environment variables directly.

Adding a New Secret

echo -n "secret-value" | \
  gcloud secrets create SECRET_NAME --data-file=-

Updating a Secret

echo -n "new-secret-value" | \
  gcloud secrets versions add SECRET_NAME --data-file=-

Granting Access

The Cloud Run service account needs access to read secrets:

gcloud secrets add-iam-policy-binding SECRET_NAME \
  --member="serviceAccount:YOUR_SERVICE_ACCOUNT" \
  --role="roles/secretmanager.secretAccessor"

Custom Domain

To use a custom domain with your Cloud Run service:

gcloud run domain-mappings create \
  --service thinnestai-backend \
  --domain api.yourdomain.com \
  --region us-central1

Then add the DNS records shown in the output to your domain registrar.

Redeploying After Code Changes

# Quick redeploy
./scripts/gcp-deploy/redeploy.sh

# Or manually
gcloud builds submit \
  --tag us-central1-docker.pkg.dev/YOUR_PROJECT/thinnestai/backend:latest \
  --dockerfile Dockerfile.backend

gcloud run deploy thinnestai-backend \
  --image us-central1-docker.pkg.dev/YOUR_PROJECT/thinnestai/backend:latest \
  --region us-central1

Viewing Logs

# Via deploy script
bash scripts/gcp-deploy/07-view-logs.sh

# Via gcloud
gcloud run services logs read thinnestai-backend --region us-central1 --limit 100

# Stream logs
gcloud run services logs tail thinnestai-backend --region us-central1

Verifying the Deployment

# Health check
curl https://your-cloud-run-url/api/health

# Via deploy script
bash scripts/gcp-deploy/deploy.sh
# Choose option 8: Verify deployment

Cost Estimates

ServiceEstimated Monthly Cost
Cloud SQL (db-f1-micro)~$10
Cloud Run (backend)~$5-50 (scales to zero)
Cloud Run (workers)~$10-30
Memorystore (1GB)~$35
Secret Manager< $1
Artifact Registry< $1
Total~$60-125/month

Costs scale with usage. Cloud Run charges only when handling requests.

Cleanup

To remove all GCP resources:

./scripts/gcp-deploy/deploy.sh
# Choose option 9: Cleanup

# Or use the cleanup script
bash scripts/gcp-deploy/cleanup-all.sh

Warning: This permanently deletes all data including your database. Always create a backup first.

Next Steps

On this page