我有两个独立的docker-compose。Yml文件在两个不同的文件夹:

~/front/docker-compose.yml ~/api/docker-compose.yml

我如何确保前面的容器可以在api中向容器发送请求?

我知道——default-gateway选项可以使用docker run为单个容器设置,这样就可以为该容器分配特定的IP地址,但似乎在使用docker-compose时这个选项不可用。

目前,我结束了一个docker检查my_api_container_id,并查看输出中的网关。它是有效的,但问题是这个IP是随机分配的,所以我不能依赖它。

这个问题的另一种形式可能是:

我可以使用docker-compose将一个固定的IP地址归属于特定的容器吗?

但最终我所追求的是:

两个不同的docker-compose项目如何相互通信?


当前回答

您只需要确保希望相互通信的容器位于同一网络上。网络是一流的docker结构,并不是特定于组合。

# front/docker-compose.yml
version: '2'
services:
  front:
    ...
    networks:
      - some-net
networks:
  some-net:
    driver: bridge

...

# api/docker-compose.yml
version: '2'
services:
  api:
    ...
    networks:
      - front_some-net
networks:
  front_some-net:
    external: true

注意:你的应用程序的网络是根据“项目名”来命名的,而“项目名”是基于它所在目录的名称,在这种情况下,添加了一个前缀front_

然后,它们可以使用服务名相互通信。从前面你可以做ping api,反之亦然。

其他回答

我将确保所有的容器都是docker-compose到同一个网络,通过在同一时间将它们组合在一起,使用:

docker compose --file ~/front/docker-compose.yml --file ~/api/docker-compose.yml up -d

如果你是

trying to communicate between two containers from different docker-compose projects and don't want to use the same network (because let's say they would have PostgreSQL or Redis container on the same port and you would prefer to not changing these ports and not use it at the same network) developing locally and want to imitate communication between two docker compose projects running two docker-compose projects on localhost developing especially Django apps or Django Rest Framework (drf) API and running app inside container on some exposed port getting Connection refused while trying to communicate between two containers

你想要

容器api_a与api_b通信(反之亦然)没有相同的“docker网络”

(下面的例子)

你可以使用第二个容器的“host”作为你的计算机的IP和端口,从Docker容器内部映射。你可以用这个脚本获取你计算机的IP地址(从:使用Python的stdlib查找本地IP地址):

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

第二种是船坞结构。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_a连接到api_b,然后api_b容器的URL将是: http:// < get_ip_from_script_above >: 8001 /

如果你正在使用超过两个(三个或更多)docker-compose项目,并且很难为所有这些项目提供公共网络,那么它就特别有价值——这是一个很好的解决方案和解决方案

另一种选择是运行第一个模块,使用“docker-compose”检查与模块相关的ip,并将第二个模块与之前的网络连接,如外部,并指向内部ip

例子 App1 -在服务行中创建的new-network,在底部标记为external: true App2 -表示由app1创建的“新网络”,在底部标记为external: true,并在配置中设置为连接,app1在此网络中的IP。

有了这个,你们就能互相交谈了

*这种方法只是针对局部测试,为了不做过于复杂的配置 **我知道这是非常“补丁的方式”,但对我来说很管用,我认为这是如此简单,其他人可以利用这一点

回答Docker,写“3”以上

默认情况下,Docker Compose使用网桥网络来提供容器之间的通信。有关容器间网络的更多信息,请阅读本文。

重要的是,默认情况下,Docker Compose会创建一个与Docker - Compose中的服务名相同的主机名。yml文件。考虑下面的docker-compose.yml:

version: '3.9'
services:
  server:
    image: node:16.9.0
    container_name: server
    tty: true
    stdin_open: true
    depends_on:
       - mongo
    command: bash

  mongo:
    image: mongo
    environment:
      MONGO_INITDB_DATABASE: my-database

当你运行Docker -compose up时,Docker将创建一个默认网络,并为mongo和server分配服务名作为主机名。

你现在可以通过以下方式访问后端容器:

docker exec -it server bash

现在你可以使用Dockers内部网络(默认端口为27017)来ping mongo容器:

curl -v http://mongo:27017/my-database

就是这样。这同样适用于您的设置。

我正在运行多个相同的docker-compose。Yml文件放在不同的目录下,使用.env文件做一些细微的区别。并使用Nginx Proxy Manage与其他服务通信。这是我的文件:

确保已创建公共网络

docker network create nginx-proxy-man

/domain1.com/docker-compose.yml, /domain2.com/docker-compose.yml,…

version: "3.9"

services:
  webserver:
    build:
      context: ./bin/${PHPVERSION}
    container_name: "${COMPOSE_PROJECT_NAME}-${PHPVERSION}"
    ...
    networks:
      - default    # network outside
      - internal   # network internal
  database:
    build:
      context: "./bin/${DATABASE}"
    container_name: "${COMPOSE_PROJECT_NAME}-${DATABASE}"
    ...
    networks:
      - internal   # network internal


networks:
  default:
    external: true
    name: nginx-proxy-man
  internal:
    internal: true

.env文件只需更改COMPOSE_PROJECT_NAME

COMPOSE_PROJECT_NAME=domain1_com
.
.
.
PHPVERSION=php56

DATABASE=mysql57

网络服务器。container_name: domain1_com-php56 -将加入默认网络(名称:Nginx - Proxy -man),之前为Nginx代理管理器创建,以便从外部访问。

备注:container_name在同一网络中是唯一的。

数据库。Container_name: domain1_com-mysql57—更容易区分

在同样的docker-compose中。Yml,由于相同的网络domain1_com_internal,服务将通过服务名称相互连接。为了更加安全,请使用internal: true选项设置此网络

注意,如果您没有显式地为每个服务指定网络,而只是为两个docker-compose使用一个公共的外部网络。嗯,那么domain1_com很可能会使用domain2_com的数据库。