10. 配置模板与检查清单

本章把常用配置和命令集中在一起。模板用于复查,第一次操作仍应阅读前面章节的解释。

1. 生产环境变量模板

文件: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

设置权限:

chmod 600 server/.env
git check-ignore -v server/.env

2. PM2 模板

文件:ecosystem.config.cjs

module.exports = {
  apps: [
    {
      name: "airport-api",
      cwd: "/var/www/airport-operations-explorer/server",
      script: "dist/server.js",
      interpreter: "node",
      instances: 1,
      exec_mode: "fork",
      env: {
        NODE_ENV: "production",
        HOST: "127.0.0.1",
        PORT: "3000"
      },
      autorestart: true,
      max_memory_restart: "750M",
      kill_timeout: 10000,
      listen_timeout: 10000,
      time: true
    }
  ]
};

启动:

pm2 start ecosystem.config.cjs
pm2 save
pm2 startup

3. Nginx 模板

文件:/etc/nginx/sites-available/airport.cxhair.cn

server {
    listen 80;
    listen [::]:80;
    server_name airport.cxhair.cn;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    server_name airport.cxhair.cn;

    root /var/www/airport-operations-explorer/client/dist;
    index index.html;

    ssl_certificate /etc/letsencrypt/live/cxhair.cn/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/cxhair.cn/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    access_log /var/log/nginx/airport.access.log;
    error_log /var/log/nginx/airport.error.log;

    location /api/ {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Request-ID $request_id;
        proxy_connect_timeout 5s;
        proxy_send_timeout 30s;
        proxy_read_timeout 30s;
    }

    location = /health {
        proxy_pass http://127.0.0.1:3000/health;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Request-ID $request_id;
        proxy_connect_timeout 5s;
        proxy_send_timeout 5s;
        proxy_read_timeout 5s;
    }

    location /assets/ {
        try_files $uri =404;
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    location / {
        try_files $uri $uri/ /index.html;
        add_header Cache-Control "no-cache";
    }
}

启用和应用:

sudo ln -s /etc/nginx/sites-available/airport.cxhair.cn \
  /etc/nginx/sites-enabled/airport.cxhair.cn
sudo nginx -t
sudo systemctl reload nginx

如果使用独立子域名证书,修改证书目录。如果 Nginx 版本不支持 http2 on;,按第 6 章改用旧版 listen 参数。

4. Certbot 命令

查看当前证书:

sudo certbot certificates

把 airport.cxhair.cn 加入名为 cxhair.cn 的现有证书:

sudo certbot --nginx \
  --cert-name cxhair.cn \
  -d cxhair.cn \
  -d airport.cxhair.cn

如果原证书还有其他域名,必须全部保留在 -d 列表中。

单独签发:

sudo certbot --nginx -d airport.cxhair.cn

测试续期:

sudo certbot renew --dry-run

5. MySQL 只读账号模板

CREATE USER 'airport_app'@'127.0.0.1'
IDENTIFIED BY '<强随机密码>';

GRANT SELECT
ON airportdb_training.*
TO 'airport_app'@'127.0.0.1';

SHOW GRANTS FOR 'airport_app'@'127.0.0.1';

不要添加 INSERT、UPDATE、DELETE、CREATE、ALTER 或 DROP。

6. 第一次上线检查清单

服务器

数据库

域名和证书

应用

Nginx

7. 日常更新检查清单

8. 回滚检查清单

9. 命令速查

项目

npm ci
npm run typecheck
npm test
npm run build
npm run check

PM2

pm2 status
pm2 logs airport-api
pm2 describe airport-api
pm2 restart airport-api
pm2 save

Nginx

sudo nginx -t
sudo systemctl reload nginx
systemctl status nginx --no-pager
sudo tail -f /var/log/nginx/airport.error.log

MySQL

systemctl status mysql --no-pager
mysql -h 127.0.0.1 -u airport_app -p airportdb_training
sudo mysql -e "SHOW FULL PROCESSLIST;"

HTTP 和 TLS

curl -i http://127.0.0.1:3000/health
curl -i https://airport.cxhair.cn/health
sudo certbot certificates
sudo certbot renew --dry-run

10. 术语速查

术语 含义
A 记录 把域名指向 IPv4 地址
SAN 一张证书实际覆盖的域名列表
HTTP-01 CA 通过公网 HTTP 路径验证域名控制权
反向代理 Nginx 接收客户端请求,再转发给内部 Express
SPA fallback 找不到静态路径时返回 index.html 交给前端路由
fork 模式 PM2 运行单个独立 Node.js 进程
优雅关闭 停止接收新请求,完成清理后退出
dump 用于恢复数据库结构和数据的导出结果
连接池 重用有限数量的数据库连接
执行计划 MySQL 执行 SQL 时选择的访问和连接方式

返回系列入口:AirportDB 从导入到上线