/** * Docker Deploy Command * Deploy containers with zero-downtime support */ import { exec } from 'child_process' import { promisify } from 'util' import { readFileSync, writeFileSync } from 'fs' const execAsync = promisify(exec) export interface DeployOptions { env?: string noDowntime?: boolean force?: boolean build?: boolean scale?: number } export async function handle(args: DeployOptions, context: any): Promise { const { env = 'production', noDowntime = true, force = false, build = true, scale } = args try { const results: string[] = [] // Build if requested if (build) { results.push('Building Docker image...') const { stdout: buildOutput } = await execAsync('docker-compose build') results.push(buildOutput) } if (noDowntime && !force) { // Zero-downtime deployment results.push('Starting zero-downtime deployment...') // Get current running containers const { stdout: psOutput } = await execAsync('docker-compose ps -q') const hasRunning = psOutput.trim().length > 0 if (hasRunning) { // Start new containers alongside old ones results.push('Starting new containers...') await execAsync(`docker-compose up -d --scale app=${scale || 2} --no-recreate`) // Wait for health checks await new Promise(resolve => setTimeout(resolve, 5000)) // Stop old containers gracefully results.push('Stopping old containers...') await execAsync('docker-compose up -d --scale app=1 --no-recreate') } else { // First deployment results.push('Initial deployment...') await execAsync('docker-compose up -d') } } else { // Standard deployment with potential downtime results.push('Deploying with potential downtime...') await execAsync('docker-compose up -d --force-recreate') } // Show status const { stdout: statusOutput } = await execAsync('docker-compose ps') results.push('\n✓ Deployment complete!\n') results.push(statusOutput) return results.join('\n') } catch (error: any) { throw new Error(`Docker deployment failed: ${error.message}`) } } export default { handle }