07. 第一次完整上线
1. 本章目标
前面的章节分别完成了数据库、域名、证书、PM2 和 Nginx。本章把它们整理成第一次上线的顺序清单。不要跳过中间验证;这样失败时能立即知道是哪一层的问题。
2. 上线前条件
airport.cxhair.cn已解析到服务器;- 服务器 80、443 可访问;
- Node.js 不低于 22.20.0;
- MySQL 已导入 AirportDB;
airport_app对训练库只有SELECT;- Git 仓库已经推送到服务器可访问的位置;
- 证书已经覆盖
airport.cxhair.cn,或准备在 Nginx HTTP 站点完成后申请。
3. 获取代码
若目录还不存在:
sudo mkdir -p /var/www/airport-operations-explorer
sudo chown deploy:deploy /var/www/airport-operations-explorer
git clone <仓库URL> /var/www/airport-operations-explorer
cd /var/www/airport-operations-explorer
确认分支与提交:
git status --short --branch
git rev-parse HEAD
服务器工作区应保持干净。不要在服务器直接修改受 Git 管理的代码;否则下次更新会出现冲突,而且修改无法通过本地测试和代码审查。
4. 创建生产环境变量
cp .env.example server/.env
chmod 600 server/.env
填写:
NODE_ENV=production
HOST=127.0.0.1
PORT=3000
CLIENT_ORIGIN=https://airport.cxhair.cn
LOG_LEVEL=info
DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=airportdb_training
DB_USER=airport_app
DB_PASSWORD=<强随机密码>
DB_POOL_MAX=10
DB_HEALTH_TIMEOUT_MS=2000
确认没有被 Git 跟踪:
git status --short
git check-ignore -v server/.env
5. 安装、检查和构建
npm ci
npm run check
根目录 npm run check 会依次执行类型检查、测试和前后端构建。任何一步失败都停止上线。不要在服务器用 --force 跳过依赖或类型错误。
确认产物:
test -f server/dist/server.js
test -f client/dist/index.html
6. 前台验证后端
cd server
NODE_ENV=production node dist/server.js
另一个会话:
curl -i http://127.0.0.1:3000/health
预期 HTTP 200、应用状态 ok、数据库状态 up。确认后按 Ctrl+C。
这一步把“代码或环境变量问题”与“PM2 配置问题”分开。如果前台都不能运行,不要进入 PM2。
7. 启动 PM2
在仓库根目录准备第 5 章的 ecosystem.config.cjs,然后:
cd /var/www/airport-operations-explorer
pm2 start ecosystem.config.cjs
pm2 status
curl -i http://127.0.0.1:3000/health
pm2 save
首次部署还要执行 pm2 startup 输出的 systemd 命令。
8. 配置 Nginx
安装第 6 章的配置:
sudo nginx -t
sudo systemctl reload nginx
如果证书尚未申请,先使用纯 HTTP server 完成 Certbot 验证,再由 Certbot 安装证书或手工合并 HTTPS 配置。
9. 从外到内验证
DNS
dig +short airport.cxhair.cn A
HTTPS 和证书
curl -I https://airport.cxhair.cn/
SPA 页面
curl -I https://airport.cxhair.cn/flights
API 与数据库
curl -i https://airport.cxhair.cn/health
监听范围
sudo ss -lntp | grep -E ':80|:443|:3000|:3306'
3000 和 3306 应绑定到回环地址或预期私有地址,不应为公网的 0.0.0.0。
进程与日志
pm2 status
pm2 logs airport-api --lines 100
sudo tail -n 100 /var/log/nginx/airport.error.log
10. 浏览器冒烟测试
用浏览器完成:
- 打开首页;
- 刷新
/flights等前端路由; - 查看开发者工具 Network;
- 确认接口请求使用
https://airport.cxhair.cn/...同源地址; - 确认没有 Mixed Content 或 CORS 错误;
- 确认健康状态能显示 API 与数据库情况。
如果前端仍请求 localhost:3000,说明代码硬编码了开发地址。生产前端必须使用相对路径。
11. 发布记录
至少记录:
发布时间:
Git commit:
Node.js 版本:
MySQL 版本:
Nginx 版本:
PM2 版本:
数据库 schema:
健康检查结果:
执行人:
不要在记录中写数据库密码或私钥路径内容。
12. 本章验收
https://airport.cxhair.cn正常打开;- 刷新 Vue 路由正常;
/health通过 Nginx 返回 200;- PM2 和 Nginx 日志没有持续错误;
- PM2 已配置开机恢复;
- Git commit 和版本信息已经记录。
下一章:日常更新与回滚