第一次接触到mongodb最新版,以及数据库的初始化,踩了不少坑,来记录下
1.docker mongodb启动命令之配置文件
一直很想找docker mongodb的配置文件在哪,在容器里找了个遍,发现/etc/mongod.conf.orig 有个配置文件,但被重命名了,明显不是
后来想到了mongo的dockerfile
地址:https://github.com/docker-library/mongo/blob/master/Dockerfile-linux.template
{{ def target: .targets[.linux] -}} FROM {{ target.image }} # add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added RUN set -eux; \ groupadd --gid 999 --system mongodb; \ useradd --uid 999 --system --gid mongodb --home-dir /data/db mongodb; \ mkdir -p /data/db /data/configdb; \ chown -R mongodb:mongodb /data/db /data/configdb RUN set -eux; \ apt-get update; \ apt-get install -y --no-install-recommends \ ca-certificates \ gnupg \ jq \ numactl \ procps \ ; \ rm -rf /var/lib/apt/lists/* # grab gosu for easy step-down from root (https://github.com/tianon/gosu/releases) ENV GOSU_VERSION 1.16 # grab "js-yaml" for parsing mongod's YAML config files (https://github.com/nodeca/js-yaml/releases) ENV JSYAML_VERSION 3.13.1 RUN set -ex; \ \ savedAptMark="$(apt-mark showmanual)"; \ apt-get update; \ apt-get install -y --no-install-recommends \ wget \ ; \ rm -rf /var/lib/apt/lists/*; \ \ dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \ wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \ wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \ export GNUPGHOME="$(mktemp -d)"; \ gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \ gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \ gpgconf --kill all; \ rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \ \ wget -O /js-yaml.js "https://github.com/nodeca/js-yaml/raw/${JSYAML_VERSION}/dist/js-yaml.js"; \ # TODO some sort of download verification here \ apt-mark auto '.*' > /dev/null; \ apt-mark manual $savedAptMark > /dev/null; \ apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ \ # smoke test chmod +x /usr/local/bin/gosu; \ gosu --version; \ gosu nobody true RUN mkdir /docker-entrypoint-initdb.d RUN set -ex; \ export GNUPGHOME="$(mktemp -d)"; \ set -- {{ .gpg | map(@sh) | join(" ") }}; \ for key; do \ gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ done; \ mkdir -p /etc/apt/keyrings; \ gpg --batch --export "$@" > /etc/apt/keyrings/mongodb.gpg; \ gpgconf --kill all; \ rm -rf "$GNUPGHOME" # Allow build-time overrides (eg. to build image with MongoDB Enterprise version) # Options for MONGO_PACKAGE: mongodb-org OR mongodb-enterprise # Options for MONGO_REPO: repo.mongodb.org OR repo.mongodb.com # Example: docker build --build-arg MONGO_PACKAGE=mongodb-enterprise --build-arg MONGO_REPO=repo.mongodb.com . ARG MONGO_PACKAGE=mongodb-org{{ if (env.version != env.rcVersion) and (env.rcVersion | split(".")[1] | tonumber % 2 == 1) then "-unstable" else "" end }} ARG MONGO_REPO=repo.mongodb.org ENV MONGO_PACKAGE=${MONGO_PACKAGE} MONGO_REPO=${MONGO_REPO} ENV MONGO_MAJOR {{ if env.version != env.rcVersion then "testing" else env.version end }} RUN echo "deb [ signed-by=/etc/apt/keyrings/mongodb.gpg ] http://$MONGO_REPO/apt/{{ target.image | gsub(":.*$"; "") }} {{ target.suite }}/${MONGO_PACKAGE%-unstable}/$MONGO_MAJOR {{ if target.image | test("^debian") then "main" else "multiverse" end }}" | tee "/etc/apt/sources.list.d/${MONGO_PACKAGE%-unstable}.list" {{ if env.version != env.rcVersion and (env.rcVersion | tonumber >= 5) then ( -}} {{ if .version | ltrimstr(env.rcVersion) | startswith(".0-") then ( -}} # {{ env.rcVersion }} is not GA, so we need the previous release for mongodb-mongosh and mongodb-database-tools RUN echo "deb [ signed-by=/etc/apt/keyrings/mongodb.gpg ] http://$MONGO_REPO/apt/{{ target.image | gsub(":.*$"; "") }} {{ target.suite }}/${MONGO_PACKAGE%-unstable}/{{ env.rcVersion | split(".") | .[0] |= (tonumber - 1 | tostring) | join(".") }} {{ if target.image | test("^debian") then "main" else "multiverse" end }}" | tee "/etc/apt/sources.list.d/mongodb-previous.list" {{ ) else ( -}} # add GA repo for mongodb-mongosh and mongodb-database-tools RUN echo "deb [ signed-by=/etc/apt/keyrings/mongodb.gpg ] http://$MONGO_REPO/apt/{{ target.image | gsub(":.*$"; "") }} {{ target.suite }}/${MONGO_PACKAGE%-unstable}/{{ env.rcVersion }} {{ if target.image | test("^debian") then "main" else "multiverse" end }}" | tee "/etc/apt/sources.list.d/mongodb-{{ env.rcVersion }}.list" {{ ) end -}} {{ ) else "" end -}} {{ if .notes then ( -}} # {{ .notes }} {{ ) else "" end -}} ENV MONGO_VERSION {{ .version | gsub("-"; "~") }} {{ if .date or .githash then ( -}} # {{ [ .date // empty, "https://github.com/mongodb/mongo/tree/" + .githash // empty ] | join(", ") }} {{ ) else "" end -}} RUN set -x \ # installing "mongodb-enterprise" pulls in "tzdata" which prompts for input && export DEBIAN_FRONTEND=noninteractive \ && apt-get update \ && apt-get install -y \ ${MONGO_PACKAGE}=$MONGO_VERSION \ ${MONGO_PACKAGE}-server=$MONGO_VERSION \ ${MONGO_PACKAGE}-shell=$MONGO_VERSION \ ${MONGO_PACKAGE}-mongos=$MONGO_VERSION \ ${MONGO_PACKAGE}-tools=$MONGO_VERSION \ && rm -rf /var/lib/apt/lists/* \ && rm -rf /var/lib/mongodb \ && mv /etc/mongod.conf /etc/mongod.conf.orig VOLUME /data/db /data/configdb # ensure that if running as custom user that "mongosh" has a valid "HOME" # https://github.com/docker-library/mongo/issues/524 ENV HOME /data/db COPY docker-entrypoint.sh /usr/local/bin/ ENTRYPOINT ["docker-entrypoint.sh"] EXPOSE 27017 CMD ["mongod"]
最后提到了执行 docker-entrypoint.sh
于是又去查看docker-entrypoint.sh脚本
地址:https://github.com/docker-library/mongo/blob/master/docker-entrypoint.sh
我只能说对于我来说太复杂了。。
不过也大概知道啥意思,结合在mongo容器里找到的/data/configdb目录,大致能猜出来,如果里面有配置文件,会以这个为准,否则为默认配置
所以锁定了要映射出来的目录:
/data/db #mongo容器的数据库存储目录
/data/configdb #mongo容器配置文件目录
/docker-entrypoint-initdb.d #mongo容器的初始化脚本读取目录,可以放置json脚本,让容器读取执行
所以最后运行脚本如下:
里面指定了映射目录,时区,账号密码等,我觉得还是比较全面的命令
注意:/data/db必须单独映射出来,mongo才会把容器里的db文件拷贝出来,我当时只映射了/data结果就没有拷出来
docker run -id \
--name mongodb \
--restart always \
-v /data/docker/mongodb/db:/data/db \
-v /data/docker/mongodb/configdb:/data/configdb \
-v /data/docker/mongodb/initdb:/docker-entrypoint-initdb.d \
-p 27017:27017 \
-e LANG=C.UTF-8 \
-e "TZ=Asia/Shanghai" \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=xxxxx \
mongo:latest \
--auth
至此,docker mongo搭建完成
下面附上docker-compose.yml脚本,便于一键部署,参考文档:https://blog.csdn.net/u011019141/article/details/130651699
其中目录挂载用的是相对路径,要先新建项目文件夹,再在里面创建docker-compose.yml文件,最后一键启动 docker compose up -d
version: '3' services: mongodb-prod: container_name: 'mongodb-prod' image: 'mongo:latest' restart: 'always' environment: - 'TZ=Asia/Shanghai' - 'LANG=C.UTF-8' - 'MONGO_INITDB_ROOT_USERNAME=admin' - 'MONGO_INITDB_ROOT_PASSWORD=xxxx' ports: - '27017:27017/tcp' volumes: - './initdb:/docker-entrypoint-initdb.d' - './db:/data/db' - './configdb:/data/configdb' command: 'mongod --auth'
2.容器内执行mongo命令报错command not found
root@1cbc7e316a67:/data# mongo
bash: mongo: command not found
这个问题真的困扰了我好久,一直以为是安装出问题了,直到看到一篇文章才知道答案
地址:https://blog.csdn.net/mw08091020/article/details/130522808
这是因为MongoDB 6.0全面弃用了mongo
而使用mongosh
。
官方说明链接:https://www.mongodb.com/docs/mongodb-shell/#the-mdb-shell-versus-the-legacy-mongo-shell
换成mongosh之后一切正常
3.新建mongo用户,登陆一直报错认证失败
其实这是mongo基本功的问题,就是mongo新建用户有个原则,就是要先切换到需要用的库,再新建用户
我当时在admin库里新建,然后role里配置到新建库的dbowner角色,最后登陆的目标是新建库
这个让我对role这个参数一直产生了疑惑,不知他的真正用途
不管怎样,以后新建用户
一定要在目标库里新建!
一定要在目标库里新建!
一定要在目标库里新建!
重要的事说三遍
dbOwner包括了读写权限,所以后面的读写属性可以省略了
use 123
db.createUser({ user:'kd',pwd:'xxxx',roles:[ { role:'dbOwner', db: '123'}]});
下面补充下mongo常用命令,作为备忘录
(1).完成创建如想进入admin库,操作步骤为:
#进入mongo命令行
mongosh
#进入admin库(switched to db admin表示进入成功)
use admin
#进行认证登录,admin是这个admin库下的用户,1表示成功,0表示登录失败
db.auth('admin','123456')
(2).下面为常见操作命令
#查询所有数据库
show dbs
#查看当前库
db
#查询当前库中所有表
show collections
#删除当前库中的集合
db.{collection_name}.drop()
#密码认证 db.auth('admin','654321') #退出登录 quit()
#新建数据库,如果数据库不存在,则创建并切换到该数据库,存在则切换到该数据库
use krs-pdds
#创建当前库的用户
db.createUser({ user:'kd',pwd:'xxxx',roles:[ { role:'dbOwner', db: 'krs-pdds'}]});
#修改用户密码
db.updateUser('admin', {pwd: '654321'})
#删除用户
db.dropUser('kd')
#先切换到指定数据库,然后执行以下命令删除数据库
use db1
db.dropDatabase()
(3).用户权限说明
(1)数据库用户角色:read(只读)、readWrite(可读写);
(2)数据库管理角色:dbAdmin(在当前db中执行管理操作的权限)、dbOwner(在当前db中执行任意操作)、userAdmin(在当前db中管理user的权限);
(3)集群管理角色:clusterAdmin(管理机器的最高权限)、clusterManager(管理和监控集群的权限)、clusterMonitor(监控集群的权限)、hostManager( 管理Server);
(4)备份恢复角色:backup、restore;
(5)所有数据库角色:readAnyDatabase(在所有数据库上都有读取数据的权限)、readWriteAnyDatabase(在所有数据库上都有读写数据的权限)、userAdminAnyDatabase(在所有数据库上都有管理user的权限)、dbAdminAnyDatabase(管理所有数据库的权限);
(6)超级用户角色:root(超级用户)
参考文档:https://blog.csdn.net/weixin_45167444/article/details/130762833
我大概找了几篇mongo基础教程,有空可以多看看
https://www.knowledgedict.com/tutorial/mongodb-drop-collection.html
https://mp.weixin.qq.com/s/uMki1mA_2H7zvl5K8RC0LQ
https://mongoing.com/archives/27298
4.mongo数据库数据初始化
当用户建完后面基本就是水到渠成的事,mongodb可以执行/docker-entrypoint-initdb.d文件夹下.js文件和.sh文件,基于这种特性,只要把需要初始化的json脚本全部拷贝到inti目录/data/docker/mongodb/initdb
然后再写个mongoimport命令的脚本即可,由于我这个json文件很少,所以直接在容器里手动执行了
相关细节可以参考文档:https://blog.csdn.net/weixin_41866717/article/details/125668406
示例命令:
-d krs-pdds是数据库名,-c track_point是表名(collections)
mongoimport --host <ip> --port <port> -d <db_name> -u <user_name> -p <password> --authenticationDatabase admin -c <table_name> --file <file_name>.json
mongoimport -u 'kd' -p 'xxxx' --authenticationDatabase krs-pdds -d krs-pdds -c track_point --file /docker-entrypoint-initdb.d/track_point.json
创建索引
mongosh
use krs-pdds db.auth('kd','xxx') db.track_point.createIndex( { coordinate: "2dsphere" }, { name: "coordinate_2dsphere", background: true, } )
5.配置程序启动报错contains a colon (:) or an at-sign (@) then it must be urlencoded
#报错 java.sql.SQLException: java.lang.IllegalArgumentException: The connection string contains invalid user information. If the username or password contains a colon (:) or an at-sign (@) then it must be urlencoded
错误分析:
原因是使用了用户名和密码登录MongoDB数据库的时候,用户名或者密码里面存在特殊字符,比如@ 或者 :符号。由于MongoDB数据库中,url一栏中本身就存在@和:这两种符号。所以如果用户名和密码里面又出现了这些符号,程序就无法正确识别出来那个是真正的分隔符,所以导致了连接报错。
解决方法:
对 @ 符号和 :符号使用16进制进行URL编码,然后使用编码后的字符替换原来用户名和密码中的字符。
@ 符号 使用16进制进行URL编号后的字符为:%40
: 符号 使用16进制进行URL编码后的字符为:%3A
密码中@改为编码字符%40之后启动正常
spring.data.mongodb.uri=mongodb://kd:xxxx%40xxx@127.0.0.1:27017/krs-pdds
参考文档:
https://blog.csdn.net/mw08091020/article/details/130522808
https://blog.csdn.net/weixin_41866717/article/details/125668406
https://blog.csdn.net/mijichui2153/article/details/119300233
https://www.jianshu.com/p/987d45370c93
https://blog.csdn.net/tmy_starlight/article/details/131072651