后端代码部署到服务器,服务器配置数据库,pm2进程管理发布(四)

前置系列文章

从零开始:在阿里云 Ubuntu 服务器部署 Node+Express 接口(一)

阿里云域名解析 + Nginx 反向代理 + HTTPS 全流程:从 IP 访问到加密域名的完整配置(二)

Node+Express+MySQL 实现注册功能(三)

将代码和数据库发布到阿里云轻量服务器(Ubuntu)的核心流程是:本地准备 → 服务器环境配置 → 代码部署(含安全传输配置文件) → 数据库迁移 → 启动服务 。以下是循序渐进的详细步骤,重点解决 .env.production 不提交到 Git 的问题:

一、本地准备工作(确保代码可部署)

1. 检查本地代码规范
  • 确认 .gitignore 配置:确保已忽略敏感文件,避免提交到 Git:
env 复制代码
# 项目根目录的 .gitignore 文件必须包含以下内容
.env.development
.env.production
.env.test
node_modules/
2. 导出本地数据库结构(用于服务器初始化)

在mysql workBench中到出本地数据库mydb,只需要导出数据结构,会有一个sql文件导到本地,可以自己命名,我的叫my_db.sql

二、服务器环境准备(阿里云 Ubuntu)

1. 登录服务器

通过终端登录阿里云轻量服务器(替换为你的服务器公网 IP):

bash 复制代码
ssh root@你的服务器公网IP # 例如:ssh root@120.78.xxx.xxx

输入服务器登录密码

2. 安装必要软件

如果服务器未安装以下软件,依次执行:

bash 复制代码
# 更新系统
sudo apt update && sudo apt upgrade -y

# 安装 Node.js(推荐 v16+)
curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
sudo apt install -y nodejs

# 安装 MySQL 服务器(生产环境数据库)
sudo apt install -y mysql-server

# 安装 PM2(Node 服务进程管理工具)
sudo npm install pm2 -g

# 安装 Nginx(反向代理、静态资源服务)
sudo apt install -y nginx
3. 配置服务器 MySQL(生产环境数据库)
步骤一:初始化 MySQL 并创建生产数据库
bash 复制代码
# 登录MySQL(Ubuntu初始无密码,直接回车)
sudo mysql -u root -p

# 设置root密码(自定义强密码,如Server@Mysql2024)
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的root密码';
FLUSH PRIVILEGES;

# 创建生产数据库(与项目.env.production一致,mydb_prod是数据库名)
CREATE DATABASE mydb_prod CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

# 创建数据库专用用户(避免root直接操作)
CREATE USER 'prod_user'@'%' IDENTIFIED BY 'Prod@2024';

# 授予用户数据库权限
GRANT ALL PRIVILEGES ON mydb_prod.* TO 'prod_user'@'%';

# 刷新权限
FLUSH PRIVILEGES;

# 退出MySQL
EXIT;

.env.production如下

js 复制代码
# 环境标识
NODE_ENV=production

# 数据库配置(服务器数据库信息,变量名与开发环境完全一致)
NODE_ENV=production
DB_HOST=localhost  # 服务器数据库在本地,填localhost
DB_PORT=3306
DB_USER=prod_user  # 步骤3创建的专用用户
DB_PASSWORD=Prod@2024  # 专用用户的密码
DB_NAME=mydb_prod  # 生产数据库名
API_PORT=3000  # 后端服务端口

因为这个文件不能提交到git,所以要在服务器这个项目的根目录创建这个文件,并把上面的内容写进去就行。 我的是放在/root/projects/node-api-test下

步骤2: 导入本地表结构到服务器数据库
bash 复制代码
# 1. 在 Mac 终端另开窗口,上传本地 my_db.sql 到服务器的 /tmp 目录
scp /本地路径/my_db.sql root@你的服务器IP:/tmp/
# 例如:scp ~/project/my_db.sql root@120.78.xxx.xxx:/tmp/

# 2. 回到服务器终端,导入表结构到 mydb_prod 数据库
mysql -u root -p mydb_prod < /tmp/my_db.sql
# 输入服务器 MySQL 的 root 密码(步骤1中设置的),完成后表结构导入成功

服务器生产数据库中创建 users 表(表结构迁移)

