【问题标题】:How to properly shudown MongoDB before stopping its docker container?如何在停止 Docker 容器之前正确关闭 MongoDB?
【发布时间】:2021-09-12 21:51:15
【问题描述】:

我想知道如何在停止并删除包含它的 docker 映像之前正确等待和关闭 MongoDB 服务器。

此拆解功能停止,然后删除一个 MongoDB docker 映像:

const teardown = async (failOnError = true) => {
  const dockerCommand = `docker stop ${imageName} && docker rm ${imageName}`

  return executeCommand(dockerCommand, environment, 'Finished database teardown', failOnError)
}

执行命令是 Node 的 child_process exec 函数的包装器,它返回一个承诺,这里是完整的 executeCommand 帮助器:

const executeCommand = (command, envObject, resolveMsg, failOnError = true) => new
Promise((resolve, reject) => {
  exec(command, envObject, (err, stdout) => {
    if (err && failOnError) {
      console.error(`Command ${command} failed with error: `, err)
      reject(err)
    }

    // if we don't error we log the resolve message if one present
    if (!err && resolveMsg) console.log(resolveMsg)

    // resolve promise with err object if it exists, otherwise resolve with command output
    resolve(err || stdout)
  })
})

这是在赛普拉斯在运行测试之前和之后调用的异步函数中调用拆卸函数的方式:

module.exports = async (on, config) => {
    on('before:run', async () => {
    console.log('BEFORE:RUN HOOK')

    // attempt to stop and remove docker images just in case teardown was not called at the end of
    // the last run. Note: will not fail or stop tests if teardown command fails
    await teardown(false)
    await setup()
    await checkHostAcceptingConnections()
  })

  on('after:run', async () => {
    console.log('AFTER:RUN HOOK')

    await teardown()
  })
}

事情是这样的:不能保证会调用 after run 挂钩中的拆解函数(以防测试套件挂起)。由于这个原因,容器可能在上次运行后仍处于启动状态。

这些方法按他们说的做,但问题是,如果我调用拆解函数,然后立即启动 MongoDB docker 容器,MongoDB 会输出错误,如“错误:套接字被另一方结束”或“连接 0”到本地主机关闭”。

如果我删除拆卸调用并让 docker 映像启动并运行,这些错误将完全消失 - 这对于本地开发来说很好,但我们的 CI 可能需要重试测试,我更喜欢以完全干净的状态启动 docker 映像.

我的印象是停止、删除然后启动 mongo docker 映像也会完全重置映像,从而清除任何状态。情况似乎并非如此(docker 新手)。

我应该如何停止 MongoDB 服务器?我只在做一些数据库操作之前调用client.connect(),然后在操作之后调用client.close(),这里是一个数据库命令的例子:

const getDocsTotal = async () => {
  await client.connect()
  const collection = client.db('admin').collection('test-data')
  const totalDocs = await collection.countDocuments({})
  await client.close()
  return totalDocs
}

【问题讨论】:

    标签: node.js mongodb docker cypress


    【解决方案1】:

    事实证明我错误地使用了 MonogDB 连接(它创建了一个连接池而不是单例连接)并且没有意识到 client.close() 完全符合我的需要。

    我将代码重构为只调用一次client.connect()(在运行前挂钩期间),因此有效的拆卸命令只需要一行额外的代码:

    // teardown the database by shutting down the MondoDB and using docker stop && docker remove
    const teardown = async (failOnError = true) => {
      const dockerCommand = `docker stop ${imageName} && docker rm ${imageName}`
    
      await client.close()
    
      return executeCommand(dockerCommand, environment, 'Finished database teardown', failOnError)
    }
    

    这个teardown命令会等待客户端连接关闭,这个方法也会彻底关闭数据库。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-17
      • 1970-01-01
      • 2016-10-24
      相关资源
      最近更新 更多