使用 Mongoose 连接 docker 环境中的 MongoCryptD 实例

Asa*_*fir 5 mongoose mongodb docker docker-compose docker-network

我在网上搜索过但无法在任何地方找到答案。我正在尝试使用 NestJS 框架运行 API Web 服务。

我正在运行 docker-compose,它会启动 API 服务器、MongoDB 实例和 mongocryptd 实例,以允许在我的应用程序上进行客户端字段级加密。

我能够连接到 MongoDB 实例,但无法连接到 mongocryptd 实例。

Docker-Compose 文件:

version: "3.7"
services:
  api:
    build:
      context: .
      dockerfile: Dockerfile
      labels:
        env: dev
      args:
        APP: appname
        APP_PORT: 3000
    ports:
      - "3000:3000"
    command: ["sh", "-c", "npm run start:app:dev"]
    volumes:
      - .:/app

  mongodb:
    build:
      context: .
      dockerfile: docker/MongoEP-Dockerfile
      labels:
        env: dev
      args:
        MONGO_PACKAGE: mongodb-enterprise
        MONGO_REPO: repo.mongodb.com
    image: mongo-enterprise:4.2.5
    command: ["--auth"]
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: usr
      MONGO_INITDB_ROOT_PASSWORD: pwd
    ports:
      - "27017:27017"
    volumes: ["/private/var/services/mongodb:/data/db"]

  mongocryptd:
    build:
      context: .
      dockerfile: docker/MongoEP-Dockerfile
      labels:
        env: dev
      args:
        MONGO_PACKAGE: mongodb-enterprise
        MONGO_REPO: repo.mongodb.com
    image: mongo-enterprise:4.2.5
    entrypoint: mongocryptd
    restart: always
    ports:
      - "27020:27020"
    volumes: ["/private/var/services/mongodb:/data/db"]
Run Code Online (Sandbox Code Playgroud)

使用的 dockerfile 是 mongo 的官方 dockerfile,但提供了 args 来构建包含企业功能的企业版镜像。

当尝试从应用程序连接到数据库时,我正在运行:

MongooseModule.forRoot(`mongodb://usr:pwd@mongodb:27017`, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
      useFindAndModify: false,
      retryAttempts: 2,
      autoEncryption: {
        keyVaultNamespace,
        kmsProviders,
        extraOptions: {
          mongocryptdURI: `mongodb://mongocryptd:27020`,
          mongocryptdBypassSpawn: true
        }
      } as any
    })
Run Code Online (Sandbox Code Playgroud)

**这是提供配置的 NestJS 版本。它类似于 mongoose - 第一个参数是 URI,第二个参数是设置对象


如果没有自动加密选项,我可以毫无问题地进行连接。这意味着我的数据库地址是正确的。通过 autoEncyption 选项,我得到了MongooseServerSelectionError: connect ECONNREFUSED 172.25.0.4:27020(mongocryptd 地址)。这意味着 IP 是正确的(DNS 已解析),但连接被拒绝。正如我之前所展示的,端口 (27020) 正在由 docker-compose 文件发布,我什至尝试在构建本身中添加 EXPOSE 步骤。

但是当我将容器的网络映射到主机 ( network_mode: "host") 时,应用程序能够毫无问题地进行连接(当然将连接 DNS 更改为 localhost:27017 和 27020)。所以这肯定意味着这是一个与 docker 相关的问题。

我尝试过的其他事情&&我尝试过的回顾:

  • 连接一个卷以替换/etc/mongod.conf.orig以下网络配置:
net:
  port: 27017
  bindIp: 0.0.0.0
  bindIpAll: true
Run Code Online (Sandbox Code Playgroud)
  • 不要附加卷,而是在启动 mongo 服务之前的构建步骤中替换它^。
  • 我还尝试将其更改bindIp为 docker 网络提供的特定应用程序 IP。
  • 所有类型的连接字符串,带或不带用户凭据、身份验证源和默认数据库。
  • 端口 27020 在 docker-compose 中发布并在 docker 文件中公开。

我没有主意了。任何帮助表示赞赏!:)

编辑:

经过更多调试后,我可以看到默认情况下mongod正在运行--bind_ip_all,因此更改conf文件应该不会产生影响。还尝试mongocryptd使用 mongodsdocker-entrypoint.sh入口点运行而不是覆盖它。

D. *_* SM 0

  1. 验证mongocryptd正在运行(ps awwxu等)
  2. 验证您可以bash使用它从运行它的同一容器上连接到它mongo
  3. 验证您可以使用从主机系统连接到它mongo
  4. 检查mongocryptd日志(它基本上mongod具有一些额外的功能)。