CROP
ProjectsParts Services

Deployment Guide - CROP Microservices

Last Updated: 2025-11-19 For: Dev/Staging/Production deployments Platform: Google Cloud Platform

Deployment Guide - CROP Microservices

Last Updated: 2025-11-19 For: Dev/Staging/Production deployments Platform: Google Cloud Platform


Table of Contents

  1. Prerequisites
  2. Quick Start
  3. Deploy Existing Service
  4. Deploy New Service
  5. Configuration Management
  6. Rollback Procedures
  7. Troubleshooting

Prerequisites

Required Tools

# Verify installations
gcloud --version    # Google Cloud SDK
docker --version    # Docker (for local builds)
bun --version       # Bun 1.3.2+
git --version       # Git

GCP Access

# Login to GCP
gcloud auth login

# Set project
gcloud config set project noted-bliss-466410-q6

# Configure Docker for GCR
gcloud auth configure-docker

Repository Access

# Clone repository
git clone <repository-url>
cd microservices

Quick Start

Deploy Search Service (Existing)

# From repository root
cd /Users/vova/Code/CROP/microservices

# Method 1: Build + Deploy in one command
gcloud run deploy search-service \
  --source services/search \
  --region us-east1 \
  --project noted-bliss-466410-q6 \
  --allow-unauthenticated

# Method 2: Using Cloud Build (recommended for production)
gcloud builds submit \
  --config services/search/cloudbuild.yaml \
  --project noted-bliss-466410-q6

Deployment time: 5-10 minutes


Deploy Existing Service

Step-by-Step Deployment

Step 1: Navigate to Repository Root

cd /Users/vova/Code/CROP/microservices

IMPORTANT: Always deploy from repository root, not from service directory!

Why: Dockerfiles use monorepo structure with shared packages/

Step 2: Choose Deployment Method

Option A: Direct Deploy (Simple, Slower)

gcloud run deploy <service-name> \
  --source services/<service-name> \
  --region us-east1 \
  --project noted-bliss-466410-q6 \
  --allow-unauthenticated \
  --execution-environment gen2

Pros:

  • Simple command
  • No need to build Docker image manually
  • Good for quick deployments

Cons:

  • Slower (rebuilds every time)
  • No caching between deployments
  • Limited control over build process

Option B: Build + Push + Deploy (Fast, More Control)

# 1. Build Docker image from repository root
docker build \
  -f services/<service-name>/Dockerfile \
  -t gcr.io/noted-bliss-466410-q6/<service-name>:$(git rev-parse --short HEAD) \
  -t gcr.io/noted-bliss-466410-q6/<service-name>:latest \
  .

# 2. Push to Container Registry
docker push --all-tags gcr.io/noted-bliss-466410-q6/<service-name>

# 3. Deploy to Cloud Run
gcloud run deploy <service-name> \
  --image gcr.io/noted-bliss-466410-q6/<service-name>:$(git rev-parse --short HEAD) \
  --region us-east1 \
  --project noted-bliss-466410-q6 \
  --allow-unauthenticated \
  --execution-environment gen2

Pros:

  • Faster (uses Docker build cache)
  • More control over build process
  • Can test image locally before deploy
  • Tagged with git commit SHA

Cons:

  • More commands
  • Requires Docker installed locally

Option C: Cloud Build (Production-Ready)

# Submit build to Cloud Build
gcloud builds submit \
  --config services/<service-name>/cloudbuild.yaml \
  --substitutions=_SERVICE_NAME=<service-name>,_REGION=us-east1 \
  --project noted-bliss-466410-q6

Pros:

  • Production-grade CI/CD
  • Automatic build + deploy
  • Build logs in Cloud Console
  • No local Docker required
  • Consistent builds

Cons:

  • Requires cloudbuild.yaml configuration
  • Slightly slower than local builds

Step 3: Verify Deployment

# Get service URL
gcloud run services describe <service-name> \
  --region us-east1 \
  --project noted-bliss-466410-q6 \
  --format='value(status.url)'

# Test health endpoint
curl <service-url>/health

# Check logs
gcloud logging tail --limit=50 \
  --filter="resource.type=cloud_run_revision AND resource.labels.service_name=<service-name>"

Deployment Examples

Example 1: Deploy Search Service

# Navigate to repo root
cd /Users/vova/Code/CROP/microservices

# Method A: Quick deploy
gcloud run deploy search-service \
  --source services/search \
  --region us-east1 \
  --allow-unauthenticated

# Method B: Build + Deploy
docker build -f services/search/Dockerfile -t gcr.io/noted-bliss-466410-q6/search-service:latest .
docker push gcr.io/noted-bliss-466410-q6/search-service:latest
gcloud run deploy search-service \
  --image gcr.io/noted-bliss-466410-q6/search-service:latest \
  --region us-east1 \
  --execution-environment gen2 \
  --vpc-connector crop-connector \
  --vpc-egress private-ranges-only

