分类课程智能体AI
文章
订阅
分类课程AI导师
文章
价格
课程进度
2 / 17
上一节MongoDB 与纸舟书店下一节BSON、集合与纸舟书店种子数据
自在学

© 2025 - 2026 株洲市自在学教育科技有限公司 版权所有

公网安备湘公网安备43020302000292号 | 湘ICP备2025148919号-1

关于我们隐私政策使用条款

© 2025 - 2026 株洲市自在学教育科技有限公司 版权所有

公网安备湘公网安备43020302000292号湘ICP备2025148919号-1

编程MongoDB 纸舟书店完整课程启动 MongoDB 8.0

启动 MongoDB 8.0

这一节会把纸舟书店的数据库服务真正启动起来。我们采用 Docker 官方 mongo:8.0 镜像,并在容器内使用 mongosh。这样做有三个目的:明确 MongoDB 的主版本边界、让启动过程可以重复、让后续清理有清楚的对象。

课程会创建三个有名字的资源:网络 paperboat-net、数据卷 paperboat-mongo-data、容器 paperboat-mongo。后面的命令都沿用这些名称,请不要随意改名,否则连接命令和副本集配置也要一起调整。

本节为了先理解数据库行为,只把端口绑定到 127.0.0.1,并且尚未启用身份认证。不要把这个容器暴露到公网或共享网络。用户、角色、最小权限和 TLS 会在安全部分单独配置。


选择课程运行方式

MongoDB 可以通过多种方式运行。课程选择容器,并不意味着原生安装不可取;它只是让数据库版本、进程参数和数据目录更容易统一。

方式适合什么情况需要注意什么
Docker 官方镜像学习、功能验证、可重复实验先理解镜像、容器、端口和数据卷的区别
MongoDB Community Server 原生安装需要研究操作系统服务、包管理和目录权限不同系统的安装命令与服务管理方式不同
MongoDB Atlas希望使用托管集群需要账号与网络访问,部分界面和套餐会变化

本课程完整实践走第一条路线。若你明确要学习原生服务管理,请从 MongoDB 8.0 的 Community Edition 安装入口 选择对应系统,并另外安装 mongosh。不要把不同版本博客中的仓库地址、包名和服务命令拼在一起。

Docker 的官方安装入口如下:

  • macOS 安装 Docker Desktop
  • Windows 安装 Docker Desktop
  • Linux 安装 Docker Desktop

Docker Desktop 的系统要求和许可条款会更新,以链接中的当前说明为准。安装完成后启动 Docker 服务,再继续下面的体检。

课程中的多行命令统一使用 Bash 兼容语法。macOS 可以使用系统自带的终端,Linux 可以使用 Bash,Windows 建议在启用 Docker Desktop WSL 2 集成后使用 WSL 终端。不要把反斜线续行命令原样粘贴进不兼容的命令解释器。


检查课程需要的命令工具

知识点

前半程主要使用 docker、mongosh 和 curl,副本集与分片章节还会使用 docker compose。mongosh 已包含在课程使用的 MongoDB 镜像中,不要求额外安装;curl 用来向 Node.js API 发送请求。

这里先检查命令是否存在,不把某个补丁版本写成固定答案。只要 Docker 客户端与服务端能通信、Compose 子命令可用、curl 能显示版本信息,就具备继续学习的工具条件。

实操

shell
docker version --format 'client={{.Client.Version}} server={{.Server.Version}}'
docker compose version
curl --version

结果展示

输出会因安装时间和操作系统而变化,结构应类似:

text
client=<Docker 客户端版本> server=<Docker 服务端版本>
Docker Compose version v<版本号>
curl <版本号> ...

如果 docker compose 不存在,先按 Docker 官方说明补齐 Compose 插件;如果 curl 不存在,先使用系统包管理器安装。不要等到 API 章节才发现基础命令缺失。


确认 Docker 客户端与服务端可用

知识点

docker 命令是客户端,它需要连接到正在运行的 Docker 服务端。只看到客户端版本还不够;如果服务端没有启动,后续 pull 和 run 都会失败。docker version 同时返回两端信息,因此适合做第一道体检。

实操

打开终端,执行:

shell
docker version --format 'client={{.Client.Version}} server={{.Server.Version}}'

结果展示

正常结果会同时出现两个版本号,例如:

text
client=<Docker 客户端版本> server=<Docker 服务端版本>

尖括号中的内容取决于你安装的 Docker 版本,不是课程要求固定的值。真正的检查条件是 client= 和 server= 后面都有值,并且命令正常退出。

如果看到 Cannot connect to the Docker daemon,先启动 Docker Desktop 或 Docker Engine,再重新执行。此时不要急着运行 MongoDB 命令,因为数据库容器还没有运行基础。


获取 MongoDB 8.0 官方镜像

知识点

