第2章:Docker 快速搭建与 Compass 可视化入门
2026/7/16 16:53:45 网站建设 项目流程

1. 项目背景

业务场景:本地生活电商的技术负责人决定用 MongoDB 替代 MySQL。消息一出,全员懵圈——开发说"我本机装不上 MongoDB",测试说"每次重新部署环境都要半小时",运维说"生产集群我们用 Docker,但本地开发怎么跟生产对齐?"更麻烦的是,不同的开发人员用 macOS、Windows、Linux,安装 MongoDB 的方式千差万别,导致"我电脑上能跑"成了每日口头禅,联调的时候经常因为版本、配置不一致而翻车。

痛点:没有标准化的本地实验环境,会给团队带来以下连锁问题:版本不统一,8.0 的新特性在旧版本上报语法错误;端口和账号密码各配各的,配置文件散落在各人电脑上;数据初始化和清理没有自动化脚本,每次手动执行容易遗漏或出错;连接报错时缺少统一的排查思路,比如认证库配错、网络不通、驱动版本不兼容等。最终结果是:同样的代码,张三能用李四不能,排查半天发现李四连的是他三周前忘记关闭的测试容器。

2. 项目设计

小胖(把键盘往前一推):大师,我 C 盘 Program Files 里已经装了 3 个版本的 MongoDB 了!每次重启电脑服务就起不来,注册表也有残留。能不能换一种不用"安装"的方式?

大师:当然可以,而且业内普遍这么干——用 Docker。你把它想象成"集装箱",把 MongoDB 和它的依赖全部打包好,不管在 Windows、Mac 还是 Linux 上,拿过来就能直接用。

小胖:集装箱?这不就跟外卖打包盒一样吗——食物(数据库)和环境(筷子、纸巾)全装好,拆开就能吃。

大师:这个比喻精准。Docker 的镜像(image)就是你点的菜品,容器(container)就是打包盒。你只需要一个命令,就能在任何有 Docker 的机器上,吃到完全一样的"MongoDB 套餐"。

技术映射:Docker 通过容器化技术将应用和依赖打包,实现"一次构建,到处运行"。MongoDB 官方维护着覆盖多个版本的 Docker 镜像,在 Docker Hub 上搜mongo即可找到。

小白(放下手中的技术博客):那 Docker Compose 又是什么?我看到很多项目用docker-compose.yml来管理多个服务。

大师:好问题。Docker 只管单个容器,但我们的业务往往需要多个服务协作——比如 MongoDB 加个 Redis 缓存、加个应用服务器。Compose 就是用一个 YAML 文件描述所有服务的关系、网络、数据卷,一条命令全部启动。

小胖:等等,数据卷是什么?容器一删数据不就没了?

大师:这就是关键。容器本身是无状态的——删了容器,里面的数据确实没了。但我们可以把宿主机的某个目录"挂载"到容器里,数据的实际存储位置在宿主机上。这就像你在一楼的储物柜(宿主机目录)放东西,二楼的住客(容器)通过一个管道(挂载)来取用。储物柜不拆,东西就不会丢。

技术映射:Docker Volume 是数据持久化的核心机制。MongoDB 的dbPath目录必须挂载到宿主机,否则容器重建后数据丢失。

小胖:那 Compass 又是干啥的?跟 phpMyAdmin 一样吗?

大师:对,Compass 就是 MongoDB 官方的图形化管理工具。你可以用鼠标点点点来浏览数据、建索引、跑聚合,不用每次都敲命令。对于刚接触 MongoDB 的同学来说,Compass 能把数据"可视化",降低学习曲线。

小白:但我看很多人用 VS Code 的 MongoDB 插件,和 Compass 怎么选?

大师:互补关系。VS Code 插件适合在写代码时快速查看数据,不离开编辑器;Compass 适合做数据分析、索引优化、模式校验,功能更完整。日常开发我建议两个都装上——“轻活儿用 VS Code 插件,重活儿开 Compass”。

小胖:那 URI 连接串呢?我见过各种奇怪的格式——mongodb://mongodb+srv://,还有authSourcereplicaSet参数,搞得我眼花缭乱。

大师:握手式讲解来了。MongoDB 的连接串叫 Connection String URI,所有客户端(Driver、mongosh、Compass)都用它来建立连接。标准格式:

mongodb://[用户名:密码@]主机1[:端口1][,主机2[:端口2]]/[数据库][?选项]

小白:那mongodb+srv://呢?

