docker

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > 云和虚拟化 > docker > Docker部署MongoDB

从零搭建到生产环境配置详解Docker部署MongoDB的完整流程

作者:身如柳絮随风扬

在容器化技术日益普及的今天,使用 Docker 部署 MongoDB 已经成为开发和生产环境的标配方案,本文详细介绍了使用Docker部署MongoDB的全过程,希望可以带大家全面掌握 Docker 部署 MongoDB 的核心技能

1. 引言

在容器化技术日益普及的今天,使用 Docker 部署 MongoDB 已经成为开发和生产环境的标配方案。通过容器化部署,我们可以快速创建隔离的数据库环境,确保在不同系统间的一致性和可移植性。MongoDB 官方在 Docker Hub 上维护了官方镜像,拉取即用,大大简化了安装配置流程。

本文将从基础到进阶,带你全面掌握 Docker 部署 MongoDB 的核心技能:

无论你是开发环境搭建,还是准备将 MongoDB 容器化上生产,本文都能提供实用的参考。

2. 环境准备

开始之前,请确保 Docker 已正确安装并运行:

# 检查 Docker 服务状态
sudo service docker status

# 确认 Docker 已安装
docker --version

如果 Docker 尚未安装,请参考官方文档进行安装(Ubuntu/CentOS 等主流发行版均有详细指南)。

3. 快速部署:单节点 MongoDB

3.1 拉取镜像

# 拉取最新官方镜像
docker pull mongo

# 拉取指定版本(如 7.0.14)
docker pull mongo:7.0.14

3.2 运行容器(基础版)

docker run -d --name mongodb -p 27017:27017 mongo

参数说明:

3.3 连接验证

# 进入容器交互式 Shell
docker exec -it mongodb mongosh

如果成功进入 MongoDB Shell,说明部署已完成。

4. 数据持久化:让数据不丢失

容器默认将数据存储在容器内部的 /data/db 目录中,容器一旦删除,所有数据都会丢失。Docker 提供了两种数据持久化方式:

方式说明适用场景
绑定挂载(Bind Mount)将宿主机目录直接映射到容器需要直接访问宿主机文件
命名卷(Named Volume)Docker 管理的独立存储空间生产环境推荐,便于备份迁移

4.1 绑定挂载(Bind Mount)

# 创建宿主机数据目录
mkdir -p /data/mongodb

# 启动容器并挂载目录
docker run -d --name mongodb \
  -p 27017:27017 \
  -v /data/mongodb:/data/db \
  mongo

关键点:宿主机目录必须存在且有正确权限,否则 MongoDB 容器可能因权限不足而启动失败。

4.2 命名卷(Named Volume)

# 创建命名卷
docker volume create mongodb_data

# 挂载卷启动容器
docker run -d --name mongodb \
  -p 27017:27017 \
  -v mongodb_data:/data/db \
  mongo

为什么推荐命名卷? 命名卷完全由 Docker 管理,不依赖宿主机目录结构,更易于备份、迁移和多容器共享。

5. 用户认证与安全配置

生产环境必须启用身份认证,确保数据库不被未授权访问。

5.1 环境变量初始化(推荐方式)

MongoDB 官方镜像支持通过环境变量在首次启动时自动创建 Root 用户:

docker run -d --name mongodb \
  -p 27017:27017 \
  -v mongodb_data:/data/db \
  -e MONGO_INITDB_ROOT_USERNAME=admin \
  -e MONGO_INITDB_ROOT_PASSWORD=your_secure_password \
  mongo

重要提醒

5.2 验证鉴权是否生效

# 使用管理员凭证连接
docker exec -it mongodb mongosh -u admin -p your_secure_password --authenticationDatabase admin

连接后执行以下命令验证权限:

# 切换至测试库
use test
# 尝试写入 - 应报错 "not authorized"(普通用户无权限)
db.test.insertOne({x:1})

