从docker里面不能访问mongo

我试图从docker container内部访问mongo当我尝试创buildconnection时发生错误。

new MongoClient(host, port)正在工作。

mongo也在robomongo docker container运行,我可以通过robomongo连接到robomongo docker container ,也可以在robomongo docker container外部运行应用程序,可以连接mongo

我得到以下例外

 No server chosen by WritableServerSelector from cluster description ClusterDescription{type=UNKNOWN, connectionMode=SINGLE, serverDescriptions=[ServerDescription{address=172.17.0.1:27017, type=UNKNOWN, state=CONNECTING}]} 2017-05-25T21:11:32.277 INFO 5 --- [72.17.0.1:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server 172.17.0.1:27017 com.mongodb.MongoSocketOpenException: Exception opening socket at com.mongodb.connection.SocketStream.open(SocketStream.java:63) at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:115) at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:113) at java.lang.Thread.run(Thread.java:745) Caused by: java.net.SocketTimeoutException: connect timed out at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:589) at com.mongodb.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:57) at com.mongodb.connection.SocketStream.open(SocketStream.java:58) ... 3 common frames omitted 

泊坞窗,compose.yml

 mongo: image: library/mongo:3.4.4 ports: - "27017:27017" - "28017:28017" - "28018:28018" volumes: - ./data/mongo:/data/db dronedelivery: image: paulcurcean/dronedelivery:latest ports: - "8080:8080" 

Dockerfile用于无人机交付

 ADD dronedelivery-0-SNAPSHOT.jar / ADD start.sh / # java -jar dronedelivery-0-SNAPSHOT.jar CMD ["sh", "/start.sh"] 

dockerPS /docker – 撰写PS

 image ports dronedelivery 0.0.0.0:8080 -> 8080/tcp mongo 0.0.0.0:27017 -> 27017/tcp, 0.0.0.0:28017-28018 -> 28017-28018/tcp 

我通过new MongoClient(host, port)连接到mongo new MongoClient(host, port)

我认为你遇到的问题是由于你错误地引用了主机。

我在这里创build了一个工作POC ,以创build两个容器,一个SpringBoot应用程序容器和Mongo容器。 信息和说明在README.md

有多个点可能会导致您的应用程序出现故障:

  • 您可能需要确保您的应用程序应该在Mongo运行正常后运行
  • 您的容器默认连接到与主机networking(您的实际主networking)不同的默认bridgenetworking。 bridgenetworking连接到您的主要主机networking。 因此,从另一个容器引用一个容器需要关于用于连接容器的networking,即bridgenetworking来完成。
  • docker-compose.ymlservices.mymongo和端口12345:27017意味着Mongo数据库可以从另一个容器引用为mymongo:27017但是从localhost:12345这样的localhost:12345 mymongo:27017 。 使用从另一个容器localhost:27017是不正确的,因为mymongo是一个主机, myapp例如是另一个。 从myapp调用localhost并不意味着mymongo主机。
  • 为了查询Mongo实例的健康状况,可以使用mongod --rest启用REST api。 因此在docker-compose.yml command: ["mongod", "--rest"] 。 这是用来启动应用程序容器,以了解Mongo实例是否启动并运行。

示例docker-compose.yml

 version: '3' services: myapp: build: ./myapp/docker environment: - SERVER_PORT=8080 - MONGODB_URI=mongodb://mymongo:27017/mydb - MONGODB_STATUS_HOST=mymongo - MONGODB_STATUS_PORT=28017 ports: - 8888:8080 mymongo: image: mongo:3.4 volumes: - ./_data:/data/db ports: - 12345:27017 - 23456:28017 command: ["mongod", "--rest"] 

请注意,Mongo在端口27017上configuration,因此REST接口将在27017 + 1000 = 28017

示例应用程序Dockerfile

以下是用于创build连接到Mongo实例的应用程序的图像的Dockerfile:

 FROM openjdk:8-jdk-alpine RUN apk update && apk upgrade && apk add netcat-openbsd RUN mkdir -p /usr/local/myapp ADD ./myapp.jar /usr/local/myapp/ ADD run.sh run.sh RUN chmod +x run.sh CMD ./run.sh 

然后,应用程序以下面的run.sh脚本启动:

 #!/bin/sh echo "********************************************************" echo "Wait for mongodb to be available" echo "********************************************************" while ! nc -z $MONGODB_STATUS_HOST $MONGODB_STATUS_PORT; do printf 'mongodb is still not available. Retrying...\n' sleep 3 done echo "********************************************************" echo "Starting myapp" echo "********************************************************" java -Dserver.port=$SERVER_PORT \ -Dspring.data.mongodb.uri=$MONGODB_URI \ -jar /usr/local/myapp/myapp.jar 

注意,它首先等待Mongo实例开始查询其REST接口,然后使用OpenJdk 8 JRE从其.jar文件启动应用程序。

你可以用docker-compose代替。

首先,安装docker-compose 。

我假设你正在为你的应用程序使用一个Dockerfile。

docker-compose.yml创build一个目录。

 version: '2' services: mongo: image: mongo:latest restart: always app: build: ./app restart: always volumes: - ./_client/:/var/www/html/ links: - mongo ports: - "80:80" 

现在,在./app中,将当前的Dockerfile放到应用程序中。

在一个_client /文件夹中放置你的应用程序(你可以根据需要更正内部path/ var / www / html)。 两个文件夹与docker-compose.yml文件位于同一级别。

最后,用docker-compose运行全部:

docker-compose -f /path/to/your/docker-compose.yml build

这个命令将会从你的Dockerfile中生成镜像

docker-compose -f /path/to/your/docker-compose.yml up

该命令将创build并运行所有定义的容器。

要从应用程序容器中访问您的mongodb容器,可以使用“mongo”作为主机名(在“services:”中定义的同名)。 在你的主机上,你可以使用docker container的IP,但是你需要在docker-compose.yml中显示一个端口,就像“app”服务一样。