后端代码部署到服务器,服务器配置数据库,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

最终测试

相关推荐
雪碧聊技术1 天前
前端项目代码发生改变,如何重新部署到linux服务器?
前端·vue3·centos7·代码更新,重新部署
liulilittle1 天前
C++ 浮点数封装。
linux·服务器·开发语言·前端·网络·数据库·c++
韩立学长1 天前
基于Springboot流浪动物领养网站0kh2iyb4(程序、源码、数据库、调试部署方案及开发环境)系统界面展示及获取方式置于文档末尾,可供参考。
数据库·spring boot·后端
wordbaby1 天前
Expo 进阶指南:赋予 TanStack Query “原生感知力” —— 深度解析 AppState 与 NetInfo
前端·react native
Moment1 天前
从美团全栈化看 AI 冲击:前端转全栈,是自救还是必然 🤔🤔🤔
前端·后端·面试
天问一1 天前
使用 Vue Router 进行路由定制和调用的示例
前端·javascript·vue.js
a努力。1 天前
腾讯Java面试被问:String、StringBuffer、StringBuilder区别
java·开发语言·后端·面试·职场和发展·架构
源码获取_wx:Fegn08951 天前
基于springboot + vue心理健康管理系统
vue.js·spring boot·后端
韩立学长1 天前
【开题答辩实录分享】以《基于Vue的非遗文化知识分享平台的设计与实现》为例进行选题答辩实录分享
前端·javascript·vue.js
优弧1 天前
离开舒适区100天,我后悔了吗?
前端·后端·面试