feat(install,update): 新增NGINX部署目录配置与同步逻辑

- 在安装生成器中新增nginxRoot配置项并保存到部署配置
- 更新配置加载逻辑以兼容新增的nginxRoot配置
- 新增前端文件同步到NGINX目录的自动同步脚本
- 根据部署模式自动选择PM2重启或NGINX同步流程
- 升级脚本版本到2.1.0
This commit is contained in:
zhang1106
2026-05-15 16:10:59 +08:00
parent 012a51f917
commit 497fa75cd1
3 changed files with 111 additions and 8 deletions
+2
View File
@@ -32,6 +32,7 @@ function saveConfig() {
frontendDeploy: config.frontendDeploy, frontendDeploy: config.frontendDeploy,
frontendPort: config.frontendPort, frontendPort: config.frontendPort,
domain: config.domain, domain: config.domain,
nginxRoot: config.nginxRoot || null,
savedAt: new Date().toISOString(), savedAt: new Date().toISOString(),
}; };
@@ -63,6 +64,7 @@ function applySavedConfig(saved) {
if (saved.frontendDeploy) config.frontendDeploy = saved.frontendDeploy; if (saved.frontendDeploy) config.frontendDeploy = saved.frontendDeploy;
if (saved.frontendPort) config.frontendPort = saved.frontendPort; if (saved.frontendPort) config.frontendPort = saved.frontendPort;
if (saved.domain) config.domain = saved.domain; if (saved.domain) config.domain = saved.domain;
if (saved.nginxRoot) config.nginxRoot = saved.nginxRoot;
} }
function parseArgs() { function parseArgs() {
+2
View File
@@ -148,6 +148,8 @@ function generateNginxConfig() {
frontendPath = '/var/www/idc'; frontendPath = '/var/www/idc';
} }
config.nginxRoot = frontendPath;
const nginxConfig = `# IDC设备管理系统 - Nginx配置 const nginxConfig = `# IDC设备管理系统 - Nginx配置
# 生成时间: ${new Date().toISOString()} # 生成时间: ${new Date().toISOString()}
+107 -8
View File
@@ -12,12 +12,31 @@ const path = require('path');
const { colors, ICONS, log, padCenter, initLogFile, closeLogFile } = require('./install/logger'); const { colors, ICONS, log, padCenter, initLogFile, closeLogFile } = require('./install/logger');
const { SCRIPT_VERSION: INSTALL_SCRIPT_VERSION, LOG_DIR: INSTALL_LOG_DIR } = require('./install/constants'); const { SCRIPT_VERSION: INSTALL_SCRIPT_VERSION, LOG_DIR: INSTALL_LOG_DIR } = require('./install/constants');
const SCRIPT_VERSION = '2.0.0'; const SCRIPT_VERSION = '2.1.0';
const MIN_NODE_VERSION = 16; const MIN_NODE_VERSION = 16;
const LOCK_FILE = path.join(__dirname, '.update.lock'); const LOCK_FILE = path.join(__dirname, '.update.lock');
const LOG_DIR = path.join(__dirname, 'logs'); const LOG_DIR = path.join(__dirname, 'logs');
const BACKUP_DIR = path.join(__dirname, 'backup'); const BACKUP_DIR = path.join(__dirname, 'backup');
const MAX_BACKUP_FILES = 10; const MAX_BACKUP_FILES = 10;
const SAVED_CONFIG_PATH = path.join(__dirname, 'deploy', 'install-config.json');
let deployConfig = null;
function loadDeployConfig() {
try {
if (!fs.existsSync(SAVED_CONFIG_PATH)) {
log.warning('未找到部署配置 (deploy/install-config.json),将使用默认逻辑');
return null;
}
const content = fs.readFileSync(SAVED_CONFIG_PATH, 'utf8');
const config = JSON.parse(content);
log.info(`部署配置: 前端=${config.frontendDeploy || '未知'}, 前端端口=${config.frontendPort || '未知'}, NGINX目录=${config.nginxRoot || '未配置'}`);
return config;
} catch (error) {
log.warning(`读取部署配置失败: ${error.message}`);
return null;
}
}
const UPDATE_STEPS = [ const UPDATE_STEPS = [
'备份数据', '备份数据',
@@ -538,6 +557,59 @@ function buildFrontend(options) {
return { success: true, skipped: true }; return { success: true, skipped: true };
} }
function syncFrontendToNginx(options) {
if (options.dryRun) {
log.subStep('[模拟] 同步前端文件到 NGINX 目录');
return { success: true, dryRun: true };
}
const frontendDeploy = deployConfig?.frontendDeploy;
if (frontendDeploy !== 'nginx') {
return { success: true, skipped: true };
}
const nginxRoot = deployConfig?.nginxRoot || '/var/www/idc';
const distDir = path.join(__dirname, 'frontend', 'dist');
if (!fs.existsSync(distDir)) {
log.warning(`前端构建产物不存在: ${distDir},跳过 NGINX 同步`);
return { success: true, skipped: true };
}
if (!fs.existsSync(nginxRoot)) {
log.info(`NGINX 目录不存在,自动创建: ${nginxRoot}`);
runCommand(`mkdir -p ${nginxRoot}`, { silent: true });
}
log.subStep(`同步前端文件到 NGINX 目录 (${nginxRoot})...`);
const sudoPrefix = (process.getuid && process.getuid() === 0) ? '' : 'sudo ';
const copyResult = runCommand(`${sudoPrefix}cp -r ${distDir}/* ${nginxRoot}/`, { silent: true });
if (copyResult.success) {
runCommand(`${sudoPrefix}chmod -R 755 ${nginxRoot}`, { silent: true });
log.success('前端文件已同步到 NGINX 目录');
} else {
log.warning('前端文件同步失败,NGINX 可能仍显示旧页面');
return { success: false };
}
log.subStep('重载 NGINX 配置...');
const reloadResult = runCommand(`${sudoPrefix}nginx -s reload`, { silent: true });
if (reloadResult.success) {
log.success('NGINX 已重载');
} else {
log.info('尝试 systemctl 重载 NGINX...');
const systemctlResult = runCommand(`${sudoPrefix}systemctl reload nginx`, { silent: true });
if (systemctlResult.success) {
log.success('NGINX 已重载 (systemctl)');
} else {
log.warning('NGINX 重载失败,请手动执行: sudo nginx -s reload');
}
}
return { success: true };
}
function restartServices(options) { function restartServices(options) {
if (options.skipRestart) { if (options.skipRestart) {
log.info('已跳过服务重启'); log.info('已跳过服务重启');
@@ -546,7 +618,12 @@ function restartServices(options) {
if (options.dryRun) { if (options.dryRun) {
log.subStep('[模拟] 重启后端服务'); log.subStep('[模拟] 重启后端服务');
log.subStep('[模拟] 重启前端服务'); const frontendDeploy = deployConfig?.frontendDeploy;
if (frontendDeploy === 'nginx') {
log.subStep('[模拟] 同步前端文件到 NGINX 目录并重载');
} else {
log.subStep('[模拟] 重启前端服务 (PM2)');
}
return { success: true, dryRun: true }; return { success: true, dryRun: true };
} }
@@ -578,12 +655,32 @@ function restartServices(options) {
return { success: false }; return { success: false };
} }
const frontendServiceName = findFrontendServiceName(); const frontendDeploy = deployConfig?.frontendDeploy;
if (frontendServiceName) {
log.subStep(`重启前端服务 (${frontendServiceName})...`); if (frontendDeploy === 'nginx') {
const frontendRestart = runCommand(`pm2 restart ${frontendServiceName}`); log.info('前端部署模式: NGINX(跳过 PM2 前端服务重启)');
if (frontendRestart.success) { const syncResult = syncFrontendToNginx(options);
log.success('前端服务已重启'); if (!syncResult.success && !syncResult.skipped) {
log.warning('NGINX 前端同步失败,请手动处理');
}
} else {
const frontendServiceName = findFrontendServiceName();
if (frontendServiceName) {
log.info('前端部署模式: PM2 serve');
log.subStep(`重启前端服务 (${frontendServiceName})...`);
const frontendRestart = runCommand(`pm2 restart ${frontendServiceName}`);
if (frontendRestart.success) {
log.success('前端服务已重启');
}
} else {
log.info('未找到 PM2 前端服务(可能使用 NGINX 部署)');
if (process.platform === 'linux') {
log.info('尝试同步前端文件到 NGINX...');
const syncResult = syncFrontendToNginx(options);
if (!syncResult.success && !syncResult.skipped) {
log.warning('NGINX 前端同步失败,请手动处理');
}
}
} }
} }
@@ -783,6 +880,8 @@ async function main() {
log.info('运行模式: 模拟运行(不会执行实际操作)'); log.info('运行模式: 模拟运行(不会执行实际操作)');
} }
deployConfig = loadDeployConfig();
const results = {}; const results = {};
try { try {