无法从docker内部访问mongo

Pau*_*aul 6 java mongodb docker

我试图mongo从 a 内部docker container 访问 当我尝试创建connection.

new MongoClient(host, port)工作中。

mongo也在 a 中运行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
Run Code Online (Sandbox Code Playgroud)

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"
Run Code Online (Sandbox Code Playgroud)

用于无人机送货的 Dockerfile

ADD dronedelivery-0-SNAPSHOT.jar /
ADD start.sh /  # java -jar dronedelivery-0-SNAPSHOT.jar
CMD ["sh", "/start.sh"]
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

我正在mongo通过以下方式连接new MongoClient(host, port)

and*_*eim 5

I think the problem you are encountering is due to the fact that you are referencing the host incorrectly.

I created a working POC here in order create two containers, a SpringBoot application container and the Mongo container. The information and instructions are in the README.md.

There are multiple points which may cause your app to malfunction:

  • you might need to ensure that your app should run after Mongo is functioning properly
  • 您的容器默认连接到默认bridge网络,该网络是与主机网络(您的实际主网络)不同的网络。该bridge网络已连接到您的主主机网络。因此,从一个容器引用另一个容器需要根据用于连接容器的网络(即网络)来完成bridge
  • 拥有 in docker-compose.yml- services.mymongowith 端口12345:27017意味着 Mongo 数据库可以从另一个容器引用,但mymongo:27017也可以从主机引用localhost:12345。从另一个容器使用localhost:27017是不正确的,因为mymongo它是一个主机,而myapp例如是另一个主机。呼叫localhost来源myapp并不意味着mymongo主机。
  • 为了查询 Mongo 实例的运行状况,您可以使用 启用 REST api mongod --rest。因此command: ["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"]
Run Code Online (Sandbox Code Playgroud)

请注意,Mongo 是在端口上配置的27017,因此 REST 接口将在 上可用27017 + 1000 = 28017

示例应用程序 Dockerfile

以下是用于创建连接 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 Code Online (Sandbox Code Playgroud)

然后使用以下脚本启动应用程序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
Run Code Online (Sandbox Code Playgroud)

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


Gon*_*alo 1

您可以使用 docker-compose 代替。

首先,安装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"
Run Code Online (Sandbox Code Playgroud)

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

在 _client/ 文件夹中放置您的应用程序(您可以根据需要更正内部路径 /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

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

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