📦
Bunty

Deploy to Google Cloud Platform

Deploy your Bunty application to Google Cloud Platform (GCP) using services like Cloud Run, App Engine, Compute Engine, or GKE.

Prerequisites

  • GCP account
  • gcloud CLI installed
  • Docker installed

Setup gcloud CLI

# Install gcloud CLI
# Download from: https://cloud.google.com/sdk/docs/install

# Initialize
gcloud init

# Set project
gcloud config set project YOUR_PROJECT_ID

# Authenticate
gcloud auth login

Cloud Run is the easiest way to deploy containerized applications with automatic scaling.

Create Dockerfile

FROM oven/bun:1-alpine
WORKDIR /app
COPY package.json bun.lockb ./
RUN bun install --frozen-lockfile --production
COPY . .
EXPOSE 8080
CMD ["bun", "run", "src/main.ts"]

Deploy with One Command

# Deploy directly from source
gcloud run deploy bunty-app \
  --source . \
  --platform managed \
  --region us-central1 \
  --allow-unauthenticated \
  --set-env-vars NODE_ENV=production,PORT=8080

Deploy from Container Registry

# Build and push to Artifact Registry
gcloud builds submit --tag gcr.io/YOUR_PROJECT_ID/bunty-app

# Deploy
gcloud run deploy bunty-app \
  --image gcr.io/YOUR_PROJECT_ID/bunty-app \
  --platform managed \
  --region us-central1 \
  --allow-unauthenticated \
  --port 8080 \
  --cpu 1 \
  --memory 512Mi \
  --min-instances 0 \
  --max-instances 10 \
  --set-env-vars NODE_ENV=production

With Cloud SQL

# Create Cloud SQL instance
gcloud sql instances create bunty-db \
  --database-version=POSTGRES_15 \
  --tier=db-f1-micro \
  --region=us-central1

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

# Deploy with Cloud SQL connection
gcloud run deploy bunty-app \
  --image gcr.io/YOUR_PROJECT_ID/bunty-app \
  --add-cloudsql-instances YOUR_PROJECT_ID:us-central1:bunty-db \
  --set-env-vars DATABASE_URL="postgresql://user:pass@/bunty?host=/cloudsql/YOUR_PROJECT_ID:us-central1:bunty-db"

Use Secrets

# Create secret
echo -n "your-secret-value" | gcloud secrets create jwt-secret --data-file=-

# Deploy with secrets
gcloud run deploy bunty-app \
  --image gcr.io/YOUR_PROJECT_ID/bunty-app \
  --set-secrets JWT_SECRET=jwt-secret:latest,DATABASE_URL=database-url:latest

Custom Domain

# Map custom domain
gcloud run services update bunty-app --platform managed --region us-central1
gcloud beta run domain-mappings create --service bunty-app --domain api.example.com

Option 2: App Engine

Create app.yaml

runtime: custom
env: flex

automatic_scaling:
  min_num_instances: 1
  max_num_instances: 10
  cool_down_period_sec: 180
  cpu_utilization:
    target_utilization: 0.7

resources:
  cpu: 1
  memory_gb: 0.5
  disk_size_gb: 10

network:
  forwarded_ports:
    - 8080

env_variables:
  NODE_ENV: 'production'
  PORT: '8080'

Deploy

# Deploy to App Engine
gcloud app deploy

# View app
gcloud app browse

# View logs
gcloud app logs tail -s default

With Datastore

import { Datastore } from '@google-cloud/datastore';

const datastore = new Datastore();

async function saveUser(user: any) {
  const key = datastore.key(['User', user.id]);
  await datastore.save({
    key,
    data: user,
  });
}

Option 3: Compute Engine (VM)

Create VM Instance

# Create instance
gcloud compute instances create bunty-vm \
  --image-family=ubuntu-2204-lts \
  --image-project=ubuntu-os-cloud \
  --machine-type=e2-medium \
  --zone=us-central1-a \
  --tags=http-server,https-server

