容器之间的连接被拒绝

时间:2019-04-14 09:27:21

标签: docker docker-compose

我尝试将运行Spring Boot 2应用程序的容器链接到运行mongo的容器,但连接被拒绝

docker-compose文件具有一个用于mongo的容器(稍后还将在此处添加另一个用于春季启动的容器)

version: '3.1'

services:
  mongo:
    image: mongo
    container_name: springboot-mongo
    ports:
      - 27017:27017
    volumes:
      - $HOME/data/springboot-mongo-data:/data/db
      - $HOME/data/springboot-mongo-bkp:/data/bkp
    restart: always

用于春季启动的dockerfile

FROM openjdk:11
RUN apt-get update && apt-get install bash
RUN mkdir -p /opt/app
ENV PROJECT_HOME /opt/app
COPY build/libs/recipe-book.jar $PROJECT_HOME/recipe-book.jar
WORKDIR $PROJECT_HOME
CMD ["java", "-Dspring.data.mongodb.uri=mongodb://springboot-mongo:27017/recipes", "-jar","./recipe-book.jar"]

我尝试了多种发送命令行mongo uri的方法:使用localhost而不是springboot-mongo,我还尝试了如何在此处https://www.baeldung.com/spring-boot-command-line-arguments,更具体地说是-Dspring-boot.run.arguments=--spring.data.mongodb.uri=mongodb://springboot-mongo:27017/recipes中对其进行描述。每次似乎都碰到连接被拒绝。

如何使弹簧容器连接到mongo?

谢谢

更新,我也尝试过将第二个容器添加到docker-compose文件中,

version: '3.1'

services:
  springboot:
    build: .
    restart: always
    container_name: springboot
    ports:
      - 8182:8080
    working_dir: /opt/app
    depends_on:
      - mongo

  mongo:
    image: mongo
    container_name: springboot-mongo
    ports:
      - 27017:27017
    volumes:
      - $HOME/data/springboot-mongo-data:/data/db
      - $HOME/data/springboot-mongo-bkp:/data/bkp
    restart: always

更新2:

我设法通过首先在计算机上本地构建映像,然后在docker-compose文件中使用创建的映像并使用-Dspring.data.mongodb.uri=mongodb://springboot-mongo:27017/recipes作为参数来部分解决该问题,但是仍然不能直接构建它在docker-compose文件中

5 个答案:

答案 0 :(得分:1)

如果您希望容器之间能够进行对话,则需要将它们添加到相同的docker网络中,

像这样更新您的docker-compose.yml文件:

version: '3.1'
services:
  springboot:
    build: .
    restart: always
    container_name: springboot
    ports:
      - 8182:8080
    working_dir: /opt/app
    depends_on:
      - mongo
    networks:
      - local

  mongo:
    image: mongo
    container_name: springboot-mongo
    ports:
      - 27017:27017
    volumes:
      - $HOME/data/springboot-mongo-data:/data/db
      - $HOME/data/springboot-mongo-bkp:/data/bkp
    restart: always
    networks:
      - local
networks:
  local:
    driver: bridge

答案 1 :(得分:0)

如果您是

  • 尝试在两个容器之间进行通信时获取Connection refused
  • 试图在不同的docker-compose项目不想使用相同的网络的两个容器之间进行通信(因为假设它们将具有PostgreSQL或Redis容器相同的端口上,您最好不要更改这些端口,并且不要在同一网络上使用它)
  • 在本地进行开发,并且希望模仿两个docker compose项目
  • 之间的通信
  • 在本地主机上运行两个docker-compose项目
  • 特别开发Django应用程序或Django Rest Framework(drf)API,并在某些暴露的端口上的容器内运行应用程序

您想

  • 容器api_aapi_b通信(反之亦然),而没有相同的“ docker网络”

(下面的示例)

您可以将第二个容器的“主机”用作计算机的IP和从Docker容器内部映射的端口。您可以使用以下脚本获取计算机的IP(来自:Finding local IP addresses using Python's stdlib):

import socket
def get_ip():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        # doesn't even have to be reachable
        s.connect(('10.255.255.255', 1))
        IP = s.getsockname()[0]
    except:
        IP = '127.0.0.1'
    finally:
        s.close()
    return IP

示例:

project_api_a/docker-compose.yml

networks:
  app-tier:
    driver: bridge

services:
  api:
    container_name: api_a
    image: api_a:latest
    depends_on:
      - postgresql
    networks:
      - app-tier

api_a容器中,您正在运行Django应用程序: manage.py runserver 0.0.0.0:8000

和其他项目中的第二个docker-compose.yml:

project_api_b/docker-compose-yml

networks:
  app-tier:
    driver: bridge

services:
  api:
    container_name: api_b
    image: api_b:latest
    depends_on:
      - postgresql
    networks:
      - app-tier

api_b容器中,您正在运行Django应用程序: manage.py runserver 0.0.0.0:8001

并尝试从容器api_aapi_b连接,那么api_b容器的URL将为: http://<get_ip_from_script_above>:8001/

如果您要使用两个(三个或更多)docker-compose项目,并且很难为所有项目提供通用网络,这将是非常有价值的-这是一个很好的解决方法和解决方案

答案 2 :(得分:0)

如果您在容器内重新使用对localhost的引用,请在运行docker时使用--network="host"

答案 3 :(得分:0)

你真的不需要使用 docker-compose。

让我们一步一步来:

创建一个网络,例如:

docker network create network-labolida

启动两个容器:

docker run --hostname=www1 -p 81:8080  --net=network-labolida --name=www1  -t www1 
docker run --hostname=www2 -p 82:8080  --net=network-labolida --name=www2  -t www2 

验证:

docker network inspect network-labolida

这将告诉您与该网络关联的容器名称。

然后,诀窍:使用容器名称!

不要使用暴露的端口,而是使用内部端口:8080!

我的意思是:

如果您想从您的主机访问您的包含服务,例如使用 PostMan,请使用:

http://127.0.0.1:81/api/mymicroservice/

http://127.0.0.1:89/api/mymicroservice/

但是

如果您想要的是让您的 container-01 访问 contanier-02 ,请使用:

http://www2:8080/api/mymicroservice/

(HOSTNAME+InternalPort) 来自 container-01。

答案 4 :(得分:0)

除了@shushu304 的回答,这对我来说也适用于有问题的容器

networks:
  - local
  - default