如何在 Docker 中安装 MongoDB

在 Docker 中安装和运行 MongoDB 是一个快速且便携的方式,特别适合开发、测试或需要隔离环境的场景。Docker 允许你通过官方 MongoDB 镜像快速部署 MongoDB,无需手动配置环境。以下是详细的步骤,涵盖如何在 Docker 中安装 MongoDB、配置容器、连接数据库以及一些最佳实践和注意事项。

前提条件

  • 安装 Docker:确保你的系统已安装 Docker(Docker Desktop for Windows/macOS 或 Docker Engine for Linux)。
    • 验证:运行 docker --version,应输出类似 Docker version 27.0.3
  • 网络连接:拉取 MongoDB 镜像需要访问 Docker Hub。
  • 基本 Docker 知识:了解 Docker 命令(如 docker rundocker ps)。

拉取 MongoDB 镜像

MongoDB 提供官方镜像,托管在 Docker Hub(https://hub.docker.com/_/mongo)。

步骤:
  1. 拉取最新 MongoDB 镜像

    docker pull mongo
    
    • 这将拉取最新版本的 MongoDB 镜像(例如 mongo:latest)。
    • 如果需要特定版本(如 MongoDB 8.0),运行:
docker pull mongo:8.0
  1. 验证镜像
docker images
  • 应看到 mongo 镜像及其版本。

运行 MongoDB 容器

使用 docker run 命令启动 MongoDB 容器。

基本运行命令:
docker run -d --name mongodb -p 27017:27017 mongo
  • 参数说明
    • -d:后台运行容器。
    • --name mongodb:为容器命名(可自定义)。
    • -p 27017:27017:将主机的 27017 端口映射到容器的 27017 端口(MongoDB 默认端口)。
    • mongo:使用的镜像名称(若指定版本,如 mongo:8.0)。
验证容器运行:
docker ps
  • 应看到 mongodb 容器处于 Up 状态。
连接到 MongoDB:
  1. 进入容器并使用 MongoDB Shell

    docker exec -it mongodb mongosh
    
    • mongosh 提示符下运行:

      show databases
      
  2. 从主机连接

    • 使用 MongoDB 客户端(如 MongoDB Compass)连接到 localhost:27017

    • 或者使用 Python 的 PyMongo:

      from pymongo import MongoClient
      client = MongoClient("mongodb://localhost:27017/")
      print(client.list_database_names())
      

配置 MongoDB 容器

为了满足实际需求(如持久化数据、设置认证),需要对容器进行额外配置。

a. 持久化数据

Docker 容器是临时的,停止并删除容器后数据会丢失。使用 Docker 卷或绑定挂载来持久化数据。

使用 Docker 卷:
docker run -d --name mongodb -p 27017:27017 -v mongodb-data:/data/db mongo
  • -v mongodb-data:/data/db:创建名为 mongodb-data 的卷,映射到容器的 /data/db(MongoDB 默认数据目录)。

  • 验证卷:

    docker volume ls
    
使用绑定挂载:
mkdir -p ~/mongodb-data
docker run -d --name mongodb -p 27017:27017 -v ~/mongodb-data:/data/db mongo
  • -v ~/mongodb-data:/data/db:将主机目录 ~/mongodb-data 映射到容器。
b. 设置用户名和密码(启用认证)

MongoDB 默认不启用认证。为安全起见,建议设置管理员账户。

运行命令:
docker run -d --name mongodb -p 27017:27017 \
  -e MONGO_INITDB_ROOT_USERNAME=admin \
  -e MONGO_INITDB_ROOT_PASSWORD=secret \
  -v mongodb-data:/data/db \
  mongo
  • 环境变量

    • MONGO_INITDB_ROOT_USERNAME:管理员用户名。
    • MONGO_INITDB_ROOT_PASSWORD:管理员密码。
  • 连接时需认证

    docker exec -it mongodb mongosh -u admin -p secret
    

    或在 PyMongo 中:

    client = MongoClient("mongodb://admin:secret@localhost:27017/")
    
c. 自定义配置文件

如果需要自定义 MongoDB 配置(如修改端口或存储引擎),可以挂载配置文件。

  1. 创建配置文件(如 mongod.conf):

    net:
      port: 27017
    storage:
      dbPath: /data/db
    
  2. 运行容器

    docker run -d --name mongodb -p 27017:27017 \
      -v $(pwd)/mongod.conf:/etc/mongod.conf \
      -v mongodb-data:/data/db \
      mongo --config /etc/mongod.conf
    

管理 MongoDB 容器

以下是常用管理命令:

  • 停止容器

    docker stop mongodb
    
  • 启动容器

    docker start mongodb
    
  • 删除容器(数据卷不会删除):

    docker rm mongodb
    
  • 查看日志

    docker logs mongodb
    
  • 检查容器资源使用

    docker stats mongodb
    

使用 Docker Compose(推荐)

Docker Compose 是一个更方便的方式,通过 YAML 文件定义和运行 MongoDB 容器,适合多容器应用。

示例 docker-compose.yml
version: '3.8'
services:
  mongodb:
    image: mongo:8.0
    container_name: mongodb
    ports:
      - "27017:27017"
    volumes:
      - mongodb-data:/data/db
    environment:
      - MONGO_INITDB_ROOT_USERNAME=admin
      - MONGO_INITDB_ROOT_PASSWORD=secret
    networks:
      - mongo-network
volumes:
  mongodb-data:
networks:
  mongo-network:
    driver: bridge
运行:
  1. 保存以上内容为 docker-compose.yml

  2. 执行:

    docker-compose up -d
    
  3. 验证:

    docker-compose ps
    
  4. 停止和删除:

    docker-compose down
    
优点:
  • 配置清晰,易于维护。
  • 支持多容器环境(例如与 Python 应用容器集成)。
  • 自动管理卷和网络。

在 Python 中连接 Docker 化的 MongoDB

以下是使用 PyMongo 连接到 Docker 容器中的 MongoDB 的示例。

示例代码:
from pymongo import MongoClient

# 连接到 MongoDB(无认证)
client = MongoClient("mongodb://localhost:27017/")

# 如果启用了认证
# client = MongoClient("mongodb://admin:secret@localhost:27017/")

db = client["mydatabase"]
collection = db["mycollection"]

# 插入测试数据
collection.insert_one({"name": "Alice", "age": 25})

# 查询数据
for doc in collection.find():
    print(doc)

client.close()

最佳实践

  • 持久化数据:始终使用卷或绑定挂载,避免数据丢失。

  • 启用认证:生产环境中必须设置用户名和密码。

  • 限制资源:为容器设置 CPU 和内存限制:

    docker run -d --name mongodb --cpus="1" --memory="512m" -p 27017:27017 mongo
    
  • 网络隔离:使用 Docker 网络(默认或自定义)隔离 MongoDB 和其他服务。

  • 监控日志:定期检查 docker logs 以排查问题。

  • 备份数据

    • 使用 mongodump 备份:

      docker exec mongodb mongodump -u admin -p secret --archive=/data/db/backup.archive
      
    • 复制备份到主机:

      docker cp mongodb:/data/db/backup.archive ./backup.archive
      
  • 版本管理:指定明确的 MongoDB 版本(如 mongo:8.0),避免使用 latest 以确保兼容性。

常见问题与解决

  • 端口冲突
    • 如果主机 27017 端口被占用,修改映射端口(如 -p 27018:27017)。
    • 检查:netstat -tuln | grep 27017(Linux)或 netstat -a(Windows)。
  • 连接失败
    • 确保容器运行(docker ps)。
    • 检查认证设置(用户名/密码是否正确)。
    • 对于 Atlas,验证 IP 白名单。
  • 数据丢失
    • 确认是否配置了卷(docker volume ls)。
    • 检查卷挂载路径是否正确。
  • 性能问题
    • 确保主机有足够资源(CPU、内存、磁盘)。
    • 使用索引优化查询(参考 PyMongo 索引操作)。

学习建议

完整示例(Docker Compose + Python)

以下是一个结合 Docker Compose 和 Python 应用的完整示例。

docker-compose.yml
version: '3.8'
services:
  mongodb:
    image: mongo:8.0
    container_name: mongodb
    ports:
      - "27017:27017"
    volumes:
      - mongodb-data:/data/db
    environment:
      - MONGO_INITDB_ROOT_USERNAME=admin
      - MONGO_INITDB_ROOT_PASSWORD=secret
  app:
    build: .
    depends_on:
      - mongodb
    environment:
      - MONGODB_URI=mongodb://admin:secret@mongodb:27017/
volumes:
  mongodb-data:
Dockerfile(Python 应用):
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY app.py .
CMD ["python", "app.py"]
requirements.txt
pymongo==4.8.0
app.py
import os
from pymongo import MongoClient

uri = os.getenv("MONGODB_URI", "mongodb://admin:secret@localhost:27017/")
client = MongoClient(uri)
db = client["mydatabase"]
collection = db["mycollection"]

collection.insert_one({"name": "Test", "source": "Docker"})
print("Inserted document")

for doc in collection.find():
    print(doc)

client.close()
运行:
docker-compose up -d
  • 检查日志:docker logs mongodbdocker logs app
  • 停止:docker-compose down

本文转自 https://blog.csdn.net/u013172930/article/details/148317208,如有侵权,请联系删除。