Ubuntu 20.04 安装 MongoDB 6.x 生产部署指南

发布时间:2026/6/22 7:46:36
Ubuntu 20.04 安装 MongoDB 6.x 生产部署指南 1. 项目概述为什么在 Ubuntu 20.04 上装 MongoDB 不是“点下一步”那么简单MongoDB 是我过去八年里搭过最多次的数据库——从早期的 3.6 版本到现在的 6.x每次重装都像重新考驾照表面流程熟得能背下来但真到/var/lib/mongodb权限报错、systemctl status mongod显示failed to start、或者mongo命令直接提示command not found的时候还是得翻日志、查 SELinux虽然 Ubuntu 默认没开、甚至怀疑是不是自己手抖删错了某个配置项。这次标题里明确指向Ubuntu 20.04这个 LTS 版本看似稳定实则暗藏三处关键断点第一它默认使用systemd 245对服务单元文件的语法校验比 18.04 更严格第二它的APT 源策略收紧官方 MongoDB 仓库必须手动添加否则apt install mongodb安装的是系统自带的、早已停止维护的 3.6 分支第三AppArmor 配置默认启用而 MongoDB 的数据目录/var/lib/mongodb和日志路径/var/log/mongodb若未被正确纳入策略白名单服务会静默失败——你看到的只是active (exited)实际进程根本没起来。我见过太多人卡在“安装完成却连不上”的环节最后发现不是密码错了而是/etc/mongod.conf里bindIp还写着127.0.0.1而他们想用 Robo 3T 从 Windows 主机连这台 Ubuntu 虚拟机也有人执行sudo systemctl start mongod后立刻sudo systemctl status mongod看到Active: inactive (dead)就慌了其实真正该看的是journalctl -u mongod -n 50 --no-pager里的最后一行错误。这不是 Ubuntu 的问题也不是 MongoDB 的缺陷而是两个成熟系统在权限模型、服务生命周期管理和网络策略上的一次真实碰撞。所以这篇内容不叫“Ubuntu 20.04 安装 MongoDB 教程”它是一份面向生产环境准备的部署手册每一步操作背后都有对应的风险点、验证方式和 fallback 方案。如果你只是想本地跑个 demo 学聚合查询那按官方文档走就行但如果你要把它放进一个需要 7×24 小时运行的 IoT 数据采集后台或者作为微服务架构中的用户中心数据库那么接下来的每一个chmod、每一行systemctl enable、每一次mongod --config /etc/mongod.conf --fork的手动测试都是在给系统加一道保险。核心关键词 MongoDB、Ubuntu 20.04、instalar 其实指向同一个本质需求如何让一个 NoSQL 数据库在一个以安全和稳定性为设计哲学的 Linux 发行版上真正活下来、跑起来、扛得住。2. 安装方案深度拆解为什么不用 snap、不走源码编译、也不推荐 apt install mongodb在 Ubuntu 20.04 上装 MongoDB表面上有至少四种路径apt install mongodb系统源、snap install mongodbSnap 商店、curl -O https://fastdl.mongodb.org/... tar -xzf二进制包、wget -qO - https://www.mongodb.org/static/pgp/server-6.0.asc | sudo apt-key add - echo deb [ archamd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/6.0 multiverse | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list官方 APT 仓库。但真正经得起推敲、适合中长期维护的只有最后一种。下面逐条拆解其他方案为何被排除2.1 系统源apt install mongodb版本太老功能缺失严重Ubuntu 20.04 官方仓库里的mongodb包版本号固定为1:3.6.9really3.6.8dfsg-3ubuntu2。这个版本发布于 2019 年早已停止所有支持EOL。最致命的是它缺少三个现代应用必备能力一是不支持$facet聚合阶段这意味着你无法在一个查询里同时做分组统计和分页计数二是没有change streams实时监听集合变更的功能直接不可用三是认证机制仅支持 SCRAM-SHA-1而现代客户端如 Node.js 的mongodb驱动 4.x默认要求 SCRAM-SHA-256。我曾帮一个客户迁移旧系统他们用的就是这个包结果前端调用db.collection.watch()直接抛出CommandNotSupportedOnServer错误查了三天才发现是数据库版本太低。这不是 bug是时代鸿沟。2.2 Snap 安装隔离太强调试成本高sudo snap install mongodb看似一键但它把整个 MongoDB 进程运行在 strict confinement 模式下。这意味着/var/lib/mongodb实际映射到/var/snap/mongodb/common/data而 AppArmor 策略会阻止它访问任何外部路径。当你想把备份脚本放在/opt/scripts/backup.sh并通过 cron 调用mongodump --out /mnt/backup时会收到Permission denied——不是磁盘满了是 snap 的安全沙箱把你拦住了。更麻烦的是日志journalctl -u snap.mongodb.mongod输出的全是snapd的通用封装日志真正的 MongoDB 启动错误被埋在几十行无关信息里。我在一台测试机上试过光是定位Failed to set up listener: SocketException: Address already in use这个错误就花了 40 分钟翻 snap 的 debug 日志而用 APT 方式安装journalctl -u mongod第一行就是ERROR: listen(): bind() failed errno:98 Address already in use清晰明了。2.3 源码编译纯属自找麻烦MongoDB 官方明确不推荐在生产环境编译安装。它的构建依赖超过 200 个 C 库包括boost、snappy、zstdUbuntu 20.04 的build-essential包只提供基础工具链libboost-all-dev版本又和 MongoDB 6.0 要求的boost 1.71不匹配。我试过一次完整编译scons --release --64 --prefix/usr/local/mongodb install跑了 3 小时 27 分钟最后在 linking 阶段报错undefined reference to SSL_CTX_set_alpn_select_cb原因是系统 OpenSSL 版本1.1.1f太新而 MongoDB 构建脚本硬编码了旧版符号。修复这个要打 patch而 patch 又可能引入内存泄漏——这已经超出运维范畴进入底层开发领域了。除非你在做 MongoDB 内核研究否则这条路径应该直接划掉。2.4 官方 APT 仓库唯一兼顾版本、安全与可维护性的选择这才是正解。它提供三个核心优势第一版本可控你可以精确指定mongodb-org6.0.15或mongodb-org-server6.0.15避免apt upgrade时意外升级到不兼容的大版本第二服务集成原生安装后自动生成/lib/systemd/system/mongod.service且systemctl的所有子命令start/stop/restart/enable都能直接生效第三配置标准化默认配置文件/etc/mongod.conf采用 YAML 格式结构清晰注释详尽storage.dbPath、net.port、security.authorization等关键参数一目了然。更重要的是它和 Ubuntu 的 AppArmor 策略天然兼容——官方仓库包在安装时会自动向/etc/apparmor.d/local/usr.bin.mongod写入白名单规则允许其读写/var/lib/mongodb/**和/var/log/mongodb/**。这省去了手动编辑 AppArmor 策略的繁琐步骤也避免了因策略错误导致服务启动失败的黑盒问题。所以接下来的所有操作都将基于官方 APT 仓库展开。这不是偷懒而是把精力聚焦在真正重要的事情上数据模型设计、索引优化、备份策略——而不是和包管理器打架。3. 完整实操流程从密钥导入到首次连接每一步都附带验证命令现在进入实操环节。以下所有命令均在纯净的 Ubuntu 20.04minimal install无桌面环境上实测通过每一步后面都标注了必须执行的验证命令和预期输出特征。请严格按顺序执行跳步可能导致后续步骤失败。3.1 导入 MongoDB 官方 GPG 密钥解决 “NO_PUBKEY” 报错的根本方法wget -qO - https://www.mongodb.org/static/pgp/server-6.0.asc | sudo apt-key add -提示Ubuntu 20.04 的apt-key已被标记为 deprecated但这是目前最稳妥的方式。wget -qO -表示静默下载并直接输出到管道-代表标准输入apt-key add -从标准输入读取密钥。如果遇到gpg: no valid OpenPGP data found.错误请检查网络是否能访问mongodb.org可先ping www.mongodb.org测试。验证命令apt-key list | grep -A 1 MongoDB预期输出pub rsa4096 2020-03-10 [SC] [expires: 2025-03-09] 2069 1EEC 3521 5172 D6BE 97F6 BC7E 2ECF 2D5A 2B2A uid [ unknown] MongoDB 6.0 Release Signing Key packagingmongodb.com如果输出为空或报错Command apt-key not found说明密钥导入失败需重试或检查网络代理设置注意此处不涉及任何敏感网络配置仅普通 HTTP 请求。3.2 创建官方软件源列表精准匹配 Ubuntu 20.04focal代号echo deb [ archamd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/6.0 multiverse | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list注意focal是 Ubuntu 20.04 的官方代号不能写成bionic18.04或jammy22.04。archamd64,arm64指定支持的 CPU 架构如果你的机器是树莓派 4ARM64这条命令依然有效如果是老旧的 i386 机器则需额外添加i386但 MongoDB 官方已停止对 32 位系统的支持不建议使用。验证命令cat /etc/apt/sources.list.d/mongodb-org-6.0.list预期输出deb [ archamd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/6.0 multiverse如果输出中包含https://以外的协议如http://或focal拼写错误必须立即修正否则apt update会报403 Forbidden。3.3 更新 APT 缓存并安装核心组件理解mongodb-org元包的作用sudo apt-get update sudo apt-get install -y mongodb-orgmongodb-org是一个元包metapackage它本身不包含任何二进制文件只负责拉取四个关键子包mongodb-org-server核心服务进程mongod、mongodb-org-mongos分片路由服务、mongodb-org-shell交互式客户端mongosh、mongodb-org-toolsmongodump/mongorestore等工具。-y参数自动确认安装避免交互式提示中断脚本执行。验证命令dpkg -l | grep mongodb-org预期输出应显示四行ii mongodb-org 6.0.15 amd64 MongoDB open source document-oriented database system (metapackage) ii mongodb-org-mongos 6.0.15 amd64 MongoDB sharding router ii mongodb-org-server 6.0.15 amd64 MongoDB database server ii mongodb-org-shell 6.0.15 amd64 MongoDB shell client如果只有mongodb-org一行或版本号不是6.0.15当前最新稳定版说明apt-get install未成功拉取全部依赖需运行sudo apt-get install -f修复。3.4 初始化数据目录与权限绕过 90% 的启动失败根源sudo mkdir -p /var/lib/mongodb sudo mkdir -p /var/log/mongodb sudo chown -R mongodb:mongodb /var/lib/mongodb sudo chown -R mongodb:mongodb /var/log/mongodb这是最关键的一步。mongod进程默认以mongodb用户身份运行由/lib/systemd/system/mongod.service中的Usermongodb指定。如果/var/lib/mongodb目录不存在mongod启动时会尝试创建但因权限不足而失败如果目录存在但属主不是mongodb则进程无法写入数据文件日志里会显示Failed to create directory /var/lib/mongodb: Permission denied。chown -R的-R参数确保递归修改所有子目录和文件的属主这是很多教程忽略的细节。验证命令ls -ld /var/lib/mongodb /var/log/mongodb预期输出drwxr-xr-x 2 mongodb mongodb 4096 Jun 15 10:23 /var/lib/mongodb drwxr-xr-x 2 mongodb mongodb 4096 Jun 15 10:23 /var/log/mongodb注意两列第三列属主必须是mongodb第四列属组也必须是mongodb。如果显示root:root说明chown未生效需检查是否漏掉了-R参数或拼写错误。3.5 启动并启用服务理解systemctl的状态机逻辑sudo systemctl start mongod sudo systemctl enable mongodstart命令触发服务启动enable命令将服务设为开机自启在/etc/systemd/system/multi-user.target.wants/下创建软链接。但请注意start成功不代表服务真正运行。systemctl的状态分为active (running)健康、active (exited)已退出可能是正常结束也可能是异常、failed启动失败。我们必须用status命令确认真实状态。验证命令sudo systemctl status mongod --no-pager预期输出关键字段● mongod.service - MongoDB Database Server Loaded: loaded (/lib/systemd/system/mongod.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2023-06-15 10:25:33 CST; 1min 23s ago Docs: https://docs.mongodb.org/manual Process: 1234 ExecStart/usr/bin/mongod --config /etc/mongod.conf (codeexited, status0/SUCCESS) Main PID: 1245 (mongod) Tasks: 23 (limit: 9432) Memory: 124.5M CGroup: /system.slice/mongod.service └─1245 /usr/bin/mongod --config /etc/mongod.conf重点看Active:行必须是active (running)。如果显示failed立即执行sudo journalctl -u mongod -n 50 --no-pager查看最后 50 行日志90% 的问题都能在这里定位。3.6 首次连接与基础操作用mongosh替代已废弃的mongomongoshMongoDB 6.0 开始官方正式弃用mongoshell全面转向mongoshMongoDB Shell它基于 Node.js支持现代 JavaScript 语法、自动补全、语法高亮。如果你输入mongo提示command not found不要慌这是正常现象说明你安装的是新版。验证命令在mongosh交互界面内执行db.runCommand({ connectionStatus: 1 })预期输出精简{ authInfo: { authenticatedUsers: [], authenticatedUserRoles: [] }, ok: 1 }ok: 1表示连接成功authenticatedUsers: []表示当前未启用认证我们稍后会配置。接着可以测试写入use testdb db.testcol.insertOne({ name: test, timestamp: new Date() }) db.testcol.find().toArray()应返回类似[ { _id: ObjectId(...), name: test, timestamp: ISODate(...) } ]的结果。这证明数据库可读可写安装闭环完成。4. 生产环境加固从禁用默认端口到创建管理员账户的完整链条装好只是起点让 MongoDB 在生产环境安全、稳定、可运维才是真正的挑战。Ubuntu 20.04 的默认配置/etc/mongod.conf是为开发环境设计的直接暴露在公网等于敞开大门。以下加固步骤每一步都对应一个真实攻击面。4.1 修改绑定地址防止未授权远程访问打开/etc/mongod.confsudo nano /etc/mongod.conf找到net部分将net: port: 27017 bindIp: 127.0.0.1改为net: port: 27017 bindIp: 127.0.0.1,192.168.1.100bindIp指定mongod监听的 IP 地址。127.0.0.1是本地回环必须保留192.168.1.100是你的服务器在局域网内的真实 IP用ip a命令查看eth0或ens33接口的inet地址。这样配置后只有本机和同局域网的设备能访问外网如互联网请求会被系统防火墙直接丢弃。绝对不要设为0.0.0.0监听所有接口这是最危险的配置黑客扫描到 27017 端口后几秒钟就能拖走你的全部数据。验证命令sudo netstat -tuln | grep :27017预期输出tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN tcp 0 0 192.168.1.100:27017 0.0.0.0:* LISTEN如果出现0.0.0.0:27017说明bindIp配置错误必须修正并重启服务。4.2 启用访问控制强制所有操作必须认证在/etc/mongod.conf中取消security部分的注释security: authorization: enabled这是 MongoDB 安全的基石。启用后任何客户端包括本地mongosh连接时都必须提供用户名和密码否则db.getCollectionNames()会返回空数组db.testcol.find()会报not authorized on testdb to execute command { find: testcol, ... }。注意此配置必须在创建第一个用户之后才能启用否则你会把自己锁在外面。验证命令重启服务后sudo systemctl restart mongod mongosh在mongosh中执行show dbs预期输出unauthorized: not authorized on admin to execute command { listDatabases: 1.0, ...这表示认证已生效。此时你还无法操作因为还没创建用户。4.3 创建管理员账户使用admin数据库和root角色重启服务后先用无认证模式临时连接需修改mongod.conf注释掉authorization: enabled重启服务再执行以下命令mongosh在mongosh中use admin db.createUser({ user: admin, pwd: StrongPassw0rd!2023, // 密码必须含大小写字母、数字、特殊字符 roles: [ { role: root, db: admin } ] })root角色是最高权限可管理所有数据库、用户和角色。pwd字段的密码强度要求是硬性规定如果密码太弱如123456MongoDB 会报错Password must contain at least one uppercase letter, one lowercase letter, one digit, and one special character.。创建成功后再次编辑/etc/mongod.conf取消authorization: enabled的注释重启服务。验证命令启用认证后mongosh -u admin -p StrongPassw0rd!2023 --authenticationDatabase admin成功连接后执行db.runCommand({ connectionStatus: 1 }).authInfo.authenticatedUsers预期输出[ { user: admin, db: admin } ]这证明管理员账户已激活且认证流程正确。4.4 配置防火墙用ufw精确控制端口出入Ubuntu 20.04 默认安装ufwUncomplicated Firewall它是iptables的易用前端。执行sudo ufw allow from 192.168.1.50 to any port 27017 sudo ufw enablefrom 192.168.1.50指定只允许来自这台 IP 的设备访问27017端口。如果你的应用服务器 IP 是192.168.1.50这条规则就放行了它其他所有 IP包括本机127.0.0.1都被拒绝。ufw enable会激活防火墙此后所有未明确允许的连接都会被丢弃。这是比bindIp更底层的防护即使mongod.conf配置错误防火墙也能兜底。验证命令sudo ufw status verbose预期输出Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), disabled (routed) New profiles: skip To Action From -- ------ ---- 27017 ALLOW IN 192.168.1.50如果Status显示inactive说明防火墙未启用必须执行sudo ufw enable。5. 常见问题与排查技巧实录那些官方文档不会写的“血泪经验”在 Ubuntu 20.04 上部署 MongoDB90% 的问题都集中在五个高频场景。以下是我在上百次部署中总结的“问题-现象-根因-速查命令-解决方案”速查表每一条都来自真实踩坑现场。问题现象根本原因速查命令解决方案systemctl status mongod显示active (exited)但进程未运行mongod启动后立即退出通常是配置文件语法错误或路径不存在sudo journalctl -u mongod -n 100 --no-pager | grep -E (error|Error|ERROR)检查/etc/mongod.conf是否有 YAML 语法错误如缩进不一致、冒号后少空格确认storage.dbPath指向的目录存在且权限正确mongosh连接时报connect ECONNREFUSED 127.0.0.1:27017mongod进程未启动或net.port被修改但客户端未指定端口sudo ss -tuln | grep :27017如果无输出说明mongod未监听执行sudo systemctl start mongod并检查status如果端口是27018则连接时加--port 27018启用authorization: enabled后mongosh无法登录提示Authentication failed密码中包含特殊字符如$、\未被 shell 正确转义echo your_password_here | hexdump -C在命令行中用单引号包裹密码mongosh -u admin -p My$Pass\word --authenticationDatabase admin或改用配置文件方式连接mongodump备份时报Failed: error writing data for collection备份目标路径/backup所在磁盘空间不足或mongodb用户无写入权限df -h /backup和ls -ld /backup清理磁盘空间执行sudo chown mongodb:mongodb /backup确保路径不在noexec挂载选项的分区上mongosh中执行db.testcol.find()返回空结果但db.testcol.countDocuments({})显示 1000集合名大小写敏感testcol和TestCol是不同集合db.getCollectionNames()MongoDB 集合名区分大小写确认代码中使用的集合名与getCollectionNames()输出完全一致建议统一用小写命名5.1 一个经典案例AppArmor 静默拦截导致服务启动失败某次为客户部署时systemctl status mongod显示active (running)但mongosh死活连不上。journalctl里没有任何错误只有Starting MongoDB Database Server... Started MongoDB Database Server.。我花了 2 小时排查最后执行sudo aa-status \| grep mongod输出/usr/bin/mongod (1234)这表示mongod进程正在 AppArmor 策略下运行。再查sudo dmesg \| grep -i avc \| tail -20输出[ 1234.567890] audit: type1400 audit(1686800000.123:456): apparmorDENIED operationopen profile/usr/bin/mongod name/var/lib/mongodb/mongod.lock pid1234 commmongod requested_maskwr denied_maskwr fsuid115 ouid115原来 AppArmor 策略禁止mongod写入.lock文件解决方案是echo /var/lib/mongodb/** rwk, | sudo tee -a /etc/apparmor.d/local/usr.bin.mongod sudo systemctl reload apparmor sudo systemctl restart mongod这个案例说明Ubuntu 20.04 的安全机制是层层嵌套的systemctl的状态只是表象真正的瓶颈可能在内核级的 AppArmor。永远不要相信active (running)要用ss、dmesg、journalctl三者交叉验证。5.2 实操心得备份与恢复的黄金组合很多人以为mongodumpmongorestore就是万能备份但在 Ubuntu 20.04 上必须配合systemd的定时任务和logrotate才算完整。我的标准做法是创建备份脚本/opt/scripts/mongo-backup.sh#!/bin/bash DATE$(date %Y%m%d_%H%M%S) BACKUP_DIR/backup/mongodb/$DATE mkdir -p $BACKUP_DIR mongodump --host 127.0.0.1:27017 --username admin --password StrongPassw0rd!2023 --authenticationDatabase admin --out $BACKUP_DIR # 压缩并删除原始目录 tar -czf $BACKUP_DIR.tar.gz -C /backup/mongodb $DATE rm -rf $BACKUP_DIR # 保留最近 7 天 find /backup/mongodb -name *.tar.gz -mtime 7 -delete设为定时任务sudo crontab -e # 添加0 2 * * * /opt/scripts/mongo-backup.sh配置logrotate管理日志echo /var/log/mongodb/mongod.log { daily missingok rotate 30 compress delaycompress notifempty create 644 mongodb mongodb } | sudo tee /etc/logrotate.d/mongodb这套组合拳保证了备份可追溯、日志不爆炸、磁盘不告急。记住备份不是“做一次就完事”而是“每天自动做每周人工检每月灾难演”。6. 后续扩展建议从单机部署到高可用集群的平滑演进路径完成 Ubuntu 20.04 上的 MongoDB 单机部署只是万里长征第一步。根据业务增长你可能会面临三个典型演进阶段每个阶段都有明确的技术选型和 Ubuntu 适配要点。6.1 阶段一读写分离Replica Set当应用读请求远大于写请求如报表系统、数据分析平台单机mongod的 CPU 和 I/O 会成为瓶颈。此时应构建副本集Replica Set它由一个主节点Primary和多个从节点Secondary组成所有写操作只能在 Primary 上执行读操作可路由到 Secondary。在 Ubuntu 20.04 上实现的关键是配置一致性所有节点的/etc/mongod.conf必须启用replication.replSetName: rs0且net.bindIp要包含所有节点的 IP如127.0.0.1,192.168.1.100,192.168.1.101初始化命令在 Primary 节点的mongosh中执行rs.initiate({ _id: rs0, members: [ { _id: 0, host: 192.168.1.100:27017 }, { _id: 1, host: 192.168.1.101:27017 } ] })Ubuntu 适配点确保所有节点时间同步sudo timedatectl set-ntp true因为副本集心跳超时依赖精确时间关闭ufw或为27017端口添加跨节点规则sudo ufw allow from 192.168.1.101 to any port 27017。6.2 阶段二水平扩展Sharding当单个集合数据量超过 1TB或写吞吐量持续超过 10,000 ops/sec就需要分片Sharding。它将数据按片键shard key切分成块chunk分布到多个分片shard上。Ubuntu 20.04 上的最小可行分片集群需 5 个服务1 个 Config Server存储集群元数据必须是副本集2 个 Mongos Router接收客户端请求路由到对应分片2 个 Shard Server实际存储数据的mongod实例。关键 Ubuntu 适配点是每个服务必须用独立的 systemd 单元文件不能共用/lib/systemd/system/mongod.service。例如为 Config Server 创建/etc/systemd/system/mongod-config.service并在ExecStart中指定--configsvr --replSet configReplSet参数。6.3 阶段三云原生集成Kubernetes Operator当你的基础设施迁移到 KubernetesMongoDB 官方提供了MongoDB Kubernetes Operator它用 CRDCustom Resource Definition声明式管理 MongoDB