268 lines
7.8 KiB
Markdown
268 lines
7.8 KiB
Markdown
# Google Cloud Build Setup Guide
|
|
|
|
## Overview
|
|
|
|
This guide explains how to configure Google Cloud Build for automatic deployment of the XTablo API to Cloud Run.
|
|
|
|
## Prerequisites
|
|
|
|
1. Google Cloud Project with billing enabled
|
|
2. Cloud Build API enabled
|
|
3. Cloud Run API enabled
|
|
4. Secret Manager API enabled
|
|
5. Artifact Registry repository created
|
|
|
|
## Required Substitution Variables
|
|
|
|
The `cloudbuild.yaml` uses substitution variables that must be configured in your Cloud Build trigger. Here's what each variable is for:
|
|
|
|
### Build Configuration Variables
|
|
|
|
| Variable | Description | Example |
|
|
|----------|-------------|---------|
|
|
| `$_NODE_ENV` | Environment (staging/production) | `production` |
|
|
| `$_AR_PROJECT_ID` | Artifact Registry project ID | `your-project-id` |
|
|
| `$_AR_REPOSITORY` | Artifact Registry repository name | `xtablo` |
|
|
| `$_SERVICE_NAME` | Cloud Run service name | `xtablo-api` |
|
|
|
|
### Application Environment Variables
|
|
|
|
| Variable | Description | Example |
|
|
|----------|-------------|---------|
|
|
| `$_SUPABASE_URL` | Supabase project URL | `https://xxx.supabase.co` |
|
|
| `$_STREAM_CHAT_API_KEY` | Stream Chat API key | `your-stream-api-key` |
|
|
| `$_EMAIL_USER` | Email sender address | `noreply@xtablo.com` |
|
|
| `$_EMAIL_CLIENT_ID` | OAuth2 client ID for email | `your-client-id` |
|
|
| `$_R2_ACCOUNT_ID` | Cloudflare R2 account ID | `your-r2-account-id` |
|
|
| `$_CORS_ORIGIN` | CORS allowed origin | `https://app.xtablo.com` |
|
|
| `$_XTABLO_URL` | Frontend application URL | `https://app.xtablo.com` |
|
|
|
|
## Setting Up Substitution Variables
|
|
|
|
### Option 1: Via Google Cloud Console
|
|
|
|
1. Go to Cloud Build > Triggers
|
|
2. Select your trigger (or create a new one)
|
|
3. Scroll to "Substitution variables"
|
|
4. Add each variable with its value:
|
|
```
|
|
_NODE_ENV = production
|
|
_AR_PROJECT_ID = your-project-id
|
|
_AR_REPOSITORY = xtablo
|
|
_SERVICE_NAME = xtablo-api
|
|
_SUPABASE_URL = https://your-project.supabase.co
|
|
_STREAM_CHAT_API_KEY = your-key
|
|
_EMAIL_USER = noreply@xtablo.com
|
|
_EMAIL_CLIENT_ID = your-client-id
|
|
_R2_ACCOUNT_ID = your-account-id
|
|
_CORS_ORIGIN = https://app.xtablo.com
|
|
_XTABLO_URL = https://app.xtablo.com
|
|
```
|
|
|
|
### Option 2: Via gcloud CLI
|
|
|
|
```bash
|
|
gcloud builds triggers create github \
|
|
--name="xtablo-api-production" \
|
|
--repo-name="xtablo-source" \
|
|
--repo-owner="your-github-org" \
|
|
--branch-pattern="^main$" \
|
|
--build-config="apps/api/cloudbuild.yaml" \
|
|
--substitutions='
|
|
_NODE_ENV=production,
|
|
_AR_PROJECT_ID=your-project-id,
|
|
_AR_REPOSITORY=xtablo,
|
|
_SERVICE_NAME=xtablo-api,
|
|
_SUPABASE_URL=https://your-project.supabase.co,
|
|
_STREAM_CHAT_API_KEY=your-key,
|
|
_EMAIL_USER=noreply@xtablo.com,
|
|
_EMAIL_CLIENT_ID=your-client-id,
|
|
_R2_ACCOUNT_ID=your-account-id,
|
|
_CORS_ORIGIN=https://app.xtablo.com,
|
|
_XTABLO_URL=https://app.xtablo.com
|
|
'
|
|
```
|
|
|
|
## Setting Up Secrets in Secret Manager
|
|
|
|
The sensitive values (API keys, tokens, etc.) are stored in Google Cloud Secret Manager. Create these secrets:
|
|
|
|
### Required Secrets
|
|
|
|
```bash
|
|
# Supabase secrets
|
|
echo -n "your-service-role-key" | gcloud secrets create supabase-service-role-key --data-file=-
|
|
echo -n "your-connection-string" | gcloud secrets create supabase-connection-string --data-file=-
|
|
echo -n "your-ca-cert" | gcloud secrets create supabase-ca-cert --data-file=-
|
|
|
|
# Stream Chat secret
|
|
echo -n "your-stream-secret" | gcloud secrets create stream-chat-api-secret --data-file=-
|
|
|
|
# Stripe secrets
|
|
echo -n "your-stripe-key" | gcloud secrets create stripe-secret-key --data-file=-
|
|
echo -n "your-webhook-secret" | gcloud secrets create stripe-webhook-secret --data-file=-
|
|
|
|
# Email secrets
|
|
echo -n "your-client-secret" | gcloud secrets create email-client-secret --data-file=-
|
|
echo -n "your-refresh-token" | gcloud secrets create email-refresh-token --data-file=-
|
|
|
|
# R2 (Cloudflare) secrets
|
|
echo -n "your-access-key-id" | gcloud secrets create r2-access-key-id --data-file=-
|
|
echo -n "your-secret-access-key" | gcloud secrets create r2-secret-access-key --data-file=-
|
|
```
|
|
|
|
### Grant Cloud Run Access to Secrets
|
|
|
|
```bash
|
|
# Get your Cloud Run service account
|
|
PROJECT_ID="your-project-id"
|
|
SERVICE_ACCOUNT="${PROJECT_ID}@appspot.gserviceaccount.com"
|
|
|
|
# Grant access to each secret
|
|
for secret in \
|
|
supabase-service-role-key \
|
|
supabase-connection-string \
|
|
supabase-ca-cert \
|
|
stream-chat-api-secret \
|
|
stripe-secret-key \
|
|
stripe-webhook-secret \
|
|
email-client-secret \
|
|
email-refresh-token \
|
|
r2-access-key-id \
|
|
r2-secret-access-key
|
|
do
|
|
gcloud secrets add-iam-policy-binding $secret \
|
|
--member="serviceAccount:${SERVICE_ACCOUNT}" \
|
|
--role="roles/secretmanager.secretAccessor"
|
|
done
|
|
```
|
|
|
|
## Environment-Specific Configurations
|
|
|
|
### Production Trigger
|
|
|
|
```yaml
|
|
_NODE_ENV: production
|
|
_CORS_ORIGIN: https://app.xtablo.com
|
|
_XTABLO_URL: https://app.xtablo.com
|
|
```
|
|
|
|
### Staging Trigger
|
|
|
|
```yaml
|
|
_NODE_ENV: staging
|
|
_CORS_ORIGIN: https://staging.xtablo.com
|
|
_XTABLO_URL: https://staging.xtablo.com
|
|
_SERVICE_NAME: xtablo-api-staging
|
|
```
|
|
|
|
## Verifying the Setup
|
|
|
|
After creating your trigger and setting up the secrets:
|
|
|
|
1. **Test the trigger manually:**
|
|
```bash
|
|
gcloud builds triggers run xtablo-api-production --branch=main
|
|
```
|
|
|
|
2. **Check the build logs:**
|
|
```bash
|
|
gcloud builds list --limit=5
|
|
gcloud builds log BUILD_ID
|
|
```
|
|
|
|
3. **Verify the deployed service:**
|
|
```bash
|
|
gcloud run services describe xtablo-api --region=europe-west1
|
|
```
|
|
|
|
4. **Check environment variables:**
|
|
```bash
|
|
gcloud run services describe xtablo-api --region=europe-west1 --format="value(spec.template.spec.containers[0].env)"
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Build Fails with "Missing Substitution Variable"
|
|
- Ensure all `$_VARIABLE` names are defined in your trigger
|
|
- Check for typos in variable names
|
|
|
|
### Cloud Run Deployment Fails
|
|
- Verify the service account has necessary permissions
|
|
- Check that the Artifact Registry URL is correct
|
|
- Ensure the image was successfully pushed
|
|
|
|
### Application Fails to Start
|
|
- Check Cloud Run logs: `gcloud run logs read --service=xtablo-api --region=europe-west1`
|
|
- Verify all secrets are accessible to the service account
|
|
- Check that environment variables are properly set
|
|
|
|
### Secret Access Denied
|
|
- Ensure the Cloud Run service account has `roles/secretmanager.secretAccessor` for each secret
|
|
- Verify secrets exist: `gcloud secrets list`
|
|
|
|
## Additional Configuration
|
|
|
|
### Service Account Permissions
|
|
|
|
Your Cloud Run service needs these roles:
|
|
|
|
```bash
|
|
gcloud projects add-iam-policy-binding $PROJECT_ID \
|
|
--member="serviceAccount:${SERVICE_ACCOUNT}" \
|
|
--role="roles/secretmanager.secretAccessor"
|
|
|
|
gcloud projects add-iam-policy-binding $PROJECT_ID \
|
|
--member="serviceAccount:${SERVICE_ACCOUNT}" \
|
|
--role="roles/cloudsql.client" # If using Cloud SQL
|
|
```
|
|
|
|
### Cloud Run Configuration Options
|
|
|
|
You can add these to your `cloudbuild.yaml` deploy step:
|
|
|
|
```yaml
|
|
- '--memory'
|
|
- '512Mi'
|
|
- '--cpu'
|
|
- '1'
|
|
- '--max-instances'
|
|
- '10'
|
|
- '--min-instances'
|
|
- '0'
|
|
- '--concurrency'
|
|
- '80'
|
|
- '--timeout'
|
|
- '300'
|
|
- '--allow-unauthenticated' # If your API is public
|
|
```
|
|
|
|
## Manual Deployment
|
|
|
|
If you need to deploy manually without Cloud Build:
|
|
|
|
```bash
|
|
# Build the image
|
|
docker build -f apps/api/Dockerfile --target production -t xtablo-api:latest .
|
|
|
|
# Tag for Artifact Registry
|
|
docker tag xtablo-api:latest europe-west1-docker.pkg.dev/PROJECT_ID/xtablo/xtablo-api:latest
|
|
|
|
# Push to Artifact Registry
|
|
docker push europe-west1-docker.pkg.dev/PROJECT_ID/xtablo/xtablo-api:latest
|
|
|
|
# Deploy to Cloud Run
|
|
gcloud run deploy xtablo-api \
|
|
--image=europe-west1-docker.pkg.dev/PROJECT_ID/xtablo/xtablo-api:latest \
|
|
--region=europe-west1 \
|
|
--set-env-vars="NODE_ENV=production,PORT=8080,..." \
|
|
--update-secrets="SUPABASE_SERVICE_ROLE_KEY=supabase-service-role-key:latest,..."
|
|
```
|
|
|
|
## Support
|
|
|
|
For more information:
|
|
- [Cloud Build Documentation](https://cloud.google.com/build/docs)
|
|
- [Cloud Run Documentation](https://cloud.google.com/run/docs)
|
|
- [Secret Manager Documentation](https://cloud.google.com/secret-manager/docs)
|
|
|