前面我们已经在ESC上部署了前端Vue应用、后端Express,现在就差数据库了。 本来是用MongoDB Altas(MongoDB 官方推出的云托管 MongoDB 数据库服务),但是国外的数据库服务,网络有点不稳定,所以决定自己安装MongoDB 社区版
我的ECS配置是2核2G 40g 云盘 系统是Alibaba Cloud Linux 4 LTS 64位
我们开始吧
- 安装mongoDB 社区版
- 启动mongoDB
- 为数据库添加访问控制,比如admin用户才可以(可选)
- 后端连接我们在ECS安装的mongoDB
安装mongoDB 社区版
我们看下官网文档,根据不同的系统,发行版本选择,对应的命令,比如我这里服务器是Alibaba Cloud Linux 4, 所以就是Linux, Red Hat

配置 MongoDB 的 YUM 软件仓库地址,让系统知道从哪里下载 MongoDB
bash
[mongodb-org-8.2]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/8/mongodb-org/8.2/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://pgp.mongodb.com/server-8.0.asc
MongoDB 8.2 使用 8.0 的 GPG 密钥 gpgkey=pgp.mongodb.com/server-8.0.... ✅ 正确
为什么 8.2 用 8.0 的密钥? MongoDB 的 GPG 密钥是按主版本(major version)管理的
1. 在ECS上创建一个 MongoDB 的 YUM 软件源配置文件 ,以便通过dnf或yum包管理器安装MongoDB 8相关软件
登录ECS,执行命令
bash
sudo tee /etc/yum.repos.d/mongodb-org-8.0.repo <<EOF
[mongodb-org-8.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/8/mongodb-org/8.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://pgp.mongodb.com/server-8.0.asc
EOF
为什么我不安装MongoDB 8.2版本呢,上面那个官方文档就是8.2,因为我当时是问了GROK ai,那个给的就是8.0版本,所以官方文档最靠谱
各部分含义拆解如下:
-
sudo- 以系统管理员(root)权限执行命令,因为写入
/etc/yum.repos.d/目录(系统软件源配置目录)需要管理员权限
- 以系统管理员(root)权限执行命令,因为写入
-
tee /etc/yum.repos.d/mongodb-org-8.0.repo- tee: 命令行工具,用户将输入内容同时写入指定文件和输出到屏幕(方便确认内容是否正确写入)
/etc/yum.repos.d/mongodb-org-8.0.repo: 目标文件路径。/etc/yum.repos.d是Linux系统默认存放软件源配置的目录,.repo是YUM/DNF源配置文件到标准后缀,文件名mongodb-org-8.0.repo明确标识了这是MongoDB8.0的源配置
-
<<EOF 和 EOF
- 这是
Shell中的Here Document(嵌入文档)语法,用于将<<EOF和EOF之间的内容作为输入传递给tee命令。EOF是分隔符(可替换为其他字符串,如END), 前后必须一致且单独成行,确保内容边界清晰。
- 这是
-
中间的配置内容(MongoDB 8.0源信息)
ini
[mongodb-org-8.0] # 软件源的唯一标识(方括号内的名称),用于区分系统中的其他软件源
name=MongoDB Repository # 软件源的描述名称,方便用户识别(此处为"MongoDB 仓库")
baseurl=https://repo.mongodb.org/yum/redhat/8/mongodb-org/8.0/x86_64/ # 软件包的实际下载地址:针对 Red Hat 8 系统、x86_64 架构的 MongoDB 8.0 官方源
gpgcheck=1 # 是否启用 GPG 签名校验(1 表示启用,用于验证软件包的完整性和安全性,防止被篡改)
enabled=1 # 是否启用该软件源(1 表示启用,0 表示禁用,启用后包管理器会从该源检索软件)
gpgkey=https://pgp.mongodb.com/server-8.0.asc # GPG 公钥文件的地址,用于校验软件包的签名
总结 这条命令的最终效果是:在系统中创建一个 MongoDB 8.0 官方源的配置文件 ,告诉包管理器(dnf/yum)可以从该源下载并安装 MongoDB 8.0 相关软件,同时通过 GPG 校验确保软件包的安全性。执行后,即可通过 sudo dnf install -y mongodb-org 等命令安装 MongoDB 8.0 了。
导入 MongoDB 的 GPG 公钥到系统
bash
sudo rpm --import https://pgp.mongodb.com/server-8.0.asc
导入 MongoDB 的 GPG 公钥到系统, 为什么需要公钥
下载软件包 → 验证签名 → 确认是官方发布 → 安全安装
↓
没有公钥 = 无法验证 = 安装失败或警告
清理 DNF 包管理器的所有缓存
bash
sudo dnf clean all
为什么要清理缓存?
| 原因 | 说明 |
|---|---|
| 🔄 刚配置了新源 | 确保使用最新的源信息 |
| 🐛 缓存损坏 | 解决安装错误 |
| 💾 释放空间 | 清理不需要的旧文件 |
| 🆕 强制刷新 | 获取最新的软件包列表 |
安装mongodb
bash
sudo yum install -y mongodb-org
配置 MongoDB 的 YUM 软件仓库地址,安装的完整截图



启动mongoDB服务
上面我们已经成功的安装了8.0.15-1这个版本,我们先把数据库服务启动
启动 MongoDB 服务器(后台服务)
bash
sudo systemctl start mongod # 启动 MongoDB 服务器
sudo systemctl enable mongod # 设置开机启动
sudo systemctl status mongod # 检查服务状态

启动 MongoDB Shell, 在ECS终端输入mongosh
bash
// 连接到本地默认 MongoDB
mongosh
这样就可以开启, 与MongoDB数据库进行交互的命令行界面, 可以看到第一次连接数据库的时候, 产生了一些警告

比如截图的第二条
Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
就是说咱们的数据库没有限制,谁都可以读写咱们的数据库
配置数据库访问权限
编辑配置文件/etc/mongod.conf,启动验证
我们编辑下配置文件
bash
sudo nano /etc/mongod.conf
把security取消注释,authorization改为enabled,允许验证
yaml
security:
authorization: enabled
保存(Ctrl+O > Enter > Ctrl+X for nano)。重启mongod服务
bash
sudo systemctl restart mongod
sudo systemctl status mongod # 确认running

增加管理员用户
我们先切换到 admin 数据库, 因为admin数据库是特殊的管理数据库
bash
use admin
- MongoDB中admin数据库是系统级数据库
- 所有的管理员用户必须存储在admin数据库中
- 只有在admin数据库中创建的用户才能拥有跨数据库的管理权限
如果你不先 use admin,而是在其他数据库(比如默认的 test)中创建管理员,这个用户就只能管理 test 数据库,无法管理整个 MongoDB 实例。
php
db.createUser({
user: "admin",
pwd: "xxxxxxxx", // 用您实际密码替换
roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db: "admin" },
{ role: "dbAdminAnyDatabase", db: "admin" }
]
})
咱们详细解释下上面命令
- user 是登录使用的账号名
- pwd 账号对应的密码
- roles 角色数组,定义了用户的权限。这里分配了三个角色:
- userAdminAnyDatabase 用户管理权限,只管理用户,不能读写数据
- readWriteAnyDatabase 在任何数据库中 读写数据
- dbAdminAnyDatabase 管理数据库结构
markdown
## 为什么需要三个角色?
每个角色负责不同的职责,组合起来形成**超级管理员**:
userAdminAnyDatabase → 管理用户和权限
+
readWriteAnyDatabase → 操作数据(增删改查)
+
dbAdminAnyDatabase → 管理数据库结构
=
完整的管理员权限

