第2章:Docker 快速搭建与 Compass 可视化入门

发布时间:2026/7/16 16:54:07

第2章:Docker 快速搭建与 Compass 可视化入门 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://、mongodbsrv://还有authSource、replicaSet参数搞得我眼花缭乱。大师握手式讲解来了。MongoDB 的连接串叫 Connection String URI所有客户端Driver、mongosh、Compass都用它来建立连接。标准格式mongodb://[用户名:密码]主机1[:端口1][,主机2[:端口2]]/[数据库][?选项]小白那mongodbsrv://呢大师DNS Seedlist 格式通过一条 DNS SRV 记录自动发现集群中的所有节点。MongoDB Atlas云服务默认给的就是 srv 格式。用了 srv 你不需要写一堆 IP 和端口MongoDB 自动从 DNS 解析出来。技术映射Connection String URI 是 MongoDB 连接的唯一入口。authSource指定认证库默认 adminreplicaSet指定复制集名称retryWritestrue启用写操作自动重试。小胖学会了那我们现在能动手搭了吗我迫不及待想看到数据了。大师走从 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-Pathmongodb-lab\data-ForceNew-Item-ItemType Directory-Pathmongodb-lab\init-scripts-ForceNew-Item-ItemType Directory-Pathmongodb-lab\config-Force步骤二编写 docker-compose.yml目标创建一个可重复启动、数据持久化的单节点 MongoDB 环境。在mongodb-lab/目录下创建docker-compose.ymlversion:3.8services: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 端口修改ports为27018: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直接连接mongoshmongodb://admin:admin123localhost:27017/?authSourceadmin进入 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打开 MongoDB Compass在连接串输入框填入mongodb://admin:admin123localhost:27017/?authSourceadmin点击 “Connect”连接左侧数据库列表展开local_life→ 点击test集合在数据视图区查看刚才插入的文档Compass 常用功能速览功能位置用途浏览数据DATABASES → 选库 → 选集合表格化查看文档支持 JSON 编辑创建索引集合页 → Indexes 标签可视化建索引查看索引大小和使用情况执行聚合集合页 → Aggregations 标签拖拽式构建聚合管道实时预览Schema 分析集合页 → Schema 标签自动分析字段类型分布发现脏数据Explain 计划输入查询条件后 → Explain 按钮可视化查看执行计划和性能指标步骤五编写初始化脚本目标让容器首次启动时自动创建 database、collection 和样例数据。创建mongodb-lab/init-scripts/01-init-data.js// 该脚本在容器首次启动且 data 目录为空时自动执行// 注意use 在脚本中有效切换到目标库dbdb.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 插件在 VS Code 中安装插件 “MongoDB for VS Code”左侧出现 MongoDB 图标叶子点击后选择 “Add Connection”填入连接串mongodb://admin:admin123localhost:27017/?authSourceadmin连接成功后可以在 VS Code 中直接浏览 databases/collections/documents右键集合 → “Playground” 创建可执行脚本执行查询并查看结果创建一个 MongoDB Playground 文件test-playground.mongodb.js// VS Code MongoDB Playground// 选中代码后按 CtrlShiftEnter 执行use(local_life);// 查询商品constproductsdb.products.find({price:{$lt:100}}).toArray();console.log(低价商品,JSON.stringify(products,null,2));// 聚合统计constresultdb.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--evaldb.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--evaldb.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 部署适用本地开发和调试秒级启动/销毁环境隔离。团队标准化docker-compose.yml 入 Git 仓库全员环境一致。持续集成CIGitHub Actions / Jenkins 中快速起 MongoDB 跑测试。学习和实验随心所欲折腾不行就down -v重来。多服务联调和 Redis、Kafka、应用服务一起编排启动。不适用场景生产环境虽然也能用但推荐 Atlas 或手动部署做调优。超大规模集群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_USERNAME和MONGO_INITDB_ROOT_PASSWORD但连接串中忘写authSourceadmin一直报 “Authentication failed”。根因root 用户的认证库是 admin如果连接串未指定 authSourceDriver 默认使用连接的数据库做认证。解决连接串末尾加上?authSourceadmin。故障案例二数据目录残留导致密码不生效测试同学想重置密码修改了 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 思考题如果要在同一个 docker-compose.yml 中同时启动 MongoDB 和 Spring Boot 应用它们之间如何通信网络需要怎么配置初始化脚本中创建了一个phone的唯一索引如果某个文档没有phone字段唯一索引会如何表现这和 MySQL 的唯一键约束有什么不同答案将在第 3 章末尾揭晓上一章思考题答案如果在_id字段上创建索引MongoDB 会报错或忽略因为每个集合的_id字段默认就有唯一索引名为_id_这个索引无法删除、无法通过createIndex同名创建。所以不需要手动建。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 实战修炼与源码剖析

相关新闻