Java can';t从内部docker进入mongo

Java can';t从内部docker进入mongo,java,mongodb,docker,Java,Mongodb,Docker,我正试图从docker容器内部访问mongo 当我试图创建连接时发生错误 新的MongoClient(主机、端口)正在运行 mongo也在docker容器中运行,我可以用robomongo连接到它,也可以在其docker容器外运行应用程序可以连接domongo 我遇到了以下异常 No server chosen by WritableServerSelector from cluster description ClusterDescription{type=UNKNOWN, connectio

我正试图从
docker容器内部访问
mongo
当我试图创建
连接时发生错误

新的MongoClient(主机、端口)
正在运行

mongo
也在
docker容器中运行,我可以用
robomongo
连接到它,也可以在其
docker容器外运行应用程序
可以连接do
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
docker 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"]
docker ps/docker compose 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

我正在通过
新的MongoClient(主机、端口)
连接到
mongo
,您可以改用docker compose

首先,安装

我假设您正在为应用程序使用Dockerfile

创建一个目录,里面有一个docker compose.yml

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

在一个_客户端/文件夹中放置你的应用程序(你可以根据需要更正内部路径/var/www/html)。这两个文件夹与docker-compose.yml文件处于同一级别

最后,使用docker compose运行all:

docker-compose-f/path/to/your/docker-compose.yml构建

此命令将从Dockerfile生成映像

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

此命令将创建并运行所有已定义的容器


要从应用程序容器内部访问mongodb容器,可以使用“mongo”作为主机名(与“服务:”中定义的名称相同)。从主机上,您可以使用docker容器IP,但需要公开一个端口,方法与docker compose.yml中的“app”服务相同。

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

我创建了一个工作流程,以便创建两个容器,一个SpringBoot应用程序容器和Mongo容器。有关信息和说明,请参见
README.md

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

  • 您可能需要确保您的应用程序在Mongo正常运行后运行
  • 默认情况下,您的容器连接到默认的
    网桥
    网络,该网络是主机网络(实际的主网络)之外的独立网络。
    网桥
    网络已连接到主主机网络。因此,从另一个容器中引用一个容器时,需要考虑用于连接容器的网络,因此,
    网桥
    网络
  • docker compose.yml
    -
    services.mymongo
    中具有端口
    12345:27017
    意味着可以从另一个容器将Mongo数据库称为
    mymongo:27017
    ,但可以从类似主机的
    localhost:12345
    引用。从另一个容器使用
    localhost:27017
    是不正确的,因为
    mymongo
    是一个主机,
    myapp
    是另一个主机。从
    myapp
    调用
    localhost
    并不意味着
    mymongo
    host
  • 为了查询Mongo实例的运行状况,可以使用
    mongod--REST
    启用restapi。因此,
    命令:[“mongod”、“--rest”]
    位于
    docker compose.yml
    中。这在启动应用程序容器时使用,以了解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
上配置,因此REST接口将在
27017+1000=28017
上可用

示例应用程序摘要文件

以下是用于创建连接到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

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

请添加
docker compose.yml
或相应的
Dockerfile
s。您还可以提供如何连接到应用程序的信息吗容器?您有
链接:
两次。您应该使用
网络
或/和来配置容器的连接方式。有许多预定义的网络
网桥
主机
。默认值为
桥接
,因此所有容器都可以看到彼此,不会出现任何问题。我认为问题还存在于其他方面。我无法理解我是如何错误地称呼主持人的,因为使用相同的引用,我可以连接“robomongo”,并且在docker容器外部运行时,应用程序也可以连接。@Paul从容器外部您可以像
mongo://localhost:27017/...
但是从内部你可以像
mongo://mongo:27017/...
@Paul有两种不同的方法网络,一个来自主机的网络,一个连接容器的网络-默认的,
bridge
。将它们视为单独的网络,在它们之间有一条小小的电线,允许您访问主机上的容器。@Paul因此,容器就像在网络上连接两台PC。您想通过mongo从无人机传送PC连接到PC。因此,您将使用mongo以
mongo://mongo:27017
。我的mongo容器运行在digitalocean服务器上,我可以从本地pc连接到它->从inside docker到mongo的连接应该与从本地pc到mongo的连接相同。此外,在我的本地pc上运行的应用程序可以连接到mongo。