# Method C: Cloud Build
gcloud builds submit --config services/search/cloudbuild.yaml

Example 2: Deploy New Catalog Service

# First time deployment
cd /Users/vova/Code/CROP/microservices

# Build image
docker build -f services/catalog/Dockerfile -t gcr.io/noted-bliss-466410-q6/catalog-service:v1 .

# Push to registry
docker push gcr.io/noted-bliss-466410-q6/catalog-service:v1

# Deploy to Cloud Run
gcloud run deploy catalog-service \
  --image gcr.io/noted-bliss-466410-q6/catalog-service:v1 \
  --region us-east1 \
  --project noted-bliss-466410-q6 \
  --allow-unauthenticated \
  --execution-environment gen2 \
  --set-env-vars="MONGODB_URI=mongodb://...,DATABASE_NAME=crop_dev" \
  --memory=512Mi \
  --cpu=1 \
  --concurrency=80 \
  --max-instances=10

Configuration Management

Environment Variables

Method 1: Via Command Line

gcloud run services update <service-name> \
  --update-env-vars KEY1=value1,KEY2=value2 \
  --region us-east1

Method 2: Via YAML File

Create env.yaml:

MONGODB_URI: mongodb://...
ELASTICSEARCH_URL: http://10.0.0.52:9200
SEARCH_INDEX_NAME: parts_current

Deploy:

gcloud run services update <service-name> \
  --env-vars-file env.yaml \
  --region us-east1

Method 3: From .env.production File

# Load from file
source .env.production

# Deploy with variables
gcloud run services update <service-name> \
  --update-env-vars="$(cat .env.production | grep -v '^#' | xargs | tr ' ' ',')" \
  --region us-east1

Secrets Management

Using Secret Manager (Recommended for Production):

# Create secret
echo -n "mongodb://user:pass@host/db" | \
  gcloud secrets create mongodb-uri \
  --data-file=- \
  --project noted-bliss-466410-q6

# Grant access to Cloud Run service account
gcloud secrets add-iam-policy-binding mongodb-uri \
  --member="serviceAccount:222426967009-compute@developer.gserviceaccount.com" \
  --role="roles/secretmanager.secretAccessor"

# Update service to use secret
gcloud run services update <service-name> \
  --update-secrets="MONGODB_URI=mongodb-uri:latest" \
  --region us-east1

VPC Configuration

Add VPC Access Connector:

gcloud run services update <service-name> \
  --vpc-connector projects/noted-bliss-466410-q6/locations/us-east1/connectors/crop-connector \
  --vpc-egress private-ranges-only \
  --execution-environment gen2 \
  --region us-east1

Remove VPC Access:

gcloud run services update <service-name> \
  --clear-vpc-connector \
  --region us-east1

Advanced Deployment Options

Resource Limits

gcloud run deploy <service-name> \
  --image <image-url> \
  --memory 512Mi \
  --cpu 1 \
  --timeout 300s \
  --concurrency 80 \
  --min-instances 0 \
  --max-instances 10 \
  --region us-east1

Traffic Splitting (Blue/Green Deployment)

# Deploy new revision without routing traffic
gcloud run deploy <service-name> \
  --image <new-image> \
  --no-traffic \
  --tag canary \
  --region us-east1

# Test canary revision
curl https://canary---<service-name>-<hash>.run.app/health

# Gradually shift traffic
gcloud run services update-traffic <service-name> \
  --to-revisions <new-revision>=10,<old-revision>=90 \
  --region us-east1

# If successful, shift all traffic
gcloud run services update-traffic <service-name> \
  --to-latest \
  --region us-east1

Custom Domains

# Map custom domain
gcloud run domain-mappings create \
  --service <service-name> \
  --domain api.example.com \
  --region us-east1

Rollback Procedures

Quick Rollback to Previous Revision

# List revisions
gcloud run revisions list \
  --service <service-name> \
  --region us-east1 \
  --limit 10

# Rollback to specific revision
gcloud run services update-traffic <service-name> \
  --to-revisions <previous-revision>=100 \
  --region us-east1

Example: Rollback Search Service

# Show recent revisions
gcloud run revisions list --service search-service --region us-east1

# Rollback to revision 00020
gcloud run services update-traffic search-service \
  --to-revisions search-service-00020-gps=100 \
  --region us-east1

Recovery Time: 30-60 seconds


Monitoring Deployment

Check Deployment Status

# Get service details
gcloud run services describe <service-name> \
  --region us-east1 \
  --format yaml

# Get latest revision
gcloud run services describe <service-name> \
  --region us-east1 \
  --format='value(status.latestReadyRevisionName)'

Watch Logs During Deployment

# Tail logs in real-time
gcloud logging tail --limit=100 \
  --filter="resource.type=cloud_run_revision AND resource.labels.service_name=<service-name>"

Check Revision Health

# Get revision status
gcloud run revisions describe <revision-name> \
  --region us-east1 \
  --format='value(status.conditions[0].status,status.conditions[0].message)'