镜像是创建容器的只读模板,容器是镜像的一次运行实例。mongo:8.0 中的 8.0 是主次版本标签:它保持在 8.0 系列,但维护者可以把标签更新到新的 8.0 补丁版本。这样能获得同一主版本的修复,也意味着补丁号和镜像摘要可能随时间变化。

Docker Hub 的 mongo 官方镜像页面说明了启动、初始化脚本、认证变量和数据卷等约定。课程使用这个官方镜像,不使用名称相近的第三方镜像。

实操

拉取 8.0 系列镜像,并查看它当前对应的仓库摘要:

shell
docker pull mongo:8.0
docker image inspect mongo:8.0 --format '{{json .RepoDigests}}'

结果展示

拉取时会看到分层下载信息,最后类似:

text
8.0: Pulling from library/mongo
Digest: sha256:<镜像摘要>
Status: Downloaded newer image for mongo:8.0

如果镜像已经存在,状态可能是 Image is up to date。第二条命令会输出包含 mongo@sha256:... 的数组。摘要由当前镜像内容决定,发生补丁更新后变化是正常现象。


创建网络和数据卷

知识点

容器本身可以删除重建,书店数据却需要跨重启保留。命名数据卷 paperboat-mongo-data 用于保存 /data/db;命名网络 paperboat-net 让后续应用容器可以通过容器名找到数据库。

这两个资源都有明确名称,因此可以检查、复用并在课程结束时精确删除,不会和其他项目混在一起。

实操

依次创建网络与数据卷:

shell
docker network create paperboat-net
docker volume create paperboat-mongo-data

结果展示

第一条命令返回网络 ID,它是一串动态生成的十六进制字符;第二条命令返回固定的数据卷名称:

text
<动态生成的网络 ID>
paperboat-mongo-data

如果提示同名网络或数据卷已经存在,说明你以前执行过这一步。可以先运行 docker network inspect paperboat-net 和 docker volume inspect paperboat-mongo-data 确认它们确实属于这门课程,然后继续使用。


启动 MongoDB 容器

知识点

我们从一开始就为 mongod 加上 --replSet rs0。即使当前只有一个节点,它也会按副本集模式运行,为后面的事务、复制和故障转移课程留下连续路径。--bind_ip_all 让 MongoDB 在容器网络内监听所有接口,而端口映射左侧的 127.0.0.1 限制了容器所在设备上的访问入口。

命令中的 -d 表示后台运行,--name 和 --hostname 固定容器身份,-v 把命名卷挂载到 MongoDB 的数据目录。

实操

执行下面这条完整命令:

shell
docker run -d \
  --name paperboat-mongo \
  --hostname paperboat-mongo \
  --network paperboat-net \
  -p 127.0.0.1:27017:27017 \
  -v paperboat-mongo-data:/data/db \
  mongo:8.0 \
  --replSet rs0 --bind_ip_all

结果展示

命令成功后会打印容器 ID:

text
<动态生成的容器 ID>

容器 ID 每次创建都会不同,不能拿它和示例逐字符比较。接着查看容器表:

知识点

docker ps 展示正在运行的容器。我们用名称过滤,避免其他项目的容器干扰判断。STATUS 中的秒数会持续变化,PORTS 则应该表明 127.0.0.1:27017 已映射到容器的 27017。

实操

shell
docker ps \
  --filter 'name=^/paperboat-mongo$' \
  --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}'

结果展示

text
NAMES              IMAGE       STATUS          PORTS
paperboat-mongo    mongo:8.0   Up <运行时长>   127.0.0.1:27017->27017/tcp

Up <运行时长> 是动态值。关键是只有目标容器这一行,并且状态以 Up 开头。


等待数据库接受连接

知识点

容器进入 Up 状态只说明主进程已经启动,不一定说明数据库已完成初始化。最可靠的检查不是猜等待几秒,而是实际发送 ping。docker exec 会在正在运行的容器中执行 mongosh,--quiet 减少与结果无关的启动信息。

实操

执行:

shell
docker exec paperboat-mongo \
  mongosh --quiet --eval 'db.adminCommand({ ping: 1 })'

结果展示

数据库就绪时返回:

text
{ ok: 1 }

如果第一次执行时连接被拒绝,说明初始化尚未完成。稍等片刻后原样重试;不要修改端口或容器名来“碰运气”。


初始化单节点副本集

知识点

--replSet rs0 只告诉 mongod 以副本集模式启动,还没有写入成员配置。rs.initiate() 会创建名为 rs0 的副本集,并把当前容器登记为成员。成员地址使用 paperboat-mongo:27017,因为这个名称能在 paperboat-net 中解析。

初始化只需要执行一次。副本集配置保存在数据卷中,停止并重新启动容器后仍然存在。

实操

shell
docker exec paperboat-mongo mongosh --quiet --eval '
rs.initiate({
  _id: "rs0",
  members: [
    { _id: 0, host: "paperboat-mongo:27017" }
  ]
})
'

结果展示

首次初始化成功时,核心结果是:

text
{ ok: 1 }

