在使用 Jenkins 进行自动化部署时,如果目标服务器使用的是 非 root 用户 SSH 登录,你可能会遇到以下非常典型的问题:
❗ 常见问题表现
在 Jenkins 构建成功 → 推送文件成功之后,执行远程命令时报错,例如:
❌ 宝塔服务重启命令执行失败
/usr/bin/java-service 项目 stop
/usr/bin/java-service 项目 start
❌ 前端解压失败
cd /www/wwwroot/jxc-web && unzip -o dist.zip
❌ 脚本没有报错但实际操作未生效
例如:
- 服务没有重新启动
- dist 文件没有解压
- 进程没有更新
- 目录内容没有变化
🧩 1. 根本原因分析(必须看!)
你登录服务器看到类似:
Last login: Wed Dec 3 14:20:53 2025
[tdtcm@server ~]$ sudo -i
[root@server ~]#
这说明:
- SSH 登录用户(如 tdtcm)不是 root
- 但可以通过
sudo -i切换到 root
问题就在这里:
✔ Jenkins 是非交互式执行命令的
sudo -i 会进入 root shell,但下一条命令又回到普通用户,因为 shell 已退出。
所以 Jenkins 实际执行流程是:
sudo -i ←进入了,但马上退出
java-service ←再次在非 root 下执行 → 失败
unzip ←无写权限 → 失败
而且 Jenkins 中一般看不到详细的 Permission denied,所以更难排查。
🧩 2. 哪些操作需要 root 权限?
✔ 宝塔 java-service start/stop
- 会 kill 进程
- 会写日志
- 会启动 java
→ 必须 root
✔ 解压到 /www/wwwroot
宝塔默认权限:
root:root
755
任何非 root 用户 无法写入、无法覆盖文件。
✔ systemctl / service
也必须 root。
📌 所以结论是:
🟥 非 root 用户可以登录,但无法执行部署所需的核心操作。
🟦 3. 最推荐的 3 种解决方案(已按优先级排序)
🥇 方案一:配置 sudo NOPASSWD(最推荐、最稳定、最安全)
让 Jenkins 用户能够无密码执行带 sudo 的命令,而不是 sudo -i。
🔧 步骤:
编辑 sudo 配置:
sudo visudo
添加:
tdtcm ALL=(ALL) NOPASSWD:ALL
或者只赋予需要的命令:
tdtcm ALL=(ALL) NOPASSWD:/usr/bin/java-service, /usr/bin/unzip
🔧 Jenkins 脚本改成:
sudo /usr/bin/java-service 进销存项目 stop
sudo /usr/bin/java-service 进销存项目 start
sudo bash -c "cd /www/wwwroot/jxc-web && unzip -o dist.zip"
✅ 优点:
- 不需改 root 登录策略
- 不破坏宝塔权限
- Jenkins 脚本更安全
- 每条命令独立 sudo,权限不丢失
- 企业中最常用方案
🥈 方案二:root 执行整个脚本(非常稳定)
创建部署脚本:
/www/deploy.sh
#!/bin/bash
/usr/bin/java-service 进销存项目 stop
/usr/bin/java-service 进销存项目 start
cd /www/wwwroot/jxc-web
unzip -o dist.zip
Jenkins 中执行:
sudo -n bash /www/deploy.sh
🔍 关键点:
-n= 不需要输入密码- 一次 sudo,全程 root 执行
✅ 优点:
- 脚本逻辑清晰
- 不会在命令之间丢失权限
- 适合多命令、大型部署流程
🥉 方案三:直接使用 root 账户连接(最简单,但需允许 root 登录)
如果服务器允许 root SSH:
- Jenkins SSH 登录改成 root
- 所有命令都会 100% 成功
🔒 优点:
- 一步到位,无需 sudo
- 避免所有权限问题
⚠️ 缺点:
- 有些公司安全策略禁止 root 登录
- 不如方案一和方案二安全可控
🟥 不推荐的方案:修改 /www/wwwroot 权限
例如:
chown -R tdtcm:tdtcm /www/wwwroot
这会破坏宝塔默认权限
可能导致宝塔面板、Nginx、网站运行出现不可控问题。
🟦 4. 最终推荐方案总结(直接照做即可)
如果你问我最安全、最企业级、最不容易踩坑的方案:
⭐ 第一推荐:
✔ visudo → NOPASSWD → 每条命令用 sudo
Jenkins 不用 root,也能执行所有高权限命令。
⭐ 第二推荐:
✔ sudo 执行整个 deploy.sh
所有部署命令在 root 环境一次性执行,保证连续性。
⭐ 第三推荐:
✔ root 直接 SSH
最省事,但受服务器策略影响。
🎯 5. 本文适用场景
- Jenkins 使用 SSH 发布到 Linux
- 宝塔服务器部署项目
- 前端 unzip 报错
- 后端 java-service 启动失败
- Jenkins 执行非 root 权限不足
- SSH 用户无法执行系统级命令
- systemctl/kill/unzip 失败