第一次接触到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

 

posted on 2023-07-11 17:07  06  阅读(2494)  评论(0编辑  收藏  举报