运维部署常见问题与 Linux 常用命令
约 1412 字大约 5 分钟
布欧-Lewyon
2026-06-04
前言
静态站 CI/CD 落地过程中,大量时间花在 权限、Nginx 路由、浏览器缓存、子路径前端 等「运行时」问题上,而不是构建本身。本文把常见现象、原因与命令整理成可查手册,并附 Ubuntu/Linux 日常运维命令速查。
文中路径均为示例(如 /var/www/static-site),请替换为自己的环境。
1. 部署阶段常见问题
1.1 rsync Permission denied
现象: Agent 日志出现 Permission denied,无法 mkdir / mkstemp。
原因: 站点目录由 sudo mkdir 创建,属主为 root,Agent 以普通用户(如 ubuntu)运行。
处理:
sudo mkdir -p /var/www/static-site
sudo chown -R ubuntu:ubuntu /var/www/static-site
touch /var/www/static-site/.test && rm /var/www/static-site/.test && echo OK勿将目录 chown 给 www-data 后仍用 Agent 部署:Agent 无法写入,Nginx 只需读权限(755/644 通常足够)。
1.2 部署成功但页面未更新
排查:
ls -la /var/www/static-site/index.html
# 看修改时间是否与最近一次部署一致若时间旧,检查流水线是否部署到同一 DEPLOY_DIR、是否只跑了构建未跑部署阶段。
1.3 制品解压找不到 index.html
现象: 脚本输出「未找到 dist/index.html」。
处理: 在部署日志临时目录中列出文件:
find /tmp -maxdepth 4 -name 'index.html' 2>/dev/null | head -10确认流水线 artifacts.path 与 VuePress 输出目录 docs/.vuepress/dist 一致。
2. Nginx 常见问题
2.1 根路径仍是旧站点 / Nginx 默认页
原因:
sites-enabled/default仍为default_server;- 或
/etc/nginx/nginx.conf的http{}内 还有旧的server { listen 80; ... },与sites-enabled冲突。
诊断:
ls -la /etc/nginx/sites-enabled/
sudo nginx -T 2>/dev/null | grep -E 'configuration file|listen 80|default_server|root '若出现 conflicting server name "_",说明有两个 server_name _ 在抢 80 端口。
处理:
- 删除或禁用
sites-enabled/default。 - 编辑
nginx.conf,删掉http{}内整段内联server { },只保留:
include /etc/nginx/sites-enabled/*;- 在
sites-available/your-site中配置listen 80 default_server;与正确root。
模板见仓库 deploy/nginx.conf。
2.2 子路径应用白屏或 JS 报 MIME 错误
现象:
Failed to load module script: ... MIME type of "text/html"原因 A: 浏览器请求了 /assets/xxx.js(根路径),Nginx 用博客的 try_files 回了 index.html。
- 子路径前端若按
/打包(base: './'或/),挂到/legacy-app/易出错。 - 正确做法: Vite 等构建工具设置
base: '/legacy-app/',产物中应为/legacy-app/assets/...。
原因 B: location ~* \.js$ 正则优先级高于普通前缀,把 /legacy-app/assets/xx.js 指到错误 root。
处理: 对子路径使用 ^~:
location ^~ /legacy-app/assets/ {
root /var/www;
try_files $uri =404;
}
location ^~ /legacy-app/ {
root /var/www;
try_files $uri $uri/ /legacy-app/index.html;
}诊断 MIME:
# 正确:application/javascript,内容以 function 或 ( 开头
curl -sI http://127.0.0.1/legacy-app/assets/index-xxxxx.js | grep -i content-type
curl -s http://127.0.0.1/legacy-app/assets/index-xxxxx.js | head -c 40
# 错误:text/html,内容以 <!doctype 开头
curl -sI http://127.0.0.1/assets/index-xxxxx.js | grep -i content-type浏览器: 无痕 + 禁用缓存;必要时给 script 加 ?v=2;确认使用 http:// 而非未配置证书的 https://。
2.3 API 反代 404
诊断:
# 直连后端
curl -i http://127.0.0.1:8000/api/your-endpoint
curl -i -X POST -H 'Content-Type: application/json' -d '{}' http://127.0.0.1:8000/api/your-endpoint
# 经 Nginx
curl -i http://127.0.0.1/api/your-endpoint| 情况 | 处理 |
|---|---|
| 后端 8000 通、Nginx 不通 | 检查 proxy_pass 是否多/少 /api 前缀 |
GET 404、日志 GET not supported | 接口可能仅支持 POST |
| 均 404 | 查 journalctl -u your-service -n 50 |
两种常见 proxy_pass 写法:
# 保留 /api 前缀 → 后端收到 /api/xxx
proxy_pass http://127.0.0.1:8000/api/;
# 去掉 /api 前缀 → /api/xxx 转为 /xxx
proxy_pass http://127.0.0.1:8000/;以前端实际请求路径与后端 Controller 为准。
2.4 重载配置
sudo nginx -t && sudo systemctl reload nginx3. 静态站 + 子路径应用共存检查清单
| 步骤 | 命令 / 动作 |
|---|---|
| 博客文件存在 | ls /var/www/static-site/index.html |
| 子路径 index 资源路径 | `grep -E 'src= |
| 无冲突 server | nginx -T | grep listen |
| 根站 curl | curl -s http://127.0.0.1/ | head -c 80 |
| 子路径 curl | curl -s http://127.0.0.1/legacy-app/ | head -c 80 |
| JS MIME | 见 2.2 |
4. Linux / Ubuntu 常用命令速查
4.1 文件与权限
ls -la /var/www/
sudo mkdir -p /var/www/static-site
sudo chown -R user:user /var/www/static-site
sudo chmod -R u+rwX,go+rX /var/www/static-site4.2 压缩与同步
# 打包
tar -czf dist.tar.gz -C ./dist .
# 解压到目标目录
sudo tar -xzf dist.tar.gz -C /var/www/static-site/
# 同步(部署常用)
rsync -av --delete ./dist/ /var/www/static-site/4.3 网络与端口
# 谁在监听 80 / 8000
sudo ss -tlnp | grep -E ':80|:8000'
# 本机 HTTP 探测
curl -sI http://127.0.0.1/
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1/api/ping4.4 Nginx
sudo nginx -t
sudo systemctl status nginx
sudo systemctl reload nginx
sudo nginx -T 2>/dev/null | less
tail -f /var/log/nginx/error.log4.5 系统服务(Java 等)
sudo systemctl status your-service
sudo systemctl restart your-service
journalctl -u your-service -n 50 --no-pager
journalctl -u your-service -f4.6 文本处理与排查
grep -r 'pattern' /etc/nginx/
grep -E 'src=|base href' /var/www/legacy-app/index.html
sed -i 's|old|new|' file
head -n 20 file4.7 磁盘与进程
df -h
du -sh /var/www/*
ps aux | grep java
top4.8 防火墙(若外网端口不通)
sudo ufw status
sudo ufw allow 80/tcp
sudo ufw reload云厂商安全组需在控制台放行对应端口。
5. 子路径前端重新打包要点(Vite 示例)
挂到 /legacy-app/ 时,源码中:
// vite.config.ts
export default defineConfig({
base: '/legacy-app/',
})构建后检查:
grep -E 'src=|href=' dist/index.html
# 期望:/legacy-app/assets/...上传后不要再手动加 <base href>,以免与绝对路径冲突。
6. 与仓库 deploy 目录的对应关系
| 文件 | 用途 |
|---|---|
deploy/nginx.conf | Nginx 配置模板(复制到服务器后修改) |
deploy/server-init.sh | 一次性目录权限初始化 |
deploy/sync-from-artifact.sh | 手动解压制品并 rsync(与流水线脚本逻辑一致) |
流水线内部署逻辑以 .workflow/branch-pipeline.yml 的 script: | 为准;遇问题按本文章节对照排查即可。