随后节点需要完成一次选举。检查它是否成为可写主节点:

知识点

db.hello() 返回连接所见的拓扑信息。单节点副本集中,我们关心 setName 是否为 rs0,以及 isWritablePrimary 是否为 true。第一次查询若仍为 false,等待短暂选举完成后重试即可。

实操

shell
docker exec paperboat-mongo mongosh --quiet --eval '
const hello = db.hello();
print(EJSON.stringify({
  setName: hello.setName,
  isWritablePrimary: hello.isWritablePrimary
}));
'

结果展示

json
{"setName":"rs0","isWritablePrimary":true}

这说明当前部署已经是名为 rs0 的副本集,并且唯一成员可以接受写入。若重复执行 rs.initiate(),MongoDB 会提示副本集已经初始化;那不是数据损坏,而是说明初始化步骤不应重复。


完成版本体检

知识点

课程要求的是 MongoDB 8.0 主版本,而不是某个永远固定的补丁号。我们同时查看服务端和 shell 版本:mongod --version 说明数据库版本,mongosh --version 说明交互客户端版本。两者是独立发布的软件,版本号不需要相同。

实操

shell
docker exec paperboat-mongo mongod --version
docker exec paperboat-mongo mongosh --version
docker exec paperboat-mongo mongosh --quiet --eval '
print(EJSON.stringify({
  serverVersion: db.version(),
  ping: db.adminCommand({ ping: 1 }).ok
}));
'

结果展示

一次实际运行中,mongo:8.0 解析到了 MongoDB 8.0.26,镜像内 mongosh 为 2.9.2,最终体检摘要为:

json
{"serverVersion":"8.0.26","ping":1}

你执行时补丁号与 mongosh 版本可能更高。验收条件是 serverVersion 以 8.0. 开头,并且 ping 为 1。这比背诵示例补丁号更可靠。


练习停止与重新启动

知识点

停止容器会结束 MongoDB 进程,但不会删除容器和命名数据卷。再次启动同一个容器后,副本集配置仍在。这个区别很重要:stop 是暂停服务,rm 是删除容器,volume rm 才会删除课程数据。

实操

shell
docker stop paperboat-mongo
docker start paperboat-mongo
docker exec paperboat-mongo \
  mongosh --quiet --eval 'db.adminCommand({ ping: 1 })'

结果展示

前两条命令分别返回容器名,最后重新得到 ok: 1:

text
paperboat-mongo
paperboat-mongo
{ ok: 1 }

启动后若数据库还在恢复,第一次 ping 可能暂时连接失败,稍后原样重试即可。数据卷没有被删除,因此不需要再次执行 rs.initiate()。


检查你的理解

1
为什么课程使用 `mongo:8.0`,却不要求输出必须等于某个固定补丁版本?

到这里,纸舟书店已经有了可连接的 MongoDB 8.0 服务:容器正在运行,数据写入命名卷,副本集 rs0 已可写,ping 返回 1。下一节会进入 bookstore 数据库并导入固定种子数据。

  • 选择课程运行方式
  • 检查课程需要的命令工具
    • 知识点
    • 实操
    • 结果展示
  • 确认 Docker 客户端与服务端可用
    • 知识点
    • 实操
    • 结果展示
  • 获取 MongoDB 8.0 官方镜像
    • 知识点
    • 实操
    • 结果展示
  • 创建网络和数据卷
    • 知识点
    • 实操
    • 结果展示
  • 启动 MongoDB 容器
    • 知识点
    • 实操
    • 结果展示
    • 知识点
    • 实操
    • 结果展示
  • 等待数据库接受连接
    • 知识点
    • 实操
    • 结果展示
  • 初始化单节点副本集
    • 知识点
    • 实操
    • 结果展示
    • 知识点
    • 实操
    • 结果展示
  • 完成版本体检
    • 知识点
    • 实操
    • 结果展示
  • 练习停止与重新启动
    • 知识点
    • 实操
    • 结果展示
  • 检查你的理解

目录

  • 选择课程运行方式
  • 检查课程需要的命令工具
    • 知识点
    • 实操
    • 结果展示
  • 确认 Docker 客户端与服务端可用
    • 知识点
    • 实操
    • 结果展示
  • 获取 MongoDB 8.0 官方镜像
    • 知识点
    • 实操
    • 结果展示
  • 创建网络和数据卷
    • 知识点
    • 实操
    • 结果展示
  • 启动 MongoDB 容器
    • 知识点
    • 实操
    • 结果展示
    • 知识点
    • 实操
    • 结果展示
  • 等待数据库接受连接
    • 知识点
    • 实操
    • 结果展示
  • 初始化单节点副本集
    • 知识点
    • 实操
    • 结果展示
    • 知识点
    • 实操
    • 结果展示
  • 完成版本体检
    • 知识点
    • 实操
    • 结果展示
  • 练习停止与重新启动
    • 知识点
    • 实操
    • 结果展示
  • 检查你的理解