Run mongodb with docker

Run mongodb with docker Modified: 2023-10-27 20:03:16 Created: 2022-01-02 23:32:30 Tags: #mongodb #docker

本文目标是快速搭建一套mongodb的环境,实现在服务器端运行mongodb,客户端通过网络访问mongodb。服务器上用 docker 来运行mongodb,客户端用pymongo来连接和访问mongodb

本文目标不是深入研究mongodb的技术细节,而在于快速搭建一个工具,帮助后续数据分析。本文分三方面介绍:

  • 服务器上用 docker 安装配置mongodb
  • 客户端用pymongo连接mongodb
  • mongodb的备份与恢复

1 服务器安装配置mongodb

1.1 服务器上 docker 配置

用 docker 来安装配置mongodb,可以省去繁琐mongodb配置,也不会搞坏本地环境。可以查看 docker 官方网站获取安装指南,或者查看这篇文章。为提升 docker 来运行mongodb的体验,建议如下配置 docker:

  1. 配置国内镜像源(这里用中科大的源)

修改配置文件/etc/docker/daemon.json,添加:

{
  "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn/"]
}
  1. 配置 docker 非 root 用户运行
  2. 创建一个docker用户组
  3. 将当前用户加入docker这个组

1.2 运行mongodb容器

服务器上获取mongodb镜像:

docker pull mongo

启动镜像(命名为LearnMongo),注意如下规则:

  1. 端口转发 mongodb服务默认使用端口27017,docker 运行时需要将此端口暴露到 host 机器
  2. 存储位置 mongodb会存储到/data/db,docker 运行时候需要文件夹映射

整体启动命令如下:

docker run --name LearnMongo -d -v $HOME/.LearnMongo:/data/db -p 27017:27017 mongo

通过 docker 命令查看 container 是否启动起来:

docker container ls -a | grep LearnMongo

如果有输出,则是正常运行起来;如果没有,则需要检查 docker 是否正常运行。

客户端的机器上,可以检查服务器相关端口,来确保连接是否通畅:

curl localhost:27017
# It looks like you are trying to access mongodb over HTTP on the native driver port.

如果客户端上没有这个输出,需要检查服务器防火墙是否开启相关端口。

2 客户端连接mongodb

mongoshmongodb的连接工具,实际使用起来并不方便;通常 python 实现的pymongo访问起来就比较方便。

2.1 pymongo连接mongodb

客户端上安装pymongo

python3 -m pip install --user --upgrade pymongo

pymongo来连接客户端,需要一个client

def get_client(host="", port="", account=None, password=None):
    login_kwargs = dict(host=host, port=port)
    if account:
        assert password is not None
        print("login with account and password")
        login_kwargs.update(dict(account=account, password=password))
    return MongoClient(**login_kwargs)

此时可以获取一个 client。通过这个 client,可以对mongodb进行进一步访问。mongodb默认没有密码:一方对初学者非常友好;另外一方面也埋下了安全隐患,因为大家都会忘记设密码。

在进一步使用之前,需对mongodb进行一些说明:

  • 一个mongodb服务中,可以有多个database
  • 每个database下面,又有多个collection
  • 每个collection中存储着许多笔数据,每一笔数据用key-value的形式存储,类似 python 的dict

如果一个database中没有collection,这个database也不存在;如果一个collection中没有数据,这个collection也不存在。当访问database或者collection时候,如果不存在,则会被自动创建。在pymongo中,访问方式如下:

database = client['database_name']
collection = database['collection_name']
# collection.insert_one()

2.2 mongodb各种角色

mongodb有完善权限管理,不同角色对应不同权限。如果对已经有的角色权限不满意,还可以自己创建角色。mongodb的权限有以下几种:

  • read
  • readWrite

也有预先创建好的角色,大概是这几种:

  • userAdmin 某一个 database 的用户管理员(针对数据库的用户,不能修改其它数据)
  • userAdminAnyDatabase 可以管理任意数据库
  • dbAdmin 某一个 database 的 crud 管理,不能管理用户
  • dbAdminAnyDatabase 所有 database 的 crud 管理
  • root 超级用户,拥有一切权限

mongodb权限管理基于数据库(database),在配置角色时候,需要指定数据库。对于用户的管理和数据库的管理是分开的。实际上,对于用户的管理,操作的是mongodb的内建database(名字叫做admin)。

admindb = client.admin
admindb.command(
        "createUser",
        "dbadmin",
        pwd="dbadmin0",
        roles=[{"role": "dbAdminAnyDatabase", "db": "admin"}],
    )

建立好用户之后,需要重新运行服务器端的mongodb,并且添加上相关命令:

mongod --auth

3 mongodb备份与恢复

为了数据安全,需要定期备份数据。mongodb也支持整个数据库备份与恢复。既可以在服务器端,也可以在客户端操作。这里介绍服务器端的备份恢复操作。

3.1 服务器端备份

使用mongodump进行备份,由于mongodb用 docker 运行,需要进入容器中:

docker exec ${container_name} mongodump ${dump_dir}

通常备份的结果在容器内部,备份完成后需要从容器内部拷贝出来:

docker cp ${container_name}:${dump_dir} ${host_local_path}

这样的备份会将所有的 database 和 collection 备份,可以添加--database--collection的方式指定 database 或者 collection。

3.2 服务器端恢复

现将备份好的文件夹拷贝到容器内部:

docker cp ${host_local_path} ${container_name}:${dump_dir}

在容器内部运行mongorestore

docker exec ${container_name} mongorestore ${dump_dir}

总结

本文介绍了mongodb的使用方式,用 docker 运行客户端,用pymongo进行连接和管理mongodb,此外还介绍了在服务器端mongodb的备份与恢复。