fix: 更新时先 down 旧容器再 up -d,解决端口占用导致的卡死

This commit is contained in:
2026-05-24 23:59:46 +08:00
parent 6b739d1c6c
commit 054150c7d0
+27 -12
View File
@@ -318,8 +318,8 @@ export async function executeUpdate(
onLog("开始更新流程"); onLog("开始更新流程");
// 0. 检查 Docker 是否可用 // 0. 检查 Docker 是否可用
onLog("[0/4] 检查 Docker 环境"); onLog("[0/5] 检查 Docker 环境");
consoleLog("执行", "步骤 0/4 — 检查 Docker 环境"); consoleLog("执行", "步骤 0/5 — 检查 Docker 环境");
const dockerCheck = checkDockerAvailable(); const dockerCheck = checkDockerAvailable();
if (!dockerCheck.ok) { if (!dockerCheck.ok) {
onLog(`${dockerCheck.message}`); onLog(`${dockerCheck.message}`);
@@ -330,8 +330,8 @@ export async function executeUpdate(
// 1. 拉取最新代码 // 1. 拉取最新代码
const url = getAuthenticatedRemoteUrl(); const url = getAuthenticatedRemoteUrl();
onLog("[1/4] 克隆最新代码"); onLog("[1/5] 克隆最新代码");
consoleLog("执行", "步骤 1/4 — 克隆代码"); consoleLog("执行", "步骤 1/5 — 克隆代码");
execSyncAndLog( execSyncAndLog(
`git clone --depth 1 "${url}" "${tmpDir}"`, `git clone --depth 1 "${url}" "${tmpDir}"`,
"git-clone", "git-clone",
@@ -340,8 +340,8 @@ export async function executeUpdate(
onLog("✓ 代码拉取完成"); onLog("✓ 代码拉取完成");
// 2. 生成 .env 文件 // 2. 生成 .env 文件
onLog("[2/4] 准备环境变量"); onLog("[2/5] 准备环境变量");
consoleLog("执行", "步骤 2/4 — 准备环境变量"); consoleLog("执行", "步骤 2/5 — 准备环境变量");
const envContent = [ const envContent = [
`DB_HOST=${process.env.DB_HOST || "127.0.0.1"}`, `DB_HOST=${process.env.DB_HOST || "127.0.0.1"}`,
`DB_PORT=${process.env.DB_PORT || "3306"}`, `DB_PORT=${process.env.DB_PORT || "3306"}`,
@@ -358,8 +358,8 @@ export async function executeUpdate(
onLog("✓ 环境变量已准备"); onLog("✓ 环境变量已准备");
// 3. 构建新镜像 // 3. 构建新镜像
onLog("[3/4] 构建新 Docker 镜像"); onLog("[3/5] 构建新 Docker 镜像");
consoleLog("执行", "步骤 3/4 — 构建镜像(可能耗时较长)"); consoleLog("执行", "步骤 3/5 — 构建镜像(可能耗时较长)");
execSyncAndLog( execSyncAndLog(
`cd "${tmpDir}" && docker-compose -p recipe_tool build`, `cd "${tmpDir}" && docker-compose -p recipe_tool build`,
"docker-build", "docker-build",
@@ -367,15 +367,30 @@ export async function executeUpdate(
); );
onLog("✓ 镜像构建完成"); onLog("✓ 镜像构建完成");
// 4. 重启服务 // 4. 停止旧容器(释放端口)
onLog("[4/4] 重启服务"); onLog("[4/5] 停止旧容器");
consoleLog("执行", "步骤 4/4重启服务"); consoleLog("执行", "步骤 4/5停止旧容器");
// 忽略 down 的错误(首次运行可能没有旧容器)
try {
execSyncAndLog(
`cd "${tmpDir}" && docker-compose -p recipe_tool down`,
"docker-down",
{ timeout: 30000, stdio: ["ignore", "pipe", "pipe"] }
);
} catch {
consoleLog("执行", "旧容器停止(可能不存在,忽略)");
}
onLog("✓ 旧容器已停止");
// 5. 启动新容器
onLog("[5/5] 启动新容器");
consoleLog("执行", "步骤 5/5 — 启动新容器");
execSyncAndLog( execSyncAndLog(
`cd "${tmpDir}" && docker-compose -p recipe_tool up -d`, `cd "${tmpDir}" && docker-compose -p recipe_tool up -d`,
"docker-up", "docker-up",
{ timeout: 60000, stdio: ["ignore", "pipe", "pipe"] } { timeout: 60000, stdio: ["ignore", "pipe", "pipe"] }
); );
onLog("✓ 服务已重启"); onLog("✓ 新容器已启动");
consoleLog("执行", "=== 更新成功 ==="); consoleLog("执行", "=== 更新成功 ===");
return { success: true, message: "更新完成" }; return { success: true, message: "更新完成" };