Jiffoo Docs
Deployment

GCP Cloud Run Deployment

Deploy Jiffoo Mall on Google Cloud Platform using Cloud Run

GCP Cloud Run Deployment

Prerequisites

  • Google Cloud CLI (gcloud) installed
  • GCP Project with billing enabled
  • Docker for building images
  • Appropriate IAM permissions (Cloud Run Admin, Cloud SQL Admin)

Architecture Overview

This guide deploys Jiffoo Mall using:

  • Cloud Run for serverless container orchestration
  • Cloud Load Balancing for traffic distribution
  • Cloud SQL PostgreSQL for database
  • Memorystore Redis for caching
  • Secret Manager for sensitive configuration
  • Artifact Registry for container images

Quick Start

1. Configure GCP CLI

# Login to GCP
gcloud auth login

# Set your project
gcloud config set project <your-project-id>

# Set default region
gcloud config set run/region us-central1

2. Enable Required APIs

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

3. Create Artifact Registry Repository

gcloud artifacts repositories create jiffoo \
  --repository-format=docker \
  --location=us-central1 \
  --description="Jiffoo Mall container images"

4. Build and Push Images

# Configure Docker authentication
gcloud auth configure-docker us-central1-docker.pkg.dev

# Build and push API
docker build -t us-central1-docker.pkg.dev/<project-id>/jiffoo/api:latest \
  -f apps/api/Dockerfile .
docker push us-central1-docker.pkg.dev/<project-id>/jiffoo/api:latest

# Build and push Shop
docker build -t us-central1-docker.pkg.dev/<project-id>/jiffoo/shop:latest \
  -f apps/shop/Dockerfile .
docker push us-central1-docker.pkg.dev/<project-id>/jiffoo/shop:latest

# Build and push Admin
docker build -t us-central1-docker.pkg.dev/<project-id>/jiffoo/admin:latest \
  -f apps/admin/Dockerfile .
docker push us-central1-docker.pkg.dev/<project-id>/jiffoo/admin:latest

5. Create Cloud SQL PostgreSQL Instance

gcloud sql instances create jiffoo-db \
  --database-version=POSTGRES_15 \
  --tier=db-f1-micro \
  --region=us-central1 \
  --root-password=<your-password> \
  --backup-start-time=03:00

# Create database
gcloud sql databases create jiffoo --instance=jiffoo-db

# Get connection name (needed later)
gcloud sql instances describe jiffoo-db --format="value(connectionName)"

6. Create Memorystore Redis Instance

gcloud redis instances create jiffoo-redis \
  --size=1 \
  --region=us-central1 \
  --redis-version=redis_7_0 \
  --tier=basic

# Get Redis host (needed later)
gcloud redis instances describe jiffoo-redis \
  --region=us-central1 \
  --format="value(host)"

Secrets Management

Store sensitive configuration in Secret Manager:

# Database URL
echo -n "postgresql://postgres:<password>@<cloud-sql-private-ip>:5432/jiffoo" | \
  gcloud secrets create database-url --data-file=-

# Redis URL
echo -n "redis://<memorystore-host>:6379" | \
  gcloud secrets create redis-url --data-file=-

# JWT Secret
echo -n "<your-jwt-secret>" | \
  gcloud secrets create jwt-secret --data-file=-

# Grant Cloud Run access to secrets
gcloud secrets add-iam-policy-binding database-url \
  --member="serviceAccount:<project-number>[email protected]" \
  --role="roles/secretmanager.secretAccessor"

gcloud secrets add-iam-policy-binding redis-url \
  --member="serviceAccount:<project-number>[email protected]" \
  --role="roles/secretmanager.secretAccessor"

gcloud secrets add-iam-policy-binding jwt-secret \
  --member="serviceAccount:<project-number>[email protected]" \
  --role="roles/secretmanager.secretAccessor"

Deploy Cloud Run Services

Deploy API Service

gcloud run deploy jiffoo-api \
  --image=us-central1-docker.pkg.dev/<project-id>/jiffoo/api:latest \
  --platform=managed \
  --region=us-central1 \
  --allow-unauthenticated \
  --port=3001 \
  --cpu=1 \
  --memory=1Gi \
  --min-instances=0 \
  --max-instances=10 \
  --set-env-vars="NODE_ENV=production" \
  --set-secrets="DATABASE_URL=database-url:latest,REDIS_URL=redis-url:latest,JWT_SECRET=jwt-secret:latest" \
  --add-cloudsql-instances=<project-id>:us-central1:jiffoo-db \
  --vpc-connector=<vpc-connector-name>

Deploy Shop Service

gcloud run deploy jiffoo-shop \
  --image=us-central1-docker.pkg.dev/<project-id>/jiffoo/shop:latest \
  --platform=managed \
  --region=us-central1 \
  --allow-unauthenticated \
  --port=3000 \
  --cpu=0.5 \
  --memory=512Mi \
  --min-instances=0 \
  --max-instances=10 \
  --set-env-vars="NEXT_PUBLIC_API_URL=https://jiffoo-api-<hash>-uc.a.run.app"