# Allow HTTP/HTTPS
gcloud compute firewall-rules create allow-http \
  --allow tcp:80,tcp:443 \
  --target-tags http-server,https-server

SSH and Setup

# SSH into instance
gcloud compute ssh bunty-vm --zone=us-central1-a

# Install Bun
curl -fsSL https://bun.sh/install | bash
source ~/.bashrc

# Clone and setup app
git clone https://github.com/yourusername/bunty-app.git
cd bunty-app
bun install --production

# Install PM2
npm install -g pm2

# Start app
pm2 start ecosystem.config.js --env production
pm2 save
pm2 startup

# Setup Nginx (same as AWS EC2 guide)

Create Instance from Image

# Create custom image
gcloud compute images create bunty-image \
  --source-disk bunty-vm \
  --source-disk-zone us-central1-a

# Create instance from image
gcloud compute instances create bunty-instance \
  --image bunty-image \
  --machine-type e2-medium \
  --zone us-central1-a

Option 4: Google Kubernetes Engine (GKE)

Create GKE Cluster

# Create cluster
gcloud container clusters create bunty-cluster \
  --num-nodes=3 \
  --machine-type=e2-medium \
  --region=us-central1 \
  --enable-autoscaling \
  --min-nodes=1 \
  --max-nodes=5

# Get credentials
gcloud container clusters get-credentials bunty-cluster --region=us-central1

Deploy to GKE

# Build and push image
gcloud builds submit --tag gcr.io/YOUR_PROJECT_ID/bunty-app

# Apply Kubernetes manifests
kubectl apply -f k8s/

# Or use this quick deployment:
kubectl create deployment bunty-app --image=gcr.io/YOUR_PROJECT_ID/bunty-app
kubectl expose deployment bunty-app --type=LoadBalancer --port=80 --target-port=3000

Full Kubernetes Setup

See Kubernetes deployment guide for complete configuration.

Cloud Build (CI/CD)

cloudbuild.yaml

steps:
  # Run tests
  - name: 'oven/bun:1'
    entrypoint: bun
    args: ['test']

  # Build Docker image
  - name: 'gcr.io/cloud-builders/docker'
    args:
      - 'build'
      - '-t'
      - 'gcr.io/$PROJECT_ID/bunty-app:$SHORT_SHA'
      - '-t'
      - 'gcr.io/$PROJECT_ID/bunty-app:latest'
      - '.'

  # Push to Container Registry
  - name: 'gcr.io/cloud-builders/docker'
    args: ['push', 'gcr.io/$PROJECT_ID/bunty-app:$SHORT_SHA']
  - name: 'gcr.io/cloud-builders/docker'
    args: ['push', 'gcr.io/$PROJECT_ID/bunty-app:latest']

  # Deploy to Cloud Run
  - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
    entrypoint: gcloud
    args:
      - 'run'
      - 'deploy'
      - 'bunty-app'
      - '--image'
      - 'gcr.io/$PROJECT_ID/bunty-app:$SHORT_SHA'
      - '--region'
      - 'us-central1'
      - '--platform'
      - 'managed'
      - '--allow-unauthenticated'

images:
  - 'gcr.io/$PROJECT_ID/bunty-app:$SHORT_SHA'
  - 'gcr.io/$PROJECT_ID/bunty-app:latest'

options:
  machineType: 'N1_HIGHCPU_8'

Create Trigger

# Connect repository
gcloud builds triggers create github \
  --name=bunty-deploy \
  --repo-name=bunty-app \
  --repo-owner=yourusername \
  --branch-pattern=^main$ \
  --build-config=cloudbuild.yaml

Cloud Storage

Create Bucket

# Create bucket
gsutil mb gs://bunty-uploads

# Make public (if needed)
gsutil iam ch allUsers:objectViewer gs://bunty-uploads

Use in Application

import { Storage } from '@google-cloud/storage';

const storage = new Storage();
const bucket = storage.bucket('bunty-uploads');

