feat: 添加 Docker 可用性前置检查,本地开发时给出友好提示
This commit is contained in:
+42
-8
@@ -219,6 +219,31 @@ export async function checkForUpdate(): Promise<VersionInfo> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查 Docker 是否可用
|
||||||
|
*/
|
||||||
|
function checkDockerAvailable(): { ok: boolean; message: string } {
|
||||||
|
try {
|
||||||
|
execSync("docker info", {
|
||||||
|
encoding: "utf-8",
|
||||||
|
timeout: 10000,
|
||||||
|
stdio: ["ignore", "pipe", "pipe"],
|
||||||
|
windowsHide: true,
|
||||||
|
});
|
||||||
|
return { ok: true, message: "" };
|
||||||
|
} catch {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
message:
|
||||||
|
"Docker 守护进程不可用。\n" +
|
||||||
|
"更新功能需要在 Docker 容器内运行,当前环境不支持。\n" +
|
||||||
|
"如需测试,请使用 Docker 部署后访问容器内的页面:\n" +
|
||||||
|
" docker compose -p recipe_tool up -d\n" +
|
||||||
|
"然后访问 http://localhost:3000/settings/update",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行 Docker 容器更新
|
* 执行 Docker 容器更新
|
||||||
* @param onLog 日志回调
|
* @param onLog 日志回调
|
||||||
@@ -234,19 +259,28 @@ export async function executeUpdate(
|
|||||||
try {
|
try {
|
||||||
onLog("开始更新流程...\n");
|
onLog("开始更新流程...\n");
|
||||||
|
|
||||||
|
// 0. 检查 Docker 是否可用
|
||||||
|
onLog("[0/4] 检查 Docker 环境...\n");
|
||||||
|
const dockerCheck = checkDockerAvailable();
|
||||||
|
if (!dockerCheck.ok) {
|
||||||
|
onLog(`✗ ${dockerCheck.message}\n`);
|
||||||
|
return { success: false, message: dockerCheck.message };
|
||||||
|
}
|
||||||
|
onLog("✓ Docker 环境正常\n");
|
||||||
|
|
||||||
// 1. 拉取最新代码
|
// 1. 拉取最新代码
|
||||||
const url = getAuthenticatedRemoteUrl();
|
const url = getAuthenticatedRemoteUrl();
|
||||||
onLog(`[1/4] 克隆最新代码...\n`);
|
onLog("[1/4] 克隆最新代码...\n");
|
||||||
execSync(`git clone --depth 1 "${url}" "${tmpDir}"`, {
|
execSync(`git clone --depth 1 "${url}" "${tmpDir}"`, {
|
||||||
encoding: "utf-8",
|
encoding: "utf-8",
|
||||||
timeout: 120000,
|
timeout: 120000,
|
||||||
windowsHide: true,
|
windowsHide: true,
|
||||||
stdio: ["ignore", "pipe", "pipe"],
|
stdio: ["ignore", "pipe", "pipe"],
|
||||||
});
|
});
|
||||||
onLog(`✓ 代码拉取完成\n`);
|
onLog("✓ 代码拉取完成\n");
|
||||||
|
|
||||||
// 2. 生成 .env 文件
|
// 2. 生成 .env 文件
|
||||||
onLog(`[2/4] 准备环境变量...\n`);
|
onLog("[2/4] 准备环境变量...\n");
|
||||||
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"}`,
|
||||||
@@ -259,27 +293,27 @@ export async function executeUpdate(
|
|||||||
`ONEDEV_ACCESS_TOKEN=${process.env.ONEDEV_ACCESS_TOKEN || ""}`,
|
`ONEDEV_ACCESS_TOKEN=${process.env.ONEDEV_ACCESS_TOKEN || ""}`,
|
||||||
].join("\n");
|
].join("\n");
|
||||||
fs.writeFileSync(path.join(tmpDir, ".env"), envContent, "utf-8");
|
fs.writeFileSync(path.join(tmpDir, ".env"), envContent, "utf-8");
|
||||||
onLog(`✓ 环境变量已准备\n`);
|
onLog("✓ 环境变量已准备\n");
|
||||||
|
|
||||||
// 3. 构建新镜像
|
// 3. 构建新镜像
|
||||||
onLog(`[3/4] 构建新 Docker 镜像...\n`);
|
onLog("[3/4] 构建新 Docker 镜像...\n");
|
||||||
execSync(`cd "${tmpDir}" && docker compose -p recipe_tool build`, {
|
execSync(`cd "${tmpDir}" && docker compose -p recipe_tool build`, {
|
||||||
encoding: "utf-8",
|
encoding: "utf-8",
|
||||||
timeout: 600000,
|
timeout: 600000,
|
||||||
windowsHide: true,
|
windowsHide: true,
|
||||||
stdio: ["ignore", "pipe", "pipe"],
|
stdio: ["ignore", "pipe", "pipe"],
|
||||||
});
|
});
|
||||||
onLog(`✓ 镜像构建完成\n`);
|
onLog("✓ 镜像构建完成\n");
|
||||||
|
|
||||||
// 4. 重启服务
|
// 4. 重启服务
|
||||||
onLog(`[4/4] 重启服务...\n`);
|
onLog("[4/4] 重启服务...\n");
|
||||||
execSync(`cd "${tmpDir}" && docker compose -p recipe_tool up -d`, {
|
execSync(`cd "${tmpDir}" && docker compose -p recipe_tool up -d`, {
|
||||||
encoding: "utf-8",
|
encoding: "utf-8",
|
||||||
timeout: 60000,
|
timeout: 60000,
|
||||||
windowsHide: true,
|
windowsHide: true,
|
||||||
stdio: ["ignore", "pipe", "pipe"],
|
stdio: ["ignore", "pipe", "pipe"],
|
||||||
});
|
});
|
||||||
onLog(`✓ 服务已重启\n`);
|
onLog("✓ 服务已重启\n");
|
||||||
|
|
||||||
return { success: true, message: "更新完成" };
|
return { success: true, message: "更新完成" };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user