大师:DNS Seedlist 格式,通过一条 DNS SRV 记录自动发现集群中的所有节点。MongoDB Atlas(云服务)默认给的就是 srv 格式。用了 srv 你不需要写一堆 IP 和端口,MongoDB 自动从 DNS 解析出来。

技术映射:Connection String URI 是 MongoDB 连接的唯一入口。authSource指定认证库(默认 admin),replicaSet指定复制集名称,retryWrites=true启用写操作自动重试。

小胖:学会了!那我们现在能动手搭了吗?我迫不及待想看到数据了。

大师:走,从 Docker Compose 开始。

3. 项目实战

3.1 环境准备

组件版本用途
Docker Desktop24+容器运行时
Docker Composev2+(集成在 Docker Desktop 中)多容器编排
MongoDB 镜像mongo:8.0数据库服务
mongosh最新版(容器自带或本机安装)命令行客户端
MongoDB Compass最新版图形管理工具
VS Code 插件MongoDB for VS Code编辑器内数据查看

3.2 分步实现

步骤一:规划目录结构

目标:创建规范的项目目录,方便后续章节共享使用。

# 在项目根目录创建统一目录结构mkdir-pmongodb-lab/data# MongoDB 数据持久化目录mkdir-pmongodb-lab/init-scripts# 初始化脚本目录mkdir-pmongodb-lab/config# 配置文件目录
# Windows 下的等效命令New-Item-ItemType Directory-Path"mongodb-lab\data"-ForceNew-Item-ItemType Directory-Path"mongodb-lab\init-scripts"-ForceNew-Item-ItemType Directory-Path"mongodb-lab\config"-Force

步骤二:编写 docker-compose.yml

目标:创建一个可重复启动、数据持久化的单节点 MongoDB 环境。

mongodb-lab/目录下创建docker-compose.yml

version:"3.8"services:mongodb:image:mongo:8.0container_name:mongodb-labrestart:unless-stoppedports:-"27017:27017"# MongoDB 默认端口environment:MONGO_INITDB_ROOT_USERNAME:adminMONGO_INITDB_ROOT_PASSWORD:admin123# 如果不需要认证(仅本地开发),可注释掉上面两行volumes:-./data:/data/db# 数据持久化-./init-scripts:/docker-entrypoint-initdb.d:ro# 初始化脚本(只读)-./config/mongod.conf:/etc/mongod.conf:ro# 自定义配置(可选)networks:-mongo-netnetworks:mongo-net:driver:bridge

可能遇到的坑

错误现象根因解决方法
port is already allocated本机已有进程占用 27017 端口修改ports27018:27017,或者停掉占用端口的进程
chown: changing ownership of '/data/db': Permission deniedWindows 上 Docker 对 NTFS 目录权限问题在 Docker Desktop 设置中启用该目录的 File Sharing
认证失败MONGO_INITDB_ROOT_PASSWORD未生效原因是 data 目录已有旧数据,清除./data目录后重启
容器反复重启配置文件语法错误或路径不存在检查volumes挂载的宿主机路径是否存在

步骤三:启动容器并验证

# 启动(在 mongodb-lab 目录下执行)dockercompose up-d# 查看容器状态dockercomposeps# 期望输出:STATUS = Up (healthy)# 查看日志(排查问题用)dockercompose logs mongodb|Select-Object-Last20

进入 mongosh:

# 方式一:通过 docker exec 进入容器内的 mongoshdockerexec-itmongodb-lab mongosh-uadmin-padmin123--authenticationDatabaseadmin# 方式二:如果本机安装了 mongosh,直接连接mongosh"mongodb://admin:admin123@localhost:27017/?authSource=admin"

进入 mongosh 后验证:

// 查看版本db.version()// 输出示例:8.0.x// 查看所有数据库show dbs// 默认只有 admin、config、local 三个系统库// 切换到 local_life 库并插入测试数据use local_life db.test.insertOne({msg:"Hello MongoDB 8.0!"})db.test.find()

步骤四:连接 Compass

  1. 打开 MongoDB Compass,在连接串输入框填入:
mongodb://admin:admin123@localhost:27017/?authSource=admin
  1. 点击 “Connect”(连接)
  2. 左侧数据库列表展开local_life→ 点击test集合
  3. 在数据视图区查看刚才插入的文档

Compass 常用功能速览