async function upload(filename: string, buffer: Buffer) {
  const file = bucket.file(filename);
  await file.save(buffer, {
    metadata: {
      contentType: 'image/jpeg',
    },
  });

  // Get public URL
  const publicUrl = `https://storage.googleapis.com/bunty-uploads/${filename}`;
  return publicUrl;
}

async function download(filename: string) {
  const file = bucket.file(filename);
  const [contents] = await file.download();
  return contents;
}

Cloud SQL

Create PostgreSQL Instance

# Create instance
gcloud sql instances create bunty-db \
  --database-version=POSTGRES_15 \
  --tier=db-g1-small \
  --region=us-central1 \
  --root-password=your-password

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

# Create user
gcloud sql users create bunty \
  --instance=bunty-db \
  --password=bunty-password

Connect from Application

import { DatabaseModule } from '@bunty/orm';

@Module({
  imports: [
    DatabaseModule.forRoot({
      host: '/cloudsql/PROJECT_ID:us-central1:bunty-db',
      database: 'bunty',
      user: 'bunty',
      password: process.env.DB_PASSWORD,
    }),
  ],
})
export class AppModule {}

Memorystore (Redis)

Create Redis Instance

gcloud redis instances create bunty-cache \
  --size=1 \
  --region=us-central1 \
  --redis-version=redis_7_0

Use in Application

import { Redis } from 'ioredis';

const redis = new Redis({
  host: process.env.REDIS_HOST,
  port: 6379,
});

await redis.set('key', 'value');
const value = await redis.get('key');

Secret Manager

Create Secrets

# Create secret
echo -n "my-secret-value" | gcloud secrets create my-secret --data-file=-

# Grant access
gcloud secrets add-iam-policy-binding my-secret \
  --member="serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
  --role="roles/secretmanager.secretAccessor"

Access in Application

import { SecretManagerServiceClient } from '@google-cloud/secret-manager';

const client = new SecretManagerServiceClient();

async function getSecret(name: string) {
  const [version] = await client.accessSecretVersion({
    name: `projects/PROJECT_ID/secrets/${name}/versions/latest`,
  });
  return version.payload.data.toString();
}

Monitoring

Cloud Logging

import { Logging } from '@google-cloud/logging';

const logging = new Logging();
const log = logging.log('bunty-app');

async function logInfo(message: string) {
  const entry = log.entry({
    severity: 'INFO',
    resource: { type: 'global' },
  }, message);

  await log.write(entry);
}

Cloud Monitoring

# View metrics
gcloud monitoring time-series list --filter='metric.type="run.googleapis.com/request_count"'

# Create alert
gcloud alpha monitoring policies create \
  --notification-channels=CHANNEL_ID \
  --display-name="High CPU" \
  --condition-threshold-value=0.8 \
  --condition-display-name="CPU > 80%"

Load Balancing

Create Load Balancer

# Create backend service
gcloud compute backend-services create bunty-backend \
  --global \
  --health-checks bunty-health \
  --protocol HTTP

# Create URL map
gcloud compute url-maps create bunty-lb \
  --default-service bunty-backend

# Create target proxy
gcloud compute target-http-proxies create bunty-proxy \
  --url-map bunty-lb

# Create forwarding rule
gcloud compute forwarding-rules create bunty-rule \
  --global \
  --target-http-proxy bunty-proxy \
  --ports 80

Cost Optimization

  • Use Cloud Run for variable workloads (pay per use)
  • Enable auto-scaling
  • Use Preemptible VMs for non-critical workloads
  • Set up budget alerts
  • Use Cloud CDN for static content
  • Choose appropriate machine types

Best Practices

  1. Use Cloud Run for most workloads (easiest, auto-scaling)
  2. Enable Cloud Build for automated deployments
  3. Use Secret Manager for sensitive data
  4. Set up Cloud Monitoring for observability
  5. Use Cloud CDN for better performance
  6. Enable VPC for security
  7. Use Cloud Armor for DDoS protection

Next Steps

Have questions? Join our Discord community
Found an issue? Edit this page on GitHub