如果鉴权未生效,show dbs 等命令会直接列出所有数据库,说明容器没有启用 --auth 模式。

6. Docker Compose 高级配置

使用 Docker Compose 可以更优雅地管理多容器服务。以下是一个完整的 docker-compose.yml 示例,包含 MongoDB 数据库和 Mongo Express 可视化管理界面:

version: '3.8'
services:
  mongodb:
    image: mongo:7.0.14
    container_name: mongodb
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: admin
      MONGO_INITDB_ROOT_PASSWORD: your_secure_password
      MONGO_INITDB_DATABASE: app_db
      TZ: Asia/Shanghai
    ports:
      - "27017:27017"
    volumes:
      - mongodb_data:/data/db
      - ./init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro
    networks:
      - mongodb_network
    healthcheck:
      test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
      interval: 10s
      timeout: 5s
      retries: 5
  mongo-express:
    image: mongo-express:latest
    container_name: mongo-express
    restart: always
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: admin
      ME_CONFIG_MONGODB_ADMINPASSWORD: your_secure_password
      ME_CONFIG_MONGODB_SERVER: mongodb
    ports:
      - "8081:8081"
    depends_on:
      - mongodb
    networks:
      - mongodb_network
networks:
  mongodb_network:
    driver: bridge
volumes:
  mongodb_data:

6.1 自动初始化脚本

上述配置中挂载了 init-mongo.js 脚本,该脚本会在 MongoDB 初始化时自动执行,可用于创建额外的数据库和业务用户:

// init-mongo.js
db = db.getSiblingDB('app_db');
db.createUser({
  user: 'app_user',
  pwd: 'app_user_password',
  roles: [{ role: 'readWrite', db: 'app_db' }]
});
// 可选:创建集合或索引
db.createCollection('users');

6.2 启动服务

# 后台启动所有服务
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看实时日志
docker-compose logs -f mongodb

启动成功后:

7. 生产环境优化与安全加固

7.1 内存管理优化

MongoDB 默认使用 WiredTiger 存储引擎,其缓存大小默认为系统内存的 50%–70%。在 Docker 容器中运行时,需要同时限制容器内存和 WiredTiger 缓存。

容器级限制

docker run -d --name mongodb \
  -m 4g \                           # 限制容器最大内存 4GB
  --memory-swap 4g \                # 禁用 swap(可选)
  -v mongodb_data:/data/db \
  mongo --wiredTigerCacheSizeGB 2   # 限制 WT 缓存为 2GB

核心原则:WiredTiger 缓存大小应始终小于容器的内存上限,并为操作系统和其他进程预留 10%–20% 的空间。在 Docker 或 Kubernetes 环境中,建议按可用内存比例的 50%–60% 配置 cacheSizeGB

Docker Compose 中的配置

services:
  mongodb:
    image: mongo:7.0.14
    deploy:
      resources:
        limits:
          memory: 4G
    command: ["--wiredTigerCacheSizeGB", "2"]

7.2 常见性能问题定位

现象可能原因排查方法
内存占用持续增长WiredTiger 缓存未限制db.serverStatus().wiredTiger.cache 查看 bytes currently in the cache
写入延迟抖动脏页过多,检查点卡顿bytes dirty in the cache 持续偏高,可调低 vm.dirty_ratio
高并发下连接失败连接池耗尽db.serverStatus().connections 查看连接数,应用端优化连接复用

7.3 跨服务依赖与健康检查

当 MongoDB 作为依赖服务(如与 Spring Boot、Node.js 等应用共享网络)时,需要在 docker-compose.yml 中配置健康检查,确保依赖容器在数据库完全就绪后才启动。

services:
  mongodb:
    image: mongo:7.0.14
    healthcheck:
      test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
      interval: 10s
      timeout: 5s
      retries: 5
  myapp:
    image: myapp:latest
    depends_on:
      mongodb:
        condition: service_healthy   # 等待 MongoDB 健康后再启动

7.4 安全加固清单