在生产环境部署中,需将本地开发的 users 表结构迁移到服务器的 mydb_prod 数据库中,确保后端接口能正常读写用户数据。

服务器导入 users 表结构到 mydb_prod

登录服务器终端,将表结构导入生产数据库:

bash 复制代码
# 服务器终端执行(输入prod_user的密码Prod@2024) 
mysql -u prod_user -p mydb_prod < /tmp/my_db.sql
(4)验证表是否创建成功

登录服务器 MySQL,检查 users 表是否存在:

bash 复制代码
# 服务器终端登录MySQL
mysql -u prod_user -p mydb_prod

# 查看数据库中的表
SHOW TABLES;  # 应显示 users 表

# 查看表结构(可选)
DESCRIBE users;  # 显示 users 表的字段、类型等结构信息

# 退出MySQL
EXIT;

补充说明

  • 若本地 users 表有初始必要数据(如管理员账号),可去掉 --no-data 参数,导出包含数据的表结构:mysqldump -u 本地用户名 -p 本地数据库名 users > users_with_data.sql,再按相同步骤导入。
  • 表结构迁移是生产部署的关键步骤,确保服务器数据库表结构与本地开发环境一致,否则会出现 "表不存在""字段缺失" 等接口错误。

发布代码

登录服务器,cd /root/xxx/xxx 到自己的项目根目录,执行git pull ,然后执行pm2 restart node-api-test

这时候会报错,提示环境变量是undefined,process.env.NODE_ENV 打印出的永远是undefined,所以下面这段代码,发布到服务器上就挂了

js 复制代码
const env = process.env.NODE_ENV || 'development'
const envPath = path.resolve(__dirname, `../.env.${env}`)
console.log('envPath', envPath) 
// 会打印出undefined

原因分析

  1. 当你在服务器命令行直接输入 pm2 start app.js 时,Linux shell 并没有设置 NODE_ENV,代码里 process.env.NODE_ENV 就会变成 undefined,然后你的代码兜底逻辑将其设为 development,于是去读开发环境的配置,导致报错。

  2. app.js 方式启动: 执行 pm2 start app.js 时,PM2 只是简单地执行 node app.js。除非你在操作系统层面(如 /etc/profile)设置了全局 NODE_ENV,否则它就是空的。

解决方案:

使用 ecosystem.config.cjs(最推荐,工业标准

项目根目录创建ecosystem.config.cjs

js 复制代码
// ecosystem.config.cjs
module.exports = {
  apps: [
    {
      name: 'node-api-test',
      script: './app.js',
 
      instances: 1,
      autorestart: true,
      watch: false,
      env: {
        NODE_ENV: 'development',
      },
      env_production: {
        NODE_ENV: 'production',
      },
    },
  ],
}

启动命令

以后在服务器上启动或重启,统一使用以下命令,不要再用 pm2 start app.js:

bash 复制代码
 #   首次启动(生产):
 pm2 start ecosystem.config.cjs --env production
 #    代码更新后重启 平滑重载(零停机):
 pm2 reload ecosystem.config.cjs --env production
 #   完全重启:
 pm2 restart ecosystem.config.cjs --env production

最终测试

相关推荐
消失的旧时光-19434 小时前
Kotlinx.serialization 对多态对象(sealed class )支持更好用
java·服务器·前端
少卿5 小时前
React Compiler 完全指南:自动化性能优化的未来
前端·javascript
广州华水科技5 小时前
水库变形监测推荐:2025年单北斗GNSS变形监测系统TOP5,助力基础设施安全
前端
广州华水科技5 小时前
北斗GNSS变形监测一体机在基础设施安全中的应用与优势
前端
七淮5 小时前
umi4暗黑模式设置
前端
8***B5 小时前
前端路由权限控制,动态路由生成
前端
bcbnb5 小时前
如何解析iOS崩溃日志:从获取到符号化分析
后端
许泽宇的技术分享5 小时前
当AI学会“说人话“:Azure语音合成技术的魔法世界
后端·python·flask
用户69371750013845 小时前
4.Kotlin 流程控制:强大的 when 表达式:取代 Switch
android·后端·kotlin
用户69371750013845 小时前
5.Kotlin 流程控制:循环的艺术:for 循环与区间 (Range)
android·后端·kotlin