执行成功,输出{ ok: 1 },就表示用户创建成功了
scss
db.getUsers()
通过db.getUsers()也可以查看我们新增的用户是否成功

由于我们现在已经启动验证 ,现在执行mongosh,是可以连接到mongoDB数据库,但是想要读写数据库,读写用户就不行了,会提示我们没有权限

使用存储在 admin 数据库中的 admin 用户进行认证登录
前面我们创建的admin用户就是保存在admin数据库,所以我们使用 admin 数据库中的admin用户认证
shell
# 1. 使用 admin 数据库中的用户认证
mongosh -u admin --authenticationDatabase admin
# 2. 登录后在 test 数据库
test>
# 3. 可以切换到任何数据库工作
test> use myapp
switched to db myapp
myapp> show collections
# 4. 也可以切换到 admin 数据库
myapp> use admin
switched to db admin
admin> db.getUsers()
- mongosh: 启动 MongoDB Shell 客户端
- -u admin: 使用用户名 admin 登录
- --authenticationDatabase admin: 指定认证数据库为 admin
- 去admin数据库中查找用户admin的认证信息
- 在admin数据库中验证密码是否正确
- 登录后默认连接的是test数据库

如果想直接连接到特定数据库 可以在连接字符串中指定:
bash
# 认证使用 admin,但直接进入 myapp 数据库工作
mongosh "mongodb://admin:password@localhost:27017/myapp?authSource=admin"
后端express连接mongoDB
前面我们mongod.conf配置文件,关于网络的,绑定IP是127.0.0.1,那就是ECS上的Mongo服务器, 只允许ECS上的后端服务访问,虽然也可以修改IP,开放外网
mongod.conf配置文件, 只允许本地访问
bash
# network interfaces
net:
port: 27017
bindIp: 127.0.0.1 # Enter 0.0.0.0,::
数据库默认不对外开放端口:为了安全,服务器上的 MongoDB、MySQL 等数据库,通常只监听本地回环地址(127.0.0.1),拒绝外部直接访问,本地服务无法通过公网 IP + 数据库端口连接。
生产环境的数据库应该只监听本地,不暴露到公网!
可是我们本地开发也需要连接,这就需要用到SSH端口转发
SSH 端口转发(SSH Tunneling) 命令
看下什么是SSH端口转发
scss
你的电脑 SSH 隧道 远程服务器
(本地) (加密连接) (114.215.200.219)
| |
| 访问 localhost:27017 |
| ────────────────────────────> |
| 通过 SSH 加密传输 |
| 转发到本地 MongoDB
| localhost:27017
| <──────────────────────────── |
| 返回数据 |
就是说本地服务 → 连接本地映射的端口 → SSH 加密通道 → 服务器 SSH 服务 → 转发到服务器本地的数据库端口,相当于通过 SSH "搭桥",让本地服务间接访问到服务器上不对外暴露的数据库。
先查询 27017 端口(MongoDB 默认端口)相关进程信息,
bash
lsof -i:27017
- lsof:List Open Files 的缩写,用于列出系统中所有打开的文件(在 Linux 中,网络连接、端口等也被视为 "文件")。
- -i:27017:-i 选项用于筛选网络相关的 "文件"(即网络连接 / 端口),:27017 指定筛选 端口号为 27017 的网络连接。
可以看到我本地mongod已经占用了27017端口, 
这样我就要停掉这个端口,如果我还要用这个端口做转发的话,不然转发的时候会报错,像这样提示Address already in use 
我先把本地占用27017的进程给停掉
bash
kill -9 914