8. 备份与恢复

8.1 数据备份(mongodump)

# 进入容器执行备份
docker exec mongodb mongodump --out /data/db/backup

# 将备份文件复制到宿主机
docker cp mongodb:/data/db/backup ./mongodb_backup

备份文件默认生成在 dump 目录下,包含 BSON 格式的数据文件。

8.2 数据恢复(mongorestore)

# 将备份文件复制到容器
docker cp ./mongodb_backup mongodb:/data/db/backup

# 进入容器执行恢复
docker exec mongodb mongorestore /data/db/backup

定期备份脚本:可将上述命令写成定时任务(cron job),每日自动备份,并将备份文件同步到远程存储。

9. 副本集(Replica Set)集群搭建(进阶)

对于需要高可用的生产环境,单节点 MongoDB 存在单点故障风险。副本集(Replica Set)是有自动故障恢复功能的主从集群,包含一个 Primary 节点和一个或多个 Secondary 节点,主节点故障时集群会自动选举新主节点。

使用 Docker Compose 搭建一主两从副本集的完整配置如下:

version: '3.8'
services:
  mongo-primary:
    image: mongo:7.0
    container_name: mongo-primary
    command: ["--replSet", "rs0", "--bind_ip_all"]
    ports:
      - "27017:27017"
    volumes:
      - mongo_primary_data:/data/db
    networks:
      - mongo_cluster
  mongo-secondary-1:
    image: mongo:7.0
    container_name: mongo-secondary-1
    command: ["--replSet", "rs0", "--bind_ip_all"]
    ports:
      - "27018:27017"
    volumes:
      - mongo_secondary1_data:/data/db
    networks:
      - mongo_cluster
    depends_on:
      - mongo-primary
  mongo-secondary-2:
    image: mongo:7.0
    container_name: mongo-secondary-2
    command: ["--replSet", "rs0", "--bind_ip_all"]
    ports:
      - "27019:27017"]
    volumes:
      - mongo_secondary2_data:/data/db
    networks:
      - mongo_cluster
    depends_on:
      - mongo-primary
networks:
  mongo_cluster:
    driver: bridge
volumes:
  mongo_primary_data:
  mongo_secondary1_data:
  mongo_secondary2_data:

9.1 初始化副本集

容器启动后,需要手动执行初始化命令:

# 进入主节点容器
docker exec -it mongo-primary mongosh

# 在 MongoDB Shell 中执行
rs.initiate({
  _id: "rs0",
  members: [
    { _id: 0, host: "mongo-primary:27017" },
    { _id: 1, host: "mongo-secondary-1:27017" },
    { _id: 2, host: "mongo-secondary-2:27017" }
  ]
})

初始化后,可通过 rs.status() 查看集群状态。当主节点故障时,剩余节点会自动选举新的 Primary,实现高可用。

10. 常见问题排查

问题原因解决方案
容器启动失败,日志显示 permission denied宿主机挂载目录权限不足使用命名卷而非绑定挂载,或手动设置目录权限
MONGO_INITDB_ROOT_USERNAME 环境变量不生效数据目录非空时不会触发初始化删除数据卷后重新创建:docker-compose down -v
MongoDB 连接超时或拒绝连接端口映射错误或容器未就绪检查 docker ps 确认容器状态,配合健康检查确保服务完全启动
副本集节点无法加入集群容器间网络不通或 bind_ip 配置错误确保所有容器在同一 Docker 网络,且 command 中设置了 --bind_ip_all

11. 总结

通过本文,你应该已经掌握了 Docker 部署 MongoDB 的核心技能。核心回顾:

Docker 容器化部署让 MongoDB 变得前所未有的轻量和可移植,无论是开发测试环境还是生产环境,都能快速交付一致可靠的数据库服务。

以上就是从零搭建到生产环境配置详解Docker部署MongoDB的完整流程的详细内容,更多关于Docker部署MongoDB的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文