brainy/cloud-wrapper/scripts/deploy-gcp.js
2025-06-24 11:41:30 -07:00

196 lines
5.5 KiB
JavaScript

#!/usr/bin/env node
/**
* Google Cloud Platform Deployment Script for Brainy Cloud Wrapper
*
* This script helps deploy the Brainy cloud wrapper to Google Cloud Run.
* It uses the Google Cloud SDK to create and configure the necessary resources.
*
* Prerequisites:
* - Google Cloud SDK installed and configured with appropriate credentials
* - Node.js 23.11.0 or higher
* - Brainy cloud wrapper built (npm run build)
* - Docker installed (for building container images)
*/
import { execSync } from 'child_process';
import fs from 'fs';
import path from 'path';
import dotenv from 'dotenv';
// Load environment variables
dotenv.config();
// Configuration
const config = {
projectId: process.env.GCP_PROJECT_ID,
region: process.env.GCP_REGION || 'us-central1',
serviceName: process.env.GCP_SERVICE_NAME || 'brainy-cloud-service',
imageName: process.env.GCP_IMAGE_NAME || 'brainy-cloud-service',
memory: process.env.GCP_MEMORY || '512Mi',
cpu: process.env.GCP_CPU || '1',
maxInstances: process.env.GCP_MAX_INSTANCES || '10',
minInstances: process.env.GCP_MIN_INSTANCES || '0'
};
// Validate configuration
if (!config.projectId) {
console.error('Error: GCP_PROJECT_ID environment variable is required');
process.exit(1);
}
// Create Dockerfile
function createDockerfile() {
console.log('Creating Dockerfile...');
const dockerfileContent = `
FROM node:23-slim
WORKDIR /app
# Copy package.json and package-lock.json
COPY package*.json ./
# Install dependencies
RUN npm install --production --legacy-peer-deps
# Copy built application
COPY dist/ ./dist/
# Copy environment variables
COPY .env ./
# Expose port
EXPOSE 8080
# Start the application
CMD ["node", "dist/index.js"]
`;
try {
fs.writeFileSync('Dockerfile', dockerfileContent);
console.log('Dockerfile created successfully');
} catch (error) {
console.error('Error creating Dockerfile:', error);
process.exit(1);
}
}
// Build and push Docker image
function buildAndPushImage() {
console.log('Building and pushing Docker image...');
try {
// Set Google Cloud project
execSync(`gcloud config set project ${config.projectId}`);
// Build the Docker image
execSync(`docker build -t gcr.io/${config.projectId}/${config.imageName} .`);
// Configure Docker to use gcloud as a credential helper
execSync('gcloud auth configure-docker');
// Push the image to Google Container Registry
execSync(`docker push gcr.io/${config.projectId}/${config.imageName}`);
console.log('Docker image built and pushed successfully');
} catch (error) {
console.error('Error building and pushing Docker image:', error);
process.exit(1);
}
}
// Deploy to Google Cloud Run
function deployToCloudRun() {
console.log('Deploying to Google Cloud Run...');
try {
// Create environment variables string
const envVars = [
`NODE_ENV=production`,
`PORT=8080`,
`STORAGE_TYPE=${process.env.STORAGE_TYPE || 'filesystem'}`
];
// Add S3 environment variables if using S3 storage
if (process.env.STORAGE_TYPE === 's3') {
envVars.push(`S3_BUCKET_NAME=${process.env.S3_BUCKET_NAME}`);
envVars.push(`S3_ACCESS_KEY_ID=${process.env.S3_ACCESS_KEY_ID}`);
envVars.push(`S3_SECRET_ACCESS_KEY=${process.env.S3_SECRET_ACCESS_KEY}`);
envVars.push(`S3_REGION=${process.env.S3_REGION || 'us-east-1'}`);
if (process.env.S3_ENDPOINT) {
envVars.push(`S3_ENDPOINT=${process.env.S3_ENDPOINT}`);
}
}
// Add embedding and HNSW configuration if provided
if (process.env.USE_SIMPLE_EMBEDDING) {
envVars.push(`USE_SIMPLE_EMBEDDING=${process.env.USE_SIMPLE_EMBEDDING}`);
}
if (process.env.HNSW_M) {
envVars.push(`HNSW_M=${process.env.HNSW_M}`);
envVars.push(`HNSW_EF_CONSTRUCTION=${process.env.HNSW_EF_CONSTRUCTION || '200'}`);
envVars.push(`HNSW_EF_SEARCH=${process.env.HNSW_EF_SEARCH || '50'}`);
}
// Deploy to Cloud Run
const envVarsString = envVars.map(env => `--set-env-vars="${env}"`).join(' ');
execSync(`gcloud run deploy ${config.serviceName} \
--image=gcr.io/${config.projectId}/${config.imageName} \
--platform=managed \
--region=${config.region} \
--memory=${config.memory} \
--cpu=${config.cpu} \
--max-instances=${config.maxInstances} \
--min-instances=${config.minInstances} \
--allow-unauthenticated \
${envVarsString}`);
console.log('Deployed to Google Cloud Run successfully');
// Get the service URL
const serviceUrl = execSync(`gcloud run services describe ${config.serviceName} --region=${config.region} --format="value(status.url)"`).toString().trim();
console.log(`Service URL: ${serviceUrl}`);
} catch (error) {
console.error('Error deploying to Google Cloud Run:', error);
process.exit(1);
}
}
// Clean up
function cleanup() {
console.log('Cleaning up...');
try {
// Remove Dockerfile
fs.unlinkSync('Dockerfile');
console.log('Cleanup completed');
} catch (error) {
console.error('Error during cleanup:', error);
}
}
// Main function
async function main() {
try {
console.log('Starting Google Cloud Platform deployment...');
createDockerfile();
buildAndPushImage();
deployToCloudRun();
cleanup();
console.log('Deployment completed successfully');
} catch (error) {
console.error('Deployment failed:', error);
cleanup();
process.exit(1);
}
}
// Run the script
main();