100 lines
3.3 KiB
JavaScript
100 lines
3.3 KiB
JavaScript
import {spawn} from 'node:child_process';
|
|
import {copyFileSync, existsSync} from 'node:fs';
|
|
import path from 'node:path';
|
|
|
|
const [, , rawCommand = 'help', ...args] = process.argv;
|
|
const command = rawCommand.trim();
|
|
const printComposeConfig = args.includes('--print');
|
|
const passthroughArgs = args.filter((arg) => arg !== '--print');
|
|
const projectRoot = process.cwd();
|
|
const composeFile = path.join('deploy', 'container', 'docker-compose.loadtest.yml');
|
|
const envExamplePath = path.join('deploy', 'container', 'api-server.env.example');
|
|
const envPath = path.join('deploy', 'container', 'api-server.env');
|
|
|
|
const supportedCommands = new Set(['init', 'build', 'up', 'down', 'logs', 'ps', 'config', 'k6']);
|
|
|
|
if (command === 'help' || !supportedCommands.has(command)) {
|
|
printHelp(command !== 'help');
|
|
process.exit(command === 'help' ? 0 : 1);
|
|
}
|
|
|
|
if (command === 'init') {
|
|
ensureEnvFile();
|
|
process.exit(0);
|
|
}
|
|
|
|
if (!existsSync(envPath)) {
|
|
ensureEnvFile();
|
|
console.error('[container] 请先检查 deploy/container/api-server.env 中的 SpacetimeDB 地址、库名和 token。');
|
|
process.exit(1);
|
|
}
|
|
|
|
const composeArgs = buildComposeArgs(command, passthroughArgs);
|
|
const child = spawn('docker', composeArgs, {
|
|
cwd: projectRoot,
|
|
env: process.env,
|
|
stdio: 'inherit',
|
|
shell: false,
|
|
});
|
|
|
|
child.on('error', (error) => {
|
|
console.error(`[container] docker compose 启动失败: ${error.message}`);
|
|
console.error('[container] 请确认 Docker Desktop 或 Docker Engine 已安装,并且 docker 在 PATH 中。');
|
|
process.exit(1);
|
|
});
|
|
|
|
child.on('exit', (code, signal) => {
|
|
if (signal) {
|
|
console.error(`[container] docker compose 被信号终止: ${signal}`);
|
|
process.exit(1);
|
|
}
|
|
process.exit(code ?? 0);
|
|
});
|
|
|
|
function buildComposeArgs(selectedCommand, extraArgs) {
|
|
const baseArgs = ['compose', '-f', composeFile];
|
|
switch (selectedCommand) {
|
|
case 'build':
|
|
return [...baseArgs, 'build', ...extraArgs];
|
|
case 'up':
|
|
return [...baseArgs, 'up', '-d', ...extraArgs];
|
|
case 'down':
|
|
return [...baseArgs, 'down', ...extraArgs];
|
|
case 'logs':
|
|
return [...baseArgs, 'logs', ...extraArgs];
|
|
case 'ps':
|
|
return [...baseArgs, 'ps', ...extraArgs];
|
|
case 'config':
|
|
return [...baseArgs, 'config', ...(printComposeConfig ? [] : ['--quiet']), ...extraArgs];
|
|
case 'k6':
|
|
return [...baseArgs, '--profile', 'loadtest', 'run', '--rm', 'k6', ...extraArgs];
|
|
default:
|
|
throw new Error(`unsupported command: ${selectedCommand}`);
|
|
}
|
|
}
|
|
|
|
function ensureEnvFile() {
|
|
if (existsSync(envPath)) {
|
|
console.log(`[container] 已存在 ${envPath}`);
|
|
return;
|
|
}
|
|
copyFileSync(envExamplePath, envPath);
|
|
console.log(`[container] 已从 ${envExamplePath} 生成 ${envPath}`);
|
|
}
|
|
|
|
function printHelp(isError) {
|
|
const output = isError ? console.error : console.log;
|
|
output(`Usage: npm run container:<command> -- [docker compose args]
|
|
|
|
Commands:
|
|
container:init 生成 deploy/container/api-server.env
|
|
container:build 构建 api-server 容器镜像
|
|
container:up 后台启动 api-server + nginx + otelcol
|
|
container:down 停止并清理容器
|
|
container:logs 查看容器日志
|
|
container:ps 查看容器状态
|
|
container:config 校验 compose 配置,传 -- --print 可展开完整配置
|
|
container:k6 在 compose 网络内运行 k6
|
|
`);
|
|
}
|