CircleCI中MongoDB连接URI正确性排查及应用连接失败问题
在CircleCI环境中运行MongoDB时,通过mongo Shell能成功连接数据库,但应用一直挂起无法建立连接。以下是相关配置和执行输出:
配置文件 config.yml
version: 2.1 orbs: node: circleci/node@5.0.2 nx: nrwl/nx@1.5.1 commands: bt-setup: steps: - checkout - bt-yarn-install bt-mongo: steps: - run: name: MongoDB Install command: | sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4 echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.0.list sudo apt-get update sudo apt-get install -y mongodb-org-shell - setup_remote_docker: version: 20.10.14 - run: name: Dockerize Mongo command: dockerize -wait tcp://localhost:27017 -timeout 1m - run: name: Get versions command: | node -v npm -v mongo --version mongo localhost --eval "db.version()" - run: name: Connect to DB command: mongo --eval "printjson(db.apikeys.count());" localhost bt-yarn-install: steps: - node/install-packages: pkg-manager: yarn jobs: test-api: docker: - image: cimg/node:lts-browsers - image: mongo:4.4.14 environment: NX_CLOUD_DISTRIBUTED_EXECUTION: "true" steps: - bt-setup - bt-mongo - run: name: Run Tests command: | MONGODB_URI=mongodb://127.0.0.1:27017/localhost IS_CI_TEST=true yarn test:api --run-in-band - bt-nx-stop workflows: build: jobs: - test-api
执行输出
$ node -v v16.16.0 $ npm -v 8.11.0 $ mongo --version MongoDB shell version v4.0.28 git version: af1a9dc12adcfa83cc19571cb3faba26eeddac92 OpenSSL version: OpenSSL 1.1.1f 31 Mar 2020 allocator: tcmalloc modules: none build environment: distmod: ubuntu1804 distarch: x86_64 target_arch: x86_64 $ mongo localhost --eval "db.version()" MongoDB shell version v4.0.28 connecting to: mongodb://127.0.0.1:27017/localhost?gssapiServiceName=mongodb Implicit session: session { "id" : UUID("ceab1ceb-c061-4be2-bc34-ef72f67331d5") } MongoDB server version: 4.4.14 WARNING: shell and server versions do not match 4.4.14
询问当前使用的连接字符串MONGODB_URI=mongodb://127.0.0.1:27017/localhost是否正确,希望排查问题原因。
连接字符串正确性说明
mongodb://127.0.0.1:27017/localhost的语法是合法的:127.0.0.1:27017是主机地址和端口,最后的localhost是指定连接的数据库名称。但这不是应用连接失败的核心原因。
核心问题点
Docker容器网络隔离
在CircleCI的Docker executor模式下,主容器(cimg/node:lts-browsers)和服务容器(mongo:4.4.14)处于同一内部网络,但主容器不能通过127.0.0.1访问服务容器,需要使用服务容器的主机名(默认是镜像名mongo)来访问。多余的
setup_remote_docker步骤
你已经通过job的docker字段启动了Mongo服务容器,setup_remote_docker会启动另一个独立的远程Docker环境,导致网络环境混淆,这一步完全多余,应该删除。Dockerize等待目标错误
当前dockerize -wait tcp://localhost:27017等待的是主容器的27017端口,但Mongo服务运行在另一个容器中,这个等待没有实际作用,需要改为等待服务容器的地址。
修复步骤
修改应用连接字符串
将测试命令中的连接字符串改为:MONGODB_URI=mongodb://mongo:27017/localhost IS_CI_TEST=true yarn test:api --run-in-band删除多余的
setup_remote_docker步骤
在bt-mongo命令中移除以下代码块:- setup_remote_docker: version: 20.10.14修正Dockerize等待地址
将dockerize命令改为:dockerize -wait tcp://mongo:27017 -timeout 1m验证Mongo Shell连接方式(可选)
为了和应用使用一致的连接方式验证,可将Mongo Shell命令改为:mongo mongo --eval "db.version()" mongo mongo --eval "printjson(db.apikeys.count());"
内容的提问来源于stack exchange,提问作者goldylucks