Troubleshooting

Common Issues

Issue 1: "Dockerfile not found"

Error:

ERROR: failed to build: failed to get filesystem: unable to find Dockerfile

Solution:

# Make sure you're in repository root
cd /Users/vova/Code/CROP/microservices

# Verify Dockerfile path
ls -la services/<service-name>/Dockerfile

# Build from root with correct path
docker build -f services/<service-name>/Dockerfile -t <tag> .

Issue 2: "VPC connector not found"

Error:

ERROR: (gcloud.run.services.update) Cannot find VPC Access connector

Solution:

# Use full resource path
gcloud run services update <service-name> \
  --vpc-connector projects/noted-bliss-466410-q6/locations/us-east1/connectors/crop-connector \
  --region us-east1

Issue 3: "Permission denied"

Error:

ERROR: (gcloud.run.deploy) Permission denied

Solution:

# Check authentication
gcloud auth list

# Re-authenticate
gcloud auth login

# Verify project
gcloud config get-value project

# Check IAM roles
gcloud projects get-iam-policy noted-bliss-466410-q6 \
  --flatten="bindings[].members" \
  --filter="bindings.members:$(gcloud config get-value account)"

Issue 4: "Build timeout"

Error:

ERROR: build timed out after 10m

Solution:

# Increase timeout in cloudbuild.yaml
timeout: 1800s  # 30 minutes

# Or via command line
gcloud builds submit --timeout=30m

Issue 5: "Service unhealthy after deployment"

Symptoms: Deployment succeeds but service returns errors

Diagnosis:

# Check logs
gcloud logging read "resource.type=cloud_run_revision \
  AND resource.labels.service_name=<service-name> \
  AND severity>=ERROR" \
  --limit=50

# Test health endpoint
curl <service-url>/health

# Check environment variables
gcloud run services describe <service-name> \
  --region us-east1 \
  --format='value(spec.template.spec.containers[0].env)'

Common causes:

  • Missing environment variables
  • Database connection failure
  • VPC configuration missing
  • Wrong image deployed

Deployment Checklist

Pre-Deployment

  • Code reviewed and tested
  • Unit tests passing
  • Integration tests passing
  • Environment variables documented
  • Secrets created in Secret Manager (production)
  • VPC requirements identified
  • Resource limits calculated
  • Rollback plan prepared

During Deployment

  • Deploy from repository root
  • Use correct Dockerfile path
  • Tag images with git commit SHA
  • Configure VPC connector (if needed)
  • Set environment variables
  • Set resource limits
  • Configure health checks

Post-Deployment

  • Verify health endpoint returns OK
  • Check logs for errors
  • Test API endpoints
  • Verify database connectivity
  • Monitor metrics for 15 minutes
  • Update documentation
  • Notify team

CI/CD Integration

Create .github/workflows/<service-name>-deploy.yml:

name: Deploy <Service Name>

on:
  push:
    branches: [main]
    paths:
      - 'services/<service-name>/**'
      - 'packages/**'

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: 'Build and Deploy'
        run: |
          gcloud builds submit \
            --config services/<service-name>/cloudbuild.yaml \
            --project noted-bliss-466410-q6

See: CI_CD_GUIDE.md for complete setup


Service-Specific Notes

Search Service

Special Requirements:

  • VPC Access Connector required
  • Elasticsearch connection (10.0.0.52)
  • MongoDB via PSC (10.0.0.2)

Deployment:

gcloud run deploy search-service \
  --image gcr.io/noted-bliss-466410-q6/search-service:latest \
  --execution-environment gen2 \
  --vpc-connector projects/noted-bliss-466410-q6/locations/us-east1/connectors/crop-connector \
  --vpc-egress private-ranges-only \
  --region us-east1

Health Analytics Service

No special requirements - standard deployment


Best Practices

  1. Always deploy from repository root
  2. Use Git commit SHA for image tags
  3. Test in staging before production
  4. Use Cloud Build for production
  5. Configure health checks
  6. Set resource limits explicitly
  7. Use Secret Manager for sensitive data
  8. Monitor logs after deployment
  9. Prepare rollback plan
  10. Document all changes

Quick Reference

Common Commands

# Deploy service
gcloud run deploy <service> --source services/<service> --region us-east1

# Update environment variable
gcloud run services update <service> --update-env-vars KEY=value --region us-east1

# Rollback
gcloud run services update-traffic <service> --to-revisions <revision>=100 --region us-east1

# View logs
gcloud logging tail --filter="resource.labels.service_name=<service>"

# Get service URL
gcloud run services describe <service> --region us-east1 --format='value(status.url)'

Next Steps:

  • Read NEW_SERVICE_TEMPLATE.md to create new services
  • Read CI_CD_GUIDE.md for automated deployments
  • Check service-specific docs in services/<service-name>/

Maintained by: Dev Team Last Review: 2025-11-19

On this page