Deploy Admin Service

gcloud run deploy jiffoo-admin \
  --image=us-central1-docker.pkg.dev/<project-id>/jiffoo/admin:latest \
  --platform=managed \
  --region=us-central1 \
  --allow-unauthenticated \
  --port=3003 \
  --cpu=0.5 \
  --memory=512Mi \
  --min-instances=0 \
  --max-instances=10 \
  --set-env-vars="NEXT_PUBLIC_API_URL=https://jiffoo-api-<hash>-uc.a.run.app"

VPC Connector (For Private Resources)

If using private Cloud SQL or Memorystore:

gcloud compute networks vpc-access connectors create jiffoo-connector \
  --region=us-central1 \
  --subnet=default \
  --subnet-project=<project-id> \
  --min-instances=2 \
  --max-instances=3 \
  --machine-type=e2-micro

Custom Domain Setup

1. Map Custom Domain

# Map domain to API
gcloud run domain-mappings create \
  --service=jiffoo-api \
  --domain=api.yourdomain.com \
  --region=us-central1

# Map domain to Shop
gcloud run domain-mappings create \
  --service=jiffoo-shop \
  --domain=shop.yourdomain.com \
  --region=us-central1

# Map domain to Admin
gcloud run domain-mappings create \
  --service=jiffoo-admin \
  --domain=admin.yourdomain.com \
  --region=us-central1

2. Update DNS Records

Add the DNS records shown in the domain mapping output to your DNS provider.

Database Migrations

Run migrations using Cloud Run Jobs:

# Create migration job
gcloud run jobs create jiffoo-migrations \
  --image=us-central1-docker.pkg.dev/<project-id>/jiffoo/api:latest \
  --region=us-central1 \
  --set-secrets="DATABASE_URL=database-url:latest" \
  --add-cloudsql-instances=<project-id>:us-central1:jiffoo-db \
  --vpc-connector=jiffoo-connector \
  --command="pnpm" \
  --args="db:push"

# Execute migration
gcloud run jobs execute jiffoo-migrations --region=us-central1

Cloud Logging

View logs for your services:

# API logs
gcloud logs tail "resource.type=cloud_run_revision AND resource.labels.service_name=jiffoo-api" --follow

# Shop logs
gcloud logs tail "resource.type=cloud_run_revision AND resource.labels.service_name=jiffoo-shop" --follow

# Admin logs
gcloud logs tail "resource.type=cloud_run_revision AND resource.labels.service_name=jiffoo-admin" --follow

# Filter by severity
gcloud logs read "resource.type=cloud_run_revision AND resource.labels.service_name=jiffoo-api AND severity>=ERROR" --limit=50

Scaling Configuration

Cloud Run auto-scales by default. Configure limits:

Update Service Concurrency

gcloud run services update jiffoo-api \
  --region=us-central1 \
  --concurrency=80 \
  --min-instances=1 \
  --max-instances=20

CPU Allocation

# CPU always allocated (better performance, higher cost)
gcloud run services update jiffoo-api \
  --region=us-central1 \
  --cpu-throttling

# CPU only during request (lower cost)
gcloud run services update jiffoo-api \
  --region=us-central1 \
  --no-cpu-throttling

Monitoring

Cloud Monitoring Dashboards

Create a custom dashboard:

# View service metrics
gcloud monitoring dashboards create --config-from-file=dashboard.json

dashboard.json:

{
  "displayName": "Jiffoo Mall Metrics",
  "dashboardFilters": [],
  "mosaicLayout": {
    "columns": 12,
    "tiles": [
      {
        "width": 6,
        "height": 4,
        "widget": {
          "title": "Request Count",
          "xyChart": {
            "dataSets": [{
              "timeSeriesQuery": {
                "timeSeriesFilter": {
                  "filter": "resource.type=\"cloud_run_revision\" AND resource.labels.service_name=\"jiffoo-api\"",
                  "aggregation": {
                    "alignmentPeriod": "60s",
                    "perSeriesAligner": "ALIGN_RATE"
                  }
                }
              }
            }]
          }
        }
      }
    ]
  }
}

Cloud Monitoring Alerts

# High error rate alert
gcloud alpha monitoring policies create \
  --notification-channels=<channel-id> \
  --display-name="Jiffoo API High Error Rate" \
  --condition-display-name="Error rate > 5%" \
  --condition-threshold-value=0.05 \
  --condition-threshold-duration=300s

Troubleshooting

Service Not Starting

Check service status and logs:

gcloud run services describe jiffoo-api --region=us-central1

gcloud logs read "resource.type=cloud_run_revision AND resource.labels.service_name=jiffoo-api" \
  --limit=50 --format=json

Deployment Failures

View revision details:

gcloud run revisions list \
  --service=jiffoo-api \
  --region=us-central1

gcloud run revisions describe <revision-name> \
  --region=us-central1

Database Connection Issues

Verify Cloud SQL connection:

# Check if Cloud SQL instance is running
gcloud sql instances describe jiffoo-db

# Test connection using Cloud SQL Proxy
cloud_sql_proxy -instances=<connection-name>=tcp:5432

Memory Issues

Check container memory usage:

gcloud monitoring time-series list \
  --filter='metric.type="run.googleapis.com/container/memory/utilizations"' \
  --format=json

If containers are OOMing, increase memory:

gcloud run services update jiffoo-api \
  --region=us-central1 \
  --memory=2Gi

Cold Start Optimization

Reduce cold starts with minimum instances:

gcloud run services update jiffoo-api \
  --region=us-central1 \
  --min-instances=1

Cost Optimization

  • Use minimum instances = 0 for non-critical services (shop, admin)
  • Set minimum instances = 1 only for API to reduce cold starts
  • Configure request timeout to prevent long-running requests
  • Use Cloud SQL shared-core instances (db-f1-micro) for development
  • Enable Cloud SQL automatic backups with 7-day retention
  • Use Memorystore basic tier for non-HA workloads
  • Monitor with Cloud Billing Budget Alerts
# Set request timeout
gcloud run services update jiffoo-api \
  --region=us-central1 \
  --timeout=60s

# Configure auto-delete for old revisions
gcloud run services update jiffoo-api \
  --region=us-central1 \
  --revision-suffix=v$(date +%Y%m%d-%H%M%S)

CI/CD Integration

GitHub Actions Example

name: Deploy to Cloud Run

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - id: auth
        uses: google-github-actions/auth@v1
        with:
          credentials_json: ${{ secrets.GCP_SA_KEY }}

      - name: Set up Cloud SDK
        uses: google-github-actions/setup-gcloud@v1

      - name: Configure Docker
        run: gcloud auth configure-docker us-central1-docker.pkg.dev

      - name: Build and Push API
        run: |
          docker build -t us-central1-docker.pkg.dev/${{ secrets.GCP_PROJECT }}/jiffoo/api:${{ github.sha }} \
            -f apps/api/Dockerfile .
          docker push us-central1-docker.pkg.dev/${{ secrets.GCP_PROJECT }}/jiffoo/api:${{ github.sha }}

      - name: Deploy to Cloud Run
        run: |
          gcloud run deploy jiffoo-api \
            --image=us-central1-docker.pkg.dev/${{ secrets.GCP_PROJECT }}/jiffoo/api:${{ github.sha }} \
            --region=us-central1 \
            --platform=managed

Using gcloud CLI

# Build and push new image
docker build -t us-central1-docker.pkg.dev/<project-id>/jiffoo/api:v2 \
  -f apps/api/Dockerfile .
docker push us-central1-docker.pkg.dev/<project-id>/jiffoo/api:v2

# Deploy new revision
gcloud run deploy jiffoo-api \
  --image=us-central1-docker.pkg.dev/<project-id>/jiffoo/api:v2 \
  --region=us-central1

# Gradual rollout (traffic splitting)
gcloud run services update-traffic jiffoo-api \
  --region=us-central1 \
  --to-revisions=LATEST=10,PREVIOUS=90

# Once validated, shift all traffic
gcloud run services update-traffic jiffoo-api \
  --region=us-central1 \
  --to-latest

Security Best Practices

1. Use IAM for Authentication

# Remove public access
gcloud run services remove-iam-policy-binding jiffoo-api \
  --region=us-central1 \
  --member="allUsers" \
  --role="roles/run.invoker"

# Grant specific service account access
gcloud run services add-iam-policy-binding jiffoo-api \
  --region=us-central1 \
  --member="serviceAccount:<sa-email>" \
  --role="roles/run.invoker"

2. Use VPC Service Controls

gcloud access-context-manager perimeters create jiffoo-perimeter \
  --title="Jiffoo Mall Services" \
  --resources=projects/<project-number> \
  --restricted-services=run.googleapis.com,sqladmin.googleapis.com

3. Enable Binary Authorization

gcloud container binauthz policy import policy.yaml

Backup and Disaster Recovery

Cloud SQL Backups

# Enable automated backups
gcloud sql instances patch jiffoo-db \
  --backup-start-time=03:00 \
  --backup-location=us

# Create on-demand backup
gcloud sql backups create \
  --instance=jiffoo-db \
  --description="Pre-deployment backup"

# Restore from backup
gcloud sql backups restore <backup-id> \
  --backup-instance=jiffoo-db \
  --backup-instance=jiffoo-db-restored

Export Database

# Export to Cloud Storage
gcloud sql export sql jiffoo-db \
  gs://<bucket-name>/backups/jiffoo-$(date +%Y%m%d).sql \
  --database=jiffoo

On this page