Skip to content

The /www is purged during deployment #753

Description

@xiyou1223

[BUG] roles/repo/tasks/build.yml 中的 create repo directories 任务会无条件删除 /www 目录,导致用户数据丢失

描述

在运行 deploy.ymlinfra.yml 的 repo 阶段时,roles/repo/tasks/build.yml 中的 create repo directories 任务会在未确认迁移成功的情况下,强制删除 /www 目录,导致用户在该目录下的业务数据永久丢失。

影响版本

当前最新版 v4.3.0 及之前所有版本。

根因分析

roles/repo/tasks/build.yml 第 20-28 行:

if [ -d "${NGINX_HOME}" ] && [ ! -L "${NGINX_HOME}" ]; then
  mv -f "${NGINX_HOME}"/* "${NGINX_DATA}/" 2>/dev/null || true
  rm -rf "${NGINX_HOME}"
fi
ln -snf "${NGINX_DATA}" "${NGINX_HOME}"

这段代码的逻辑意图是:如果 /www 是一个普通目录(不是软链接),则将其内容迁移到 /data/nginx,然后删除 /www,最后创建一个 /www → /data/nginx 的软链接。

问题在于:

  1. 2>/dev/null — mv 命令的所有错误输出被静默丢弃,用户看不到任何错误信息
  2. || true — 即使 mv 返回非零退出码(迁移失败),也被视为"成功"
  3. rm -rf 无条件执行 — mv 失败后,rm -rf 仍然会执行,导致源文件被永久删除

复现步骤

  1. 在服务器上创建一个包含业务数据的 /www 目录(例如网站文件)
  2. 按照官方文档执行 Pigsty 部署
  3. deploy.yml 运行到 REPO 阶段时,自动执行上述任务
  4. /www 目录及其下所有文件被删除,替换为 /data/nginx 的软链接

实际结果

  • /www 目录被 rm -rf 删除
  • /www 下的文件并未成功迁移到 /data/nginx(跨设备 mv 失败等原因)
  • 用户数据永久丢失

预期结果

  • 如果 /www 已存在且是用户数据目录,应当:
    • 跳过该操作,或
    • 提示用户并征得确认,或
    • 至少保证 mv 失败时不执行 rm

建议修复方案

if [ -d "${NGINX_HOME}" ] && [ ! -L "${NGINX_HOME}" ]; then
  if mv -f "${NGINX_HOME}"/* "${NGINX_DATA}/" 2>/dev/null; then
    rm -rf "${NGINX_HOME}"
  else
    echo "[ERROR] Failed to migrate ${NGINX_HOME} to ${NGINX_DATA}, aborting"
    exit 1
  fi
fi

或者更保守的做法:如果 /www 已存在且非空且不是软链接,直接报错退出,让用户手动处理。

额外说明

  • 默认配置中 nginx_home: /www 是一个硬编码路径, /www 是很多用户放置网站文件的常见路径,冲突概率很高
  • 文档中对此行为没有任何警告
  • 建议在文档和配置注释中明确标注此破坏性行为的风险

Metadata

Metadata

Assignees

Labels

ENHANCEMENTNew feature or request

Type

Fields

No fields configured for Bug.

Projects

Status
Done

Relationships

None yet

Development

No branches or pull requests

Issue actions