头铁
This commit is contained in:
@@ -36,7 +36,7 @@ except ImportError:
|
||||
|
||||
# 端口统一从环境变量 DEPLOY_PORT 读取,未设置时使用此默认值
|
||||
DEPLOY_PM2_APP = "soul"
|
||||
DEFAULT_DEPLOY_PORT = 30006
|
||||
DEFAULT_DEPLOY_PORT = 3888
|
||||
DEPLOY_PROJECT_PATH = "/www/wwwroot/soul"
|
||||
DEPLOY_SITE_URL = "https://soul.quwanzhi.com"
|
||||
# SSH 端口(支持环境变量 DEPLOY_SSH_PORT,未设置时默认为 22022)
|
||||
@@ -61,7 +61,9 @@ def get_cfg():
|
||||
|
||||
|
||||
def get_cfg_devlop():
|
||||
"""devlop 模式配置:在基础配置上增加 base_path / dist / dist2"""
|
||||
"""devlop 模式配置:在基础配置上增加 base_path / dist / dist2。
|
||||
实际运行目录为 dist_path(切换后新版本在 dist),宝塔 PM2 项目路径必须指向 dist_path,
|
||||
否则会从错误目录启动导致 .next/static 等静态资源 404。"""
|
||||
cfg = get_cfg().copy()
|
||||
cfg["base_path"] = os.environ.get("DEVOP_BASE_PATH", "/www/wwwroot/auto-devlop/soul")
|
||||
cfg["dist_path"] = cfg["base_path"] + "/dist"
|
||||
@@ -269,6 +271,10 @@ def pack_standalone_tar(root):
|
||||
if not os.path.isdir(standalone) or not os.path.isdir(static_src):
|
||||
print(" [失败] 未找到 .next/standalone 或 .next/static")
|
||||
return None
|
||||
chunks_dir = os.path.join(static_src, "chunks")
|
||||
if not os.path.isdir(chunks_dir):
|
||||
print(" [失败] .next/static/chunks 不存在,请先完整执行 pnpm build(本地 pnpm start 能正常打开页面后再部署)")
|
||||
return None
|
||||
|
||||
staging = tempfile.mkdtemp(prefix="soul_deploy_")
|
||||
try:
|
||||
@@ -291,6 +297,13 @@ def pack_standalone_tar(root):
|
||||
shutil.rmtree(static_dst)
|
||||
os.makedirs(os.path.dirname(static_dst), exist_ok=True)
|
||||
shutil.copytree(static_src, static_dst)
|
||||
# 同步构建索引,避免 server 用错 BUILD_ID/manifest 导致静态 404
|
||||
next_root = os.path.join(root, ".next")
|
||||
next_staging = os.path.join(staging, ".next")
|
||||
for name in ["BUILD_ID", "build-manifest.json", "app-path-routes-manifest.json", "routes-manifest.json"]:
|
||||
src = os.path.join(next_root, name)
|
||||
if os.path.isfile(src):
|
||||
shutil.copy2(src, os.path.join(next_staging, name))
|
||||
if os.path.isdir(public_src):
|
||||
shutil.copytree(public_src, os.path.join(staging, "public"), dirs_exist_ok=True)
|
||||
if os.path.isfile(ecosystem_src):
|
||||
@@ -410,7 +423,7 @@ def deploy_via_baota_api(cfg):
|
||||
|
||||
# ==================== 打包(devlop 模式:zip) ====================
|
||||
|
||||
ZIP_EXCLUDE_DIRS = {".cache", "__pycache__", ".git", "node_modules", "cache", "test", "tests", "coverage", ".nyc_output", ".turbo", "开发文档", "miniprogramPre", "my-app", "newpp"}
|
||||
ZIP_EXCLUDE_DIRS = {".cache", "__pycache__", ".git", "node_modules", "cache", "test", "tests", "coverage", ".nyc_output", ".turbo", "开发文档"}
|
||||
ZIP_EXCLUDE_FILE_NAMES = {".DS_Store", "Thumbs.db"}
|
||||
ZIP_EXCLUDE_FILE_SUFFIXES = (".log", ".map")
|
||||
|
||||
@@ -438,6 +451,10 @@ def pack_standalone_zip(root):
|
||||
if not os.path.isdir(standalone) or not os.path.isdir(static_src):
|
||||
print(" [失败] 未找到 .next/standalone 或 .next/static")
|
||||
return None
|
||||
chunks_dir = os.path.join(static_src, "chunks")
|
||||
if not os.path.isdir(chunks_dir):
|
||||
print(" [失败] .next/static/chunks 不存在,请先完整执行 pnpm build(本地 pnpm start 能正常打开页面后再部署)")
|
||||
return None
|
||||
|
||||
staging = tempfile.mkdtemp(prefix="soul_devlop_")
|
||||
try:
|
||||
@@ -457,6 +474,13 @@ def pack_standalone_zip(root):
|
||||
break
|
||||
os.makedirs(os.path.join(staging, ".next"), exist_ok=True)
|
||||
shutil.copytree(static_src, os.path.join(staging, ".next", "static"), dirs_exist_ok=True)
|
||||
# 同步构建索引,避免 server 用错 BUILD_ID/manifest 导致静态 404
|
||||
next_root = os.path.join(root, ".next")
|
||||
next_staging = os.path.join(staging, ".next")
|
||||
for name in ["BUILD_ID", "build-manifest.json", "app-path-routes-manifest.json", "routes-manifest.json"]:
|
||||
src = os.path.join(next_root, name)
|
||||
if os.path.isfile(src):
|
||||
shutil.copy2(src, os.path.join(next_staging, name))
|
||||
if os.path.isdir(public_src):
|
||||
shutil.copytree(public_src, os.path.join(staging, "public"), dirs_exist_ok=True)
|
||||
if os.path.isfile(ecosystem_src):
|
||||
@@ -599,7 +623,7 @@ def run_pnpm_install_in_dist2(cfg):
|
||||
|
||||
|
||||
def remote_swap_dist_and_restart(cfg):
|
||||
"""暂停 → dist→dist1, dist2→dist → 删除 dist1 → 重启(devlop 模式)"""
|
||||
"""暂停 → dist→dist1, dist2→dist → 删除 dist1 → 更新 PM2 项目路径 → 重启(devlop 模式)"""
|
||||
print("[5/7] 宝塔 API 暂停 Node 项目 ...")
|
||||
stop_node_project(cfg["panel_url"], cfg["api_key"], cfg["pm2_name"])
|
||||
time.sleep(2)
|
||||
@@ -620,9 +644,16 @@ def remote_swap_dist_and_restart(cfg):
|
||||
print(" [成功] 新版本位于 %s" % cfg["dist_path"])
|
||||
finally:
|
||||
client.close()
|
||||
print("[7/7] 宝塔 API 重启 Node 项目 ...")
|
||||
# 关键:devlop 实际运行目录是 dist_path,必须让宝塔 PM2 从该目录启动,否则会从错误目录跑导致静态资源 404
|
||||
print("[7/7] 更新宝塔 Node 项目路径并重启 ...")
|
||||
add_or_update_node_project(
|
||||
cfg["panel_url"], cfg["api_key"], cfg["pm2_name"],
|
||||
cfg["dist_path"], # 使用 dist_path,不是 project_path
|
||||
port=cfg["port"],
|
||||
node_path=cfg.get("node_path"),
|
||||
)
|
||||
if not start_node_project(cfg["panel_url"], cfg["api_key"], cfg["pm2_name"]):
|
||||
print(" [警告] 请到宝塔手动启动 %s" % cfg["pm2_name"])
|
||||
print(" [警告] 请到宝塔手动启动 %s,并确认项目路径为: %s" % (cfg["pm2_name"], cfg["dist_path"]))
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
Reference in New Issue
Block a user