功能位置用途
浏览数据DATABASES → 选库 → 选集合表格化查看文档,支持 JSON 编辑
创建索引集合页 → Indexes 标签可视化建索引,查看索引大小和使用情况
执行聚合集合页 → Aggregations 标签拖拽式构建聚合管道,实时预览
Schema 分析集合页 → Schema 标签自动分析字段类型分布,发现脏数据
Explain 计划输入查询条件后 → Explain 按钮可视化查看执行计划和性能指标

步骤五:编写初始化脚本

目标:让容器首次启动时自动创建 database、collection 和样例数据。

创建mongodb-lab/init-scripts/01-init-data.js

// 该脚本在容器首次启动且 data 目录为空时自动执行// 注意:use 在脚本中有效,切换到目标库db=db.getSiblingDB("local_life");// 创建用户集合db.createCollection("users");db.users.insertMany([{name:"测试张三",phone:"13800000001",tags:["新用户","深圳"],registeredAt:newDate(),balance:NumberDecimal("100.00")},{name:"测试李四",phone:"13800000002",tags:["会员","广州"],registeredAt:newDate(),balance:NumberDecimal("500.00")}]);// 创建商品集合db.createCollection("products");db.products.insertMany([{name:"测试商品A",category:"数码",price:199,stock:50},{name:"测试商品B",category:"家居",price:59,stock:200}]);// 建索引db.products.createIndex({category:1});db.users.createIndex({phone:1},{unique:true});print("=== 初始化数据完成 ===");

步骤六:连接 VS Code 插件

  1. 在 VS Code 中安装插件 “MongoDB for VS Code”
  2. 左侧出现 MongoDB 图标(叶子),点击后选择 “Add Connection”
  3. 填入连接串:mongodb://admin:admin123@localhost:27017/?authSource=admin
  4. 连接成功后,可以在 VS Code 中直接:
  • 浏览 databases/collections/documents
  • 右键集合 → “Playground” 创建可执行脚本
  • 执行查询并查看结果

创建一个 MongoDB Playground 文件test-playground.mongodb.js

// VS Code MongoDB Playground// 选中代码后按 Ctrl+Shift+Enter 执行use("local_life");// 查询商品constproducts=db.products.find({price:{$lt:100}}).toArray();console.log("低价商品:",JSON.stringify(products,null,2));// 聚合统计constresult=db.products.aggregate([{$group:{_id:"$category",count:{$sum:1}}}]).toArray();console.log("类目统计:",JSON.stringify(result,null,2));

3.3 完整代码清单

文件用途
mongodb-lab/docker-compose.yml单节点 MongoDB 启动配置
mongodb-lab/init-scripts/01-init-data.js首次初始化自动建库和数据
mongodb-lab/config/mongod.confMongoDB 服务端配置(可选)

3.4 测试验证

# 1. 验证容器运行dockercompose-fmongodb-lab/docker-compose.ymlps# 期望 STATUS = Up# 2. 验证数据持久化:重启容器后数据仍在dockercompose-fmongodb-lab/docker-compose.yml restart mongodbdockerexec-itmongodb-lab mongosh-uadmin-padmin123--eval"db.getSiblingDB('local_life').users.countDocuments()"# 期望输出:2# 3. 销毁并重新创建,验证初始化脚本dockercompose-fmongodb-lab/docker-compose.yml down-v# -v 同时删除数据卷Remove-Item-Recurse-Forcemongodb-lab\data\*# 清空数据目录dockercompose-fmongodb-lab/docker-compose.yml up-d# 等待 10 秒后验证dockerexec-itmongodb-lab mongosh-uadmin-padmin123--eval"db.getSiblingDB('local_life').users.find().toArray()"# 期望输出:包含 测试张三、测试李四# 4. 验证 Compass 连接(用 GUI 操作,此处仅描述预期)# Compass 中应能看到 local_life 库及 users、products 集合

4. 项目总结

4.1 Docker 部署 vs 传统安装 vs Atlas 云服务

维度Docker Compose(本地)原生安装MongoDB Atlas(云)
部署速度3 分钟30 分钟(含环境配置)5 分钟(UI 创建集群)
环境一致性镜像统一,全平台一致各操作系统体验不同云端统一
数据持久化需手动配置 Volume默认持久自动持久
升级难度改镜像 tag 重启下载安装包,手动迁移云端一键升级
离线使用支持支持不支持
适用场景本地开发、测试、CI个人长期实例生产环境首选
成本免费免费(硬件自备)按量付费

