从Docker容器连接到本地MongoDB

42

我有一个运行在mongodb://127.0.0.1:27017上的本地mongoDB服务器。我的数据库名称为localv2。我有一个node/express应用程序,Dockerfile如下:

FROM node:7.5

RUN npm install -g pm2

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY package.json /usr/src/app
RUN npm install

COPY . /usr/src/app

EXPOSE 3002

ENV NODE_ENV local

CMD pm2 start --no-daemon server.js

server.js文件使用以下代码连接到本地mongodb:

app.db = mongoose.connect("mongodb://127.0.0.1:27017/localv2", options);

当我使用上面的Dockerfile创建的镜像启动容器时,这不起作用。我在某个地方读到Docker会创建一个带有自己网关IP地址的VLAN。当我用docker inspect查看我的容器时,我的网关IP地址是:172.17.0.1。

即使将mongodb连接更改为

app.db = mongoose.connect("mongodb://172.17.0.1:27017/localv2", options)

重新构建镜像并启动新容器后,我仍然遇到了错误:

MongoError: failed to connect to server [172.17.0.1:27017] on first connect [MongoError: connect ECONNREFUSED 172.17.0.1:27017]
运行容器的命令:docker run -p 3002:3002 image-name 请帮忙。

你是如何运行Mongo的?它也在Docker中吗? - Vlad Holubiev
不,它正在作为独立服务器运行。 - chaudharyp
6
Docker官方文档:https://docs.docker.com/engine/reference/run/#network-host 这份文档介绍了在Docker容器中使用"host"网络模式的方法。通过使用"host"网络模式,容器可以直接访问主机上的网络资源,而不需要进行端口映射或其他网络配置。 - Vlad Holubiev
尝试找出您的PC本地IP地址而不是容器地址,并将其添加到Mongo连接配置中。 - bxN5
@VladHolubiev 那个有效。谢谢! - chaudharyp
我不确定我缺少什么,但我在连接到服务器10.113.12.198:27017时出现了org.mongodb.driver.cluster - 监视器线程异常。 - Sourabh Roy
5个回答

38

2
我更喜欢这个解决方案,胜过所有其他的方案。 - Gibberish

22

因为这个方法对我有用且可以帮助用户找到答案,所以在此将@vlad-holubiev的回答添加进来。

使用如文档中所述的docker run命令的网络主机选项

当网络设置为主机时,容器将共享主机的网络栈,并且主机的所有接口都可用于容器。容器的主机名将匹配主系统上的主机名。

docker run -d -e ROOT_URL=http://localhost -e MONGO_URL=mongodb://localhost:27017 --network="host"

尝试解决相同的问题,但不理解您如何使用它:您使用此代码来运行容器吗? - JSking
1
收到以下错误提示:node: 错误选项: --network=host!该怎么办? - Rohit Rane
@jackOfAll,你用的是Windows/Mac操作系统吗? - Abhishek Pankar
@AbhishekPankar Mac - Rohit Rane
网络主机仅适用于Linux机器。在此处检查 https://docs.docker.com/network/host/ - Abhishek Pankar

13

一个 Docker 容器是独立于你的计算机的,
因此你将无法连接到你的 localhost
你应该在容器上运行 MongoDB 服务器,然后使用镜像名称进行连接。

mongodb://CONTAINER-NAME:port

3
这是一个更好的回答。 - Armeen Moon
1
这完全取决于你是否暴露了端口。如果你暴露了内部的Docker容器端口,你可以使用localhost进行连接。 - RaduM
Docker容器是独立但相互连接的,因此可以从容器内部连接到本地计算机,您只需要找出本地计算机在Docker网络上的IP地址即可。在破坏本地网络DNS集成之前(大约版本19.0),这更容易实现,当时您可以指定本地计算机的名称,DNS会自动查找。 - MikeT
如何在docker-compose文件中指定外部mongo数据库连接。 - vinsent paramanantham
当然可以连接到本地主机。基于什么来源,你断言这是不可能的? - Paulo Guimarães

2

谢谢,这在Windows上运行正常。我不知道为什么它没有赞。需要注意的是,您链接的文档指出它只应用于开发目的,不能在生产环境中使用。 - Mis
我之前一直很困惑,直到我找到了这个解决方法。如果你的Mongo容器名称是mongodb_container,那么在命名URI时请不要包含端口号: mongoose.connect(mongodb://mongodb_container/mydatabase, {}); - undefined

0

创建 .env 文件,例如:

DB_HOST=myMongoServiceIp
DB_USER=myMongoDBUser
DB_PORT=myMongoServicePort
DB_PASSWORD=myMongoDBPort
DB_AUTH_NAME=myMongoDBAuthDatabase
DB_CONNECT_NAME=myStartDBConnection

如果您的本地机器上已经有MongoDB服务,只需将DB_HOST替换为host.docker.internal。这是一个特殊的DNS名称,仅解析为主机使用的内部IP地址。当在生产模式下运行时,当然需要用服务器的正确IP替换DB_HOST
最后,本地主机示例.env:
DB_HOST=host.docker.internal
DB_USER=app1
DB_PORT=27017
DB_PASSWORD=123
DB_AUTH_NAME=admin
DB_CONNECT_NAME=test

如果您的应用程序是使用Mongoose编写的,那么mongodb连接字符串可能类似于:
var mongoConnectionString = `mongodb://${process.env.DB_USER}:${process.env.DB_PASSWORD}@${process.env.DB_HOST}:${process.env.DB_PORT}/${process.env.DB_CONNECT_NAME}?authSource=${process.env.DB_AUTH_NAME}`

最终,现在运行Docker容器,你只需要将你的.env文件添加到其中即可,例如:
docker run --env-file .\src\.env --name MyContainer -dp 8080:8080 <myUser>/<repo>:<tagname>

那么您有一个使用本地MongoDB而不是另一个容器的容器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接