执行如下的端口转发命令
bash
ssh -CNL 27017:127.0.0.1:27017 root@114.215.200.219
命令解释
markdown
### 1. **`ssh`**
- SSH 客户端命令
### 2. **`-C`** (Compression)
- 表示**启用数据压缩**
- 在传输过程中压缩数据以节省带宽
详细说明:
- **作用**:压缩 SSH 连接中传输的所有数据
- **优势**:在网络带宽有限或延迟高的情况下提升速度
- **适用**:特别适合传输文本数据(如数据库查询结果)
### 3. **`-N`** (No command)
- 表示**不执行远程命令**
- 只做端口转发,不打开远程 shell
详细说明:
- **作用**:登录后不显示命令行提示符
- **优势**:不占用远程 shell 会话,更加轻量
- **效果**:终端光标停留,专注于端口转发功能
### 4. **`-L`** (Local Port Forwarding)
- 表示**本地端口转发**
- 将本地端口映射到远程服务器的端口
### 5. **`27017:127.0.0.1:27017`**
这是转发规则,格式为:`本地端口:目标主机:目标端口`
27017 : 127.0.0.1 : 27017
↓ ↓ ↓
本地端口 目标主机 目标端口
详细说明:
- **第一个 27017**:你本地电脑的端口
- **127.0.0.1**:从**远程服务器**的角度看,目标主机是它自己(localhost)
- **第二个 27017**:远程服务器上的 MongoDB 端口
### 6. **`root@114.215.200.219`**
- 用户名:`root`
- 远程服务器 IP:`114.215.200.219`
以 root 用户连接到 114.215.200.219 服务器,启用数据压缩(-C),不执行远程命令(-N),建立本地端口转发(-L),将本地 27017 端口映射到远程服务器的 127.0.0.1:27017
执行后会提示我们输入密码,root@114.215.200.219, 服务器root用户对应的密码,密码输入完后,该终端窗口会卡在那里(这代表隧道保持打开)。

新开一个终端执行:
css
lsof -i:27017
看到是SSH占用了ssh 占用了 27017,说明隧道建立成功。

在express服务里配置.env MONGODB_URI
配置.env
bash
MONGODB_URI=mongodb://admin:替换自己的密码@127.0.0.1:27017/admin?authSource=admin
上面代码解释如下
markdown
## 连接字符串结构
mongodb:// admin : 密码 @ 127.0.0.1 : 27017 / admin ? authSource=admin
↓ ↓ ↓ ↓ ↓ ↓ ↓
协议 用户名 密码 服务器地址 端口 默认数据库 认证数据库
// 连接后
admin> ← 直接在 admin 数据库中
### 6. **`?authSource=admin`** (认证数据库)
- **指定去哪个数据库验证用户身份**
- 这里指定在 `admin` 数据库中查找用户并验证密码
连接到:127.0.0.1:27017 的 MongoDB
默认数据库:admin(连接后工作的数据库)
认证方式:使用存储在 admin 数据库中的 admin 用户进行身份验证

如果没有建立SSH端口转发,就会提示如下,连接错误,拒绝连接

还有一点要说的是,如果咱们关掉SSH连接终端窗口,就会导致本地连接错误,所以本地连接ECS数据库,需要保持SSH隧道连接