备份包只有 1.5K?

改 OpenResty 配置之前我做了备份。备份包躺在目录里,1.5K。

这台机器不是我一个人的。1Panel 面板上挂着 9 个站点,我自己的 3 个,别人的 6 个。我那三个域名是 h5.example.com、api.example.com、admin.example.com。

在这种机器上,任何一次 nginx -s reload 都在同时动 9 个业务。所以我先备份,再改配置。给的那条命令是这一条。

bash 复制代码
tar -czf "$BK" $(dirname $(find /opt/1panel -name "*.conf" -path "*conf.d*" 2>/dev/null | head -1))

跑完 ls -lh 一看。

复制代码
-rw-r--r-- 1 root root 1.5K Sep 22 20:41 openresty_backup.tar.gz

九个站点的配置,压缩完 1.5K。这个数字本身就在报警。可我当时接下去做的事是改配置,不是打开包看看。

这条命令我是怎么想出来的

拆开看,里头叠了三层错。单看每一层,都像个好习惯。

第一层出在 -path "conf.d"。我一开始想的是「站点配置都在 conf.d 里」,就先拿 -path 筛了一遍。可 /opt/1panel 下面不止一个 conf.d,面板自己的、镜像默认的、各个应用目录里都有。这个条件没能帮我定位到站点配置,只是把候选集缩成了一堆同名目录。

第二层是 | head -1。这层最致命。find 的输出顺序取决于文件系统怎么遍历,不是按重要性排的,也不保证稳定。第一条是谁,不知道。

第三层是 $(dirname ...)。它把「一个文件」换成了「一个目录」,然后只备份这一个目录。

三层叠起来的结果是,find 找到的第一个 .conf 所在的那个目录被打包,其余全都不进包。而它实际取到的是面板或者镜像自带的那个默认 conf.d,里面是出厂配置,不含任何站点配置。

两个目录的挂载关系是这样。

复制代码
宿主  /opt/1panel/www         ──>  容器内  /www
宿主  /opt/1panel/www/conf.d  ──>  容器内  /usr/local/openresty/nginx/conf/conf.d

真正要备份的站点配置在 /opt/1panel/www/... 这一支上,我取到的是另一支。

还有第四层,也是最该记住的一层。我没验证。tar 不报错,ls 显示文件存在,退出码是 0。一个空备份和一份有效备份,在命令行回显上长得一模一样。

哪一刻确认它等于没备份

让我确认的是这条命令。

bash 复制代码
tar -tzf "$BK" | grep -E "example\.com"

没有任何输出。

tar -tzf 列出包内文件清单,grep 拿域名关键字去筛,一个站点都没有。那时候我正准备改一个 OpenResty 配置,改错就要回滚,而回滚依据的那个包里一片空白。同机 6 个别人的站点正跑着。

验收标准只有一个,我要保的域名在不在包里

这件事给我的教训不是「命令写错了」。一个 1.5K 的包确实存在,可它承诺不了任何东西。所以验收动作得回答一个具体问题:我要保的那几个域名,在包里吗?

正确打包,是把 find 的结果整体交给 tar,而不是取一条再 dirname。

bash 复制代码
BK=/opt/1panel/backup; TS=$(date +%Y%m%d_%H%M%S); mkdir -p "$BK"

# ① 全量打包:find 的结果通过 -T - 从 stdin 交给 tar,绕开参数展开与空格问题
find /opt/1panel -name "*.conf" -type f 2>/dev/null \
  | tar -czf "$BK/openresty_all_$TS.tar.gz" -T -
ls -lh "$BK/openresty_all_$TS.tar.gz"

# ② 必须验证:列得出域名才算备份成立
tar -tzf "$BK/openresty_all_$TS.tar.gz" | grep -E "example\.com"

-T - 这处是关键。tar 从标准输入读文件列表,绕开了 $(...) 展开带来的参数个数上限和文件名空格问题。如果路径里可能有空格,用 -print0 与 --null 配对。

bash 复制代码
find /opt/1panel -name "*.conf" -type f -print0 2>/dev/null \
  | tar -czf "$BK/openresty_all_$TS.tar.gz" --null -T -

