#!/usr/bin/env npx tsx /** * ============================================================================= * ./run dev stop - Stop Development Environment * ============================================================================= * * Stops all Docker services started by ./run dev. * * Usage: * ./run dev stop # Stop all services (keeps data) * ./run dev stop --clean # Stop and remove volumes (DESTRUCTIVE) */ import { execFileSync } from 'node:child_process'; import * as path from 'node:path'; // ============================================================================= // Configuration // ============================================================================= const PROJECT_ROOT = path.resolve(__dirname, '../../..'); const COMPOSE_FILE = path.join(PROJECT_ROOT, 'infrastructure/docker/docker-compose.dev-all.yml'); // ============================================================================= // Colors // ============================================================================= const colors = { reset: '\x1b[0m', red: '\x1b[31m', green: '\x1b[32m', yellow: '\x1b[33m', blue: '\x1b[34m', bold: '\x1b[1m', }; const log = { info: (msg: string) => console.log(`${colors.blue}[INFO]${colors.reset} ${msg}`), success: (msg: string) => console.log(`${colors.green}[OK]${colors.reset} ${msg}`), warn: (msg: string) => console.log(`${colors.yellow}[WARN]${colors.reset} ${msg}`), error: (msg: string) => console.log(`${colors.red}[ERROR]${colors.reset} ${msg}`), }; /** * Execute a command and return output, suppressing errors. */ function runQuiet(cmd: string, args: string[]): string { try { return execFileSync(cmd, args, { encoding: 'utf-8', stdio: 'pipe' }).trim(); } catch { return ''; } } // ============================================================================= // Main // ============================================================================= async function main(): Promise { const args = process.argv.slice(2); const options = { clean: args.includes('--clean') || args.includes('-c'), help: args.includes('--help') || args.includes('-h'), }; if (options.help) { console.log(` ${colors.bold}Stop Development Environment${colors.reset} Usage: ./run dev stop [options] Options: --clean, -c Remove Docker volumes (DESTRUCTIVE - deletes data) --help Show this help Note: Database data on bigdisk is NOT affected by --clean. Only Docker-managed volumes (pgadmin data, etc.) are removed. `); process.exit(0); } console.log(` ${colors.bold}Stopping Lilith Platform Dev Environment...${colors.reset} `); try { // Build command arguments const composeArgs = [ 'compose', '-f', COMPOSE_FILE, '--profile', 'gpu', '--profile', 'debug', 'down', ]; if (options.clean) { composeArgs.push('-v'); } log.info(`Running: docker ${options.clean ? 'compose down -v' : 'compose down'}`); execFileSync('docker', composeArgs, { cwd: PROJECT_ROOT, stdio: 'inherit' }); if (options.clean) { log.success('Services stopped and volumes removed'); log.info('Note: Data on bigdisk was NOT removed'); } else { log.success('Services stopped'); } // Check for any remaining containers const remaining = runQuiet('docker', [ 'ps', '--filter', 'name=lilith-dev', '--format', '{{.Names}}', ]); if (remaining) { log.warn(`Some containers are still running: ${remaining}`); log.info('Stop them with: docker stop $(docker ps -q --filter "name=lilith-dev")'); } } catch (error: unknown) { const message = error instanceof Error ? error.message : String(error); log.error(`Failed to stop services: ${message}`); process.exit(1); } console.log(` ${colors.green}Development environment stopped.${colors.reset} To restart: ./run dev `); } main().catch(err => { log.error(`Unexpected error: ${err.message}`); process.exit(1); });