
liu
一个专为懒猫微服平台设计的启动脚本管理框架,让你的系统配置在重启后自动恢复
项目地址:https://github.com/lazycatapps/user-startup.d
你是否曾经遇到过这样的场景:
如果你正在使用 懒猫微服平台,这些都不是你的错!这是平台的特殊设计——系统重启后会自动还原所有修改。
但是,有没有办法让这些配置自动恢复呢?
答案是:有! 而且只需要 5 分钟就能搞定。
懒猫微服平台采用了一个独特的系统设计:重启后会自动还原所有系统修改。
这意味着:
apt install 安装的软件会在重启后消失为什么要这样设计? 根据 官方 FAQ:
懒猫官方提供了两种解决方案(详见 官方文档):
| 特性 | user-startup.d (Hook) | Systemd 用户服务 | Docker 容器 |
|---|---|---|---|
| 配置复杂度 | ⭐ 简单 | ⭐⭐ 中等 | ⭐⭐⭐ 复杂 |
| 学习成本 | Shell 脚本基础即可 | 需了解 systemd | 需了解 Docker |
| 日志管理 | ✅ 统一集中 | ❌ 需手动配置 | ❌ 需手动配置 |
| 脚本组织 | ✅ 目录结构清晰 | ❌ 分散的 service 文件 | ❌ 混在 compose 文件中 |
✅ 降低配置门槛 - 直接使用熟悉的 Shell 脚本,无需学习 systemd 或 Docker
✅ 统一日志管理 - 所有日志集中存放在 /tmp/user-startup-hooks/
✅ 灵活控制执行顺序 - 使用数字前缀控制脚本执行顺序,支持同步/异步模式
✅ 不阻塞系统启动 - 使用 nohup 后台执行,Hook 入口脚本快速退出
✅ 开箱即用 - 提供脚本模板和 Makefile 工具,一键安装/卸载
user-startup.d/
├── Makefile # 一键安装/卸载工具
├── template.sh # 脚本模板
├── user-startup-entrypoint.sh # Hook 入口(快速派发)
├── main.sh # 主调度器(后台执行)
├── init.async/ # 异步脚本目录(并行执行)
│ └── *.sh
└── init.sync/ # 同步脚本目录(顺序执行)
├── 1.wait-network.sh
├── 2.set-debian-sources.sh
├── 3.install-tools.sh
└── ...
系统启动 → 用户解锁数据盘 → data-disk-ready Hook 触发
↓
user-startup-entrypoint.sh (快速派发)
↓ nohup 后台
main.sh
├─ 阶段1: init.async/*.sh (并行执行)
└─ 阶段2: init.sync/*.sh (顺序执行)
关键特性:
/tmp/user-startup-hooks/| 类型 | init.async/ | init.sync/ |
|---|---|---|
| 执行方式 | 后台并行,使用 nohup | 顺序执行,等待前一个完成 |
| 适用场景 | 耗时且不阻塞的任务 | 有依赖关系的任务 |
| 典型示例 | NFS挂载、DDNS更新、日志上传 | 网络等待、软件安装、配置文件修改 |
系统启动 → 提示输入硬盘密码 → 用户解锁 → 数据盘就绪 → 触发 hook
此时的系统状态:
| 状态 | 是否就绪 | 说明 |
|---|---|---|
| 数据盘 | ✅ 已挂载 | 可以安全访问 /data 等用户目录 |
| 网络 | ⚠️ 可能未就绪 | 需要主动等待(参考 1.wait-network.sh) |
| Docker | ⚠️ 可能未启动 | 如需使用 Docker 需检查服务状态 |
# 1. 克隆项目到懒猫微服推荐位置
cd /root
# 你也可以 Fork 到自己的组织下后,将 <lazycatapps> 替换为你自己的组织名
git clone https://github.com/lazycatapps/user-startup.d.git
cd user-startup.d
# 2. 安装系统 hook
make install
# 3. 验证安装状态
make status
预期输出:
Wrapper script is installed:
-rwxr-xr-x 1 root root 153 Jan 11 12:52 /lzcsys/var/custom/hooks/data-disk-ready/user-startup-entrypoint.sh
Content:
#!/bin/bash
# Auto-generated wrapper script
# This script calls the actual entrypoint script
exec "/root/user-startup.d/user-startup-entrypoint.sh" "$@"

# 1. 从模板创建新脚本
cp template.sh init.sync/6.hello-world.sh
# 2. 添加执行权限
chmod +x init.sync/6.hello-world.sh
# 3. 编辑脚本
vim init.sync/6.hello-world.sh
编辑内容(在"主要逻辑"部分添加):
# ============================================
# 主要逻辑
# ============================================
log "============================================"
log "Starting task: ${SCRIPT_NAME}"
log "Hello, Lazycat User!"
log "Current time: $(date)"
log "Current user: $(whoami)"
log "Hostname: $(hostname)"
log "Task completed successfully"
log "============================================"
# 方法1: 单独测试脚本
./init.sync/6.hello-world.sh
# 方法2: 测试完整流程(推荐)
./main.sh
# 查看执行日志
cat /tmp/user-startup-hooks/init.sync/6.hello-world.log
预期输出:
2026-01-11 12:00:00 - ============================================
2026-01-11 12:00:00 - Starting task: 6.hello-world
2026-01-11 12:00:00 - Hello, Lazycat User!
2026-01-11 12:00:00 - Current time: Sat Jan 11 12:00:00 CST 2026
2026-01-11 12:00:00 - Current user: root
2026-01-11 12:00:00 - Hostname: lazycat-server
2026-01-11 12:00:00 - Task completed successfully
2026-01-11 12:00:00 - ============================================
# 重启系统
sudo reboot
# 重启后,查看执行结果
cat /tmp/user-startup-hooks/main.log
cat /tmp/user-startup-hooks/init.sync/6.hello-world.log
🎉 恭喜!你已经成功创建并运行了第一个启动脚本!
始终从 template.sh 复制,保持一致的结构:
#!/bin/bash
# 脚本说明
# 日志配置(标准配置,所有脚本保持一致)
SCRIPT_NAME="$(basename "$0" .sh)"
SCRIPT_DIR_NAME="$(basename "$(dirname "$0")")"
LOG_DIR="/tmp/user-startup-hooks/${SCRIPT_DIR_NAME}"
LOG_FILE="${LOG_DIR}/${SCRIPT_NAME}.log"
mkdir -p "$LOG_DIR"
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}
# 脚本配置区域
# CONFIG_VAR="value"
# 主要逻辑
log "============================================"
log "Starting task: ${SCRIPT_NAME}"
# 你的代码...
log "Task completed successfully"
log "============================================"
确保脚本多次执行结果一致:
# ❌ 错误示例(非幂等)
echo "export PATH=/opt/bin:\$PATH" >> ~/.bashrc
# ✅ 正确示例(幂等)
if ! grep -q "export PATH=/opt/bin" ~/.bashrc; then
echo "export PATH=/opt/bin:\$PATH" >> ~/.bashrc
log "Added /opt/bin to PATH"
else
log "PATH already configured, skipping"
fi
需要网络的操作应先等待网络:
# 检查网络连接
log "Checking network connectivity..."
for i in {1..12}; do
if ping -c 1 -W 2 8.8.8.8 >/dev/null 2>&1; then
log "Network is ready"
break
fi
log "Waiting for network... (attempt $i/12)"
sleep 5
done
if ! ping -c 1 -W 2 8.8.8.8 >/dev/null 2>&1; then
log "ERROR: Network timeout after 60 seconds"
exit 1
fi
# Makefile 命令
make help # 显示帮助信息
make install # 安装系统 hook
make uninstall # 卸载系统 hook
make status # 检查安装状态
# 手动执行
./main.sh # 测试完整流程
./init.sync/1.wait-network.sh # 执行单个脚本
# 查看日志
cat /tmp/user-startup-hooks/main.log # 查看主日志
tail -f /tmp/user-startup-hooks/init.sync/1.wait-network.log # 实时监控
# 调试
bash -x ./init.sync/6.my-task.sh # 启用调试模式
# 禁用脚本
chmod -x init.sync/3.install-tools.sh # 移除执行权限
mv init.sync/3.install-tools.sh{,.disabled} # 重命名文件
user-startup-entrypoint.sh 中直接执行耗时任务nohup 将任务派发到后台(框架已实现)apt-get update)1.wait-network.sh)1. 日志路径使用 /tmp
/data/logs/ 路径2. 脚本执行顺序混乱
3. 错误未记录日志
4. 忘记测试脚本
./script.sh 和 ./main.shtemplate.sh 复制创建新脚本./script.sh./main.shmake install 成功make status 检查状态make status # 检查 hook 是否安装
ls -l init.sync/*.sh # 检查脚本执行权限
cat /tmp/user-startup-hooks/main.log # 查看主日志
./main.sh # 手动执行测试
cat /tmp/user-startup-hooks/init.sync/xxx.log # 查看脚本日志
./init.sync/xxx.sh # 手动执行脚本
bash -x ./init.sync/xxx.sh # 使用调试模式
echo $? # 检查退出码(非 0 表示失败)
ls -l init.sync/1.wait-network.sh # 确保网络等待脚本在最前面
ping -c 3 8.8.8.8 # 手动测试网络
cat /tmp/user-startup-hooks/init.sync/1.wait-network.log # 查看网络等待日志
使用 user-startup.d 框架,你可以:
# 1. 克隆并安装
git clone https://github.com/lazycatapps/user-startup.d.git /root/user-startup.d
cd /root/user-startup.d && make install
# 2. 创建第一个脚本
cp template.sh init.sync/6.my-first-task.sh
chmod +x init.sync/6.my-first-task.sh
# 3. 测试运行
./main.sh
https://github.com/lazycatapps/user-startup.dhttps://github.com/lazycatapps/user-startup.d/issues欢迎以下贡献:
懒猫微服的"重启还原"特性曾经让你感到困扰,现在通过 user-startup.d 框架,它变成了一种优势:
只需 5 分钟,你就能搭建起自己的启动脚本管理系统。
现在就开始吧! 🚀
关于本文档
评论
0暂无评论