4.2 适用场景

Docker Compose 部署适用

  1. 本地开发和调试:秒级启动/销毁,环境隔离。
  2. 团队标准化:docker-compose.yml 入 Git 仓库,全员环境一致。
  3. 持续集成(CI):GitHub Actions / Jenkins 中快速起 MongoDB 跑测试。
  4. 学习和实验:随心所欲折腾,不行就down -v重来。
  5. 多服务联调:和 Redis、Kafka、应用服务一起编排启动。

不适用场景

  1. 生产环境(虽然也能用,但推荐 Atlas 或手动部署做调优)。
  2. 超大规模集群(Kubernetes + Operator 更合适,见第 30 章)。

4.3 注意事项

注意事项说明
Windows 路径挂载Docker Desktop 需先在 Settings → Resources → File Sharing 中加入项目目录
默认无认证MONGO_INITDB_ROOT_*变量仅在首次启动且 data 目录为空时生效,已有数据后修改密码需用db.updateUser()
init-scripts执行时机脚本只在 data 目录首次初始化时执行,后续重启不会重复执行
端口映射生产环境建议不对外暴露 27017,仅通过内部网络访问
WSL2 资源限制Windows 上 Docker Desktop 使用 WSL2 引擎,默认内存上限为系统内存的 50%,可在.wslconfig中调大

4.4 常见踩坑经验

故障案例一:认证库配错导致连接失败

某开发在docker-compose.yml中设置了MONGO_INITDB_ROOT_USERNAMEMONGO_INITDB_ROOT_PASSWORD,但连接串中忘写authSource=admin,一直报 “Authentication failed”。根因:root 用户的认证库是 admin,如果连接串未指定 authSource,Driver 默认使用连接的数据库做认证。解决:连接串末尾加上?authSource=admin

故障案例二:数据目录残留导致密码不生效

测试同学想重置密码,修改了 docker-compose.yml 后执行docker compose down -v && docker compose up -d,但发现新密码无效。根因:他忘了-v参数只删除 Docker 创建的匿名卷,显式挂载的宿主机目录./data不会被删除。解决:手动Remove-Item -Recurse -Force mongodb-lab\data\*清空数据目录。

故障案例三:ARM vs AMD64 镜像兼容问题

某 M1 Mac 开发使用mongo:8.0镜像正常,但推送到 x86 CI 服务器后报 “exec /usr/local/bin/docker-entrypoint.sh: exec format error”。根因:他在 M1 上构建的镜像默认是 ARM64 架构,无法在 x86 上运行。解决:CI 服务器上直接 pull 官方多架构镜像(Docker Hub 的 mongo 镜像支持 amd64 和 arm64),无需本地构建。

4.5 思考题

  1. 如果要在同一个 docker-compose.yml 中同时启动 MongoDB 和 Spring Boot 应用,它们之间如何通信?网络需要怎么配置?
  2. 初始化脚本中创建了一个phone的唯一索引,如果某个文档没有phone字段,唯一索引会如何表现?这和 MySQL 的唯一键约束有什么不同?

(答案将在第 3 章末尾揭晓)

上一章思考题答案

  1. 如果在_id字段上创建索引,MongoDB 会报错或忽略,因为每个集合的_id字段默认就有唯一索引(名为_id_),这个索引无法删除、无法通过createIndex同名创建。所以不需要手动建。

  2. MongoDB 的嵌套文档存储在一块连续的 BSON 数据中,访问第 99 层字段不需要"跨表查找",但需要遍历整个 BSON 结构找到目标字段路径——深度越深,解析开销越大。RDBMS 的 JOIN 则需要在不同表之间匹配数据,存在磁盘 I/O 和内存开销。两者在"关联数据查找"上本质不同:MongoDB 是"在同一个文件里往下翻",MySQL 是"在多个文件之间往返跳转"。

延伸阅读与资源

python入门:Rquests从菜鸟脚本到企业级SDK的网络实战圣经
Milvus向量数据库实战修炼:从 0 到 1精通向量检索与生产落地
后端工程师的 AI 转型第一课:Ollama 与私有化大模型实战
10倍开发者的 Dify 魔法书:从零构建全栈 AI 应用
后端工程师转型AI第一课-Ollama 与私有化大模型实战

大型语言模型(LLM) vLLM 高性能推理落地实战

Agent开发之LlamaIndex 实战修炼与源码进阶

大语言模型Transformers 实战修炼与源码剖析

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询