验证这一步不是可选项,它是备份的一部分。只做打包、不做验证,和那条 head -1 命令没有本质区别,你只是换了一种方式不知道自己备份了什么。

还有一点不显眼但很要命:备份包要带时间戳命名,就是上面命令里的 $TS。它不是为了归档整齐,而是为了不覆盖上一份。你永远不知道上一份是不是唯一一份还有效的。

顺带一条,怎么确认真正生效的配置在哪个文件

面板托管的 Nginx,配置文件位置不一定是你以为的那个。这条命令能 dump 全部生效配置,并把每一段配置的来源文件打出来。

bash 复制代码
docker exec <面板web容器> nginx -T 2>&1 \
  | sed -n 's/^# configuration file \(.*\):$/\1/p' | sort -u

两点要注意。输出的是容器内路径,要对照挂载关系换算成宿主路径,比如 /www/... 换回 /opt/1panel/www/...。它回答的是「哪些文件被真正加载了」,这正好就是你的备份清单该覆盖的集合。

固化成几条能复用的判据

打包这一步,做法是 find 根路径 -name "*.conf" -type f -print0 交给 tar -czf 包 --null -T -。不用 head,也不用 dirname 取单条。验证内容这步是 tar -tzf 包 再 grep -E "域名关键字",列得出生效域名才算过,列不出来就回到打包那步重来。验证可解是 tar -xzf 包 -C /tmp/verify 之后 ls /tmp/verify,看能不能解出目录树。

确认配置来源还是用 docker exec 进面板 web 容器跑 nginx -T。再 sed 出 # configuration file 那几行去重。改前基线要逐个域名 curl 一遍,参数是 -s -o /dev/null -w "%{http_code}" --max-time 8。再带上 Host 头打 http://127.0.0.1/,全 200 或者 301 就记录下来。改后用同一条 for 循环再跑一次,跟基线对照,掉了就立刻回滚。语法门禁是 docker exec 进容器跑 nginx -t,看到 syntax is ok 才 reload。

基线和改后对照这两步在这台机器上尤其重要。它的粒度不是「我这个站点」,而是「这台机上全部 9 个」。

grep 的关键字要覆盖他人站点的域名,不能只 grep 自己的。你动的这份配置,影响的是整台机。

剩下的几条我一起放在这里。find 加 head -1 取到的不是「一个代表」,它是个「未知」,备份要全量,用 -T - 把清单整体交给 tar。1.5K 这个数字本身就是信号,备份体积和常识不匹配的时候,先停下来。nginx -T 能打出每一段配置的来源文件,这是该备份哪些文件的权威清单。

备份不做验证,那张包就是空的。

相关推荐
Linux-lucky8 小时前
45-Linux学习之旅之防火墙与WEB加固
linux·前端·网络·学习·ubuntu
禁默8 小时前
启元 Q1 二次开发实践:Ubuntu 部署与仿真验证,从 PrimeConsole 到 ROS 2 Humble + RViz
linux·运维·ubuntu
skywalk81639 小时前
把 去也网站 从 Ubuntu 搬到 FreeBSD:一次 Service Jail + nginx 的部署实录
linux·运维·nginx·ubuntu·freebsd
爱莉希雅&&&11 小时前
GitLab 完整学习笔记
linux·运维·服务器
风笙97811 小时前
[文件系统]文件系统挂载与卸载详解
linux
GeW11 小时前
新质生产力路线图解读:数据库性能优化与Linux调优专场
linux·数据库
博客zhu虎康11 小时前
实现局域网P2P通信:内网发送消息
网络·网络协议·p2p
吴声子夜歌12 小时前
Kubernetes权威指南——网络原理(一)
网络·容器·kubernetes
陈希12313 小时前
Linux 服务器性能排查手册(2026):CPU、内存、磁盘IO、网络四大瓶颈定位
linux·服务器·网络
国科安芯14 小时前
从遥控到自治:ASP4644S2B支撑星载电源健康管理与容错配电
网络·单片机·嵌入式硬件·安全·dcdc·低轨卫星·商业航天