Docker 安装 MongoDB
大约 8 分钟约 2265 字
Docker 安装 MongoDB
简介
MongoDB 是一个基于文档的 NoSQL 数据库,以其灵活的数据模型、出色的水平扩展能力和丰富的查询语言而著称。它使用 BSON(Binary JSON)格式存储数据,天然适合存储结构不固定或半结构化的数据,在现代 Web 应用、物联网、内容管理系统等场景中被广泛使用。
使用 Docker 部署 MongoDB 可以快速搭建开发、测试环境,也能通过合理的配置满足中小型生产环境的需求。本文将详细介绍使用 Docker 部署 MongoDB 的完整流程,包括镜像选择、容器配置、数据持久化、认证授权、备份恢复以及生产环境的优化建议。
环境准备
系统要求
| 项目 | 最低要求 | 推荐配置 |
|---|---|---|
| 操作系统 | CentOS 7+ / Ubuntu 18.04+ | CentOS 7.9 |
| 内存 | 1GB | 4GB+ |
| 磁盘 | 10GB | 50GB+ SSD |
| Docker | 19.03+ | 最新稳定版 |
检查 Docker 环境
# 检查 Docker 版本
docker --version
# 检查 Docker 服务状态
systemctl status docker
# 检查可用磁盘空间
df -h第一步:拉取 MongoDB 镜像
# 搜索可用的 MongoDB 镜像
docker search mongo
# 拉取最新版本的 MongoDB 镜像
docker pull mongo:latest
# 建议指定版本(生产环境务必固定版本)
docker pull mongo:6.0
docker pull mongo:5.0.15
# 查看已拉取的镜像
docker images | grep mongo版本选择建议
- MongoDB 6.x:最新稳定版,包含性能改进和安全增强
- MongoDB 5.x:长期支持版本,适合需要稳定性的生产环境
- MongoDB 4.4:旧版 LTS,适用于遗留系统兼容
- 生产环境严禁使用
latest标签,必须固定具体版本号
第二步:创建宿主机挂载目录
在启动容器之前,先创建用于数据持久化和日志存储的目录:
# 创建数据目录
mkdir -p /usr/local/docker/mongodb/data
# 创建日志目录
mkdir -p /usr/local/docker/mongodb/logs
# 创建配置文件目录
mkdir -p /usr/local/docker/mongodb/conf
# 设置目录权限(MongoDB 容器内使用 mongodb 用户,UID 通常为 999)
chown -R 999:999 /usr/local/docker/mongodb
chmod -R 755 /usr/local/docker/mongodb第三步:运行容器
基础启动(开启认证)
docker run --name mongodb \
-p 27017:27017 \
--restart=always \
--privileged \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=your_strong_password \
-v /usr/local/docker/mongodb/data:/data/db \
-v /usr/local/docker/mongodb/logs:/var/log/mongodb \
-d mongo:6.0 \
mongod --auth参数详解
| 参数 | 说明 |
|---|---|
-d | 后台运行容器 |
--name mongodb | 指定容器名称为 mongodb |
-p 27017:27017 | 端口映射,宿主机 27017 端口映射到容器 27017 端口 |
--restart=always | Docker 服务重启后容器自动启动 |
--privileged | 拥有真正的 root 权限,解决可能的权限问题 |
-e MONGO_INITDB_ROOT_USERNAME=admin | 指定管理员用户名 |
-e MONGO_INITDB_ROOT_PASSWORD=your_strong_password | 指定管理员密码 |
-v /usr/local/docker/mongodb/data:/data/db | 将宿主机数据目录挂载到容器内数据目录 |
mongod --auth | 以认证模式启动 MongoDB |
使用自定义配置文件启动
# 创建 MongoDB 配置文件
cat > /usr/local/docker/mongodb/conf/mongod.conf <<EOF
# 数据存储目录
storage:
dbPath: /data/db
journal:
enabled: true
wiredTiger:
engineConfig:
cacheSizeGB: 2
# 日志配置
systemLog:
destination: file
path: /var/log/mongodb/mongod.log
logAppend: true
# 网络配置
net:
port: 27017
bindIp: 0.0.0.0
# 安全配置
security:
authorization: enabled
# 操作日志
operationProfiling:
mode: slowOp
slowOpThresholdMs: 100
EOF
# 使用配置文件启动
docker run --name mongodb \
-p 27017:27017 \
--restart=always \
-v /usr/local/docker/mongodb/data:/data/db \
-v /usr/local/docker/mongodb/logs:/var/log/mongodb \
-v /usr/local/docker/mongodb/conf/mongod.conf:/etc/mongod.conf \
-d mongo:6.0 \
mongod -f /etc/mongod.conf密码安全
示例中的密码 your_strong_password 仅为演示用途。生产环境密码必须满足以下要求:
- 至少 8 个字符
- 包含大小写字母、数字和特殊字符
- 不要使用常见密码或与用户名相同
- 不要在脚本中明文存储密码,考虑使用 Docker Secrets 或环境变量文件
防火墙配置
# 查看防火墙当前的放行端口列表
firewall-cmd --list-ports
# 添加防火墙放行端口(permanent 代表永久生效)
firewall-cmd --add-port=27017/tcp --permanent
# 重新加载防火墙(添加完放行端口一定要重新加载防火墙)
firewall-cmd --reload
# 验证端口是否放行成功
firewall-cmd --list-ports验证安装
进入容器连接数据库
# 进入容器
docker exec -it mongodb bash
# 使用管理员账号连接
mongosh -u admin -p your_strong_password --authenticationDatabase admin
# 如果是 MongoDB 5.0 以下版本,使用 mongo 命令
mongo -u admin -p your_strong_password --authenticationDatabase admin基本数据库操作
// 查看所有数据库
show dbs
// 切换到 admin 数据库
use admin
// 创建普通用户
db.createUser({
user: "appuser",
pwd: "appuser_password",
roles: [
{ role: "readWrite", db: "myapp" },
{ role: "dbAdmin", db: "myapp" }
]
})
// 切换到应用数据库
use myapp
// 插入测试数据
db.users.insertOne({ name: "zhangsan", email: "zhangsan@example.com", age: 28 })
// 查询数据
db.users.find()
// 查看用户列表
show users
// 查看当前数据库状态
db.stats()用户与权限管理
MongoDB 内置角色
| 角色分类 | 角色 | 说明 |
|---|---|---|
| 数据库用户角色 | read / readWrite | 读写权限 |
| 数据库管理角色 | dbAdmin / userAdmin | 管理数据库和用户 |
| 集群管理角色 | clusterAdmin / clusterMonitor | 集群管理 |
| 备份恢复角色 | backup / restore | 备份和恢复 |
| 超级用户角色 | root | 所有权限(谨慎使用) |
创建不同权限的用户
// 连接到 MongoDB
mongosh -u admin -p your_strong_password --authenticationDatabase admin
// 创建只读用户
use myapp
db.createUser({
user: "readonly_user",
pwd: "readonly_password",
roles: [{ role: "read", db: "myapp" }]
})
// 创建读写用户
use myapp
db.createUser({
user: "readwrite_user",
pwd: "readwrite_password",
roles: [{ role: "readWrite", db: "myapp" }]
})
// 创建备份用户
use admin
db.createUser({
user: "backup_user",
pwd: "backup_password",
roles: [{ role: "backup", db: "admin" }]
})
// 查看所有用户
use admin
db.system.users.find({}, { user: 1, db: 1, roles: 1 })
// 删除用户
use myapp
db.dropUser("readonly_user")
// 修改密码
db.changeUserPassword("appuser", "new_password")数据备份与恢复
容器内备份
# 全库备份
docker exec mongodb mongodump \
-u admin -p your_strong_password \
--authenticationDatabase admin \
--out /data/backup/$(date +%Y%m%d)
# 备份指定数据库
docker exec mongodb mongodump \
-u admin -p your_strong_password \
--authenticationDatabase admin \
-d myapp \
--out /data/backup/myapp_$(date +%Y%m%d)
# 备份指定集合
docker exec mongodb mongodump \
-u admin -p your_strong_password \
--authenticationDatabase admin \
-d myapp -c users \
--out /data/backup/users_$(date +%Y%m%d)
# 备份到宿主机
docker exec mongodb mongodump \
-u admin -p your_strong_password \
--authenticationDatabase admin \
--archive=/data/backup/full_backup_$(date +%Y%m%d).gz \
--gzip数据恢复
# 恢复全库备份
docker exec -i mongodb mongorestore \
-u admin -p your_strong_password \
--authenticationDatabase admin \
--gzip --archive < /backup/full_backup_20240101.gz
# 恢复指定数据库
docker exec mongodb mongorestore \
-u admin -p your_strong_password \
--authenticationDatabase admin \
-d myapp \
/data/backup/myapp_20240101/myapp
# 恢复指定集合
docker exec mongodb mongorestore \
-u admin -p your_strong_password \
--authenticationDatabase admin \
-d myapp -c users \
/data/backup/users_20240101/myapp/users.bson自动化备份脚本
#!/bin/bash
# /opt/scripts/mongodb_backup.sh
set -euo pipefail
BACKUP_DIR="/backup/mongodb"
DATE=$(date +%Y%m%d_%H%M%S)
RETAIN_DAYS=7
MONGO_USER="admin"
MONGO_PASS="your_strong_password"
MONGO_AUTH_DB="admin"
CONTAINER_NAME="mongodb"
# 创建备份目录
mkdir -p "${BACKUP_DIR}"
# 执行备份
echo "[$(date)] Starting MongoDB backup..."
docker exec "${CONTAINER_NAME}" mongodump \
-u "${MONGO_USER}" -p "${MONGO_PASS}" \
--authenticationDatabase "${MONGO_AUTH_DB}" \
--gzip \
--archive="/data/backup/backup_${DATE}.gz"
# 从容器复制备份到宿主机
docker cp "${CONTAINER_NAME}:/data/backup/backup_${DATE}.gz" "${BACKUP_DIR}/"
# 清理旧备份
find "${BACKUP_DIR}" -name "*.gz" -mtime +${RETAIN_DAYS} -delete
echo "[$(date)] MongoDB backup completed: backup_${DATE}.gz"
# 添加到 crontab
# 0 2 * * * /opt/scripts/mongodb_backup.sh >> /var/log/mongodb_backup.log 2>&1常见问题排查
容器启动失败
# 查看容器日志
docker logs mongodb
# 查看详细日志
docker logs --tail 100 mongodb
# 常见原因:
# 1. 数据目录权限问题 → chown -R 999:999 /usr/local/docker/mongodb/data
# 2. 端口被占用 → ss -tlnp | grep 27017
# 3. 配置文件语法错误 → 检查 mongod.conf 格式连接被拒绝
# 检查容器是否运行
docker ps | grep mongodb
# 检查端口映射
docker port mongodb
# 检查防火墙
firewall-cmd --list-ports
# 检查 MongoDB 是否监听正确的地址
docker exec mongodb mongosh --eval "db.serverStatus().host"
# 检查认证是否正常
docker exec mongodb mongosh -u admin -p your_strong_password --authenticationDatabase admin --eval "db.runCommand({ping:1})"性能问题
// 查看服务器状态
db.serverStatus()
// 查看当前操作
db.currentOp()
// 查看慢查询
db.setProfilingLevel(1, { slowms: 100 })
db.system.profile.find().sort({ ts: -1 }).limit(10)
// 查看集合统计信息
db.users.stats()
// 查看索引使用情况
db.users.aggregate([{ $indexStats: {} }])性能优化建议
WiredTiger 存储引擎调优
# 在 mongod.conf 中配置
storage:
wiredTiger:
engineConfig:
cacheSizeGB: 2 # 缓存大小,建议为物理内存的 50%
journalCompressor: snappy
collectionConfig:
blockCompressor: snappy # 压缩算法:snappy/zlib/zstd
indexConfig:
prefixCompression: true索引优化
// 查看集合的索引
db.users.getIndexes()
// 创建单字段索引
db.users.createIndex({ email: 1 })
// 创建复合索引
db.users.createIndex({ name: 1, age: -1 })
// 创建唯一索引
db.users.createIndex({ email: 1 }, { unique: true })
// 创建 TTL 索引(自动过期数据)
db.logs.createIndex({ createdAt: 1 }, { expireAfterSeconds: 2592000 })
// 删除索引
db.users.dropIndex("email_1")Docker Compose 部署
# docker-compose-mongodb.yml
version: '3.8'
services:
mongodb:
image: mongo:6.0
container_name: mongodb
restart: always
ports:
- "27017:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: your_strong_password
TZ: Asia/Shanghai
volumes:
- ./mongodb/data:/data/db
- ./mongodb/logs:/var/log/mongodb
- ./mongodb/conf/mongod.conf:/etc/mongod.conf
command: mongod -f /etc/mongod.conf
networks:
- app-net
mongo-express:
image: mongo-express:latest
container_name: mongo-express
restart: always
ports:
- "8081:8081"
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: admin
ME_CONFIG_MONGODB_ADMINPASSWORD: your_strong_password
ME_CONFIG_MONGODB_URL: mongodb://admin:your_strong_password@mongodb:27017/
depends_on:
- mongodb
networks:
- app-net
networks:
app-net:
driver: bridge安全加固清单
- 启用认证:始终使用
--auth参数启动,不要在无认证模式下运行 - 限制监听地址:生产环境使用
bindIp限制为内网地址 - 强密码策略:使用复杂密码,定期更换
- 最小权限原则:为应用创建专用的数据库用户,只授予必要权限
- 启用 TLS/SSL:配置加密传输
- 防火墙:只对需要访问的服务器开放 27017 端口
- 定期备份:建立自动化备份流程并定期验证恢复
- 审计日志:开启数据库审计功能
- 禁止公网暴露:不要将 MongoDB 直接暴露在公网上
- 更新版本:及时更新到最新的稳定版本,修复已知漏洞
