我有两个独立的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-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的数据库。

其他回答

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

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

您可以在所有项目中添加包含COMPOSE_PROJECT_NAME= someename的.env文件。

COMPOSE_PROJECT_NAME覆盖了用于命名资源的前缀,因此所有的项目都将使用somename_default作为它们的网络,使得服务可以相互通信,因为它们在同一个项目中。

注意:您将得到从其他项目创建的“孤立”容器的警告。

要连接两个docker-compose,你需要一个网络,把两个docker-compose都放在这个网络中, 你可以用docker来创建网络,

或者你可以简单地把网络声明放在docker-compose文件的网络选项中,当你运行docker-compose (docker-compose up)时,网络就会自动创建。

在两个docker-compose文件中放入下面的行

networks:
   net-for-alpine:
     name: test-db-net

注意:net-for-alpine是网络的内部名称,它将在docker-compose文件中使用,可以是不同的。 Test-db-net是网络的外部名称,在两个docker-compose文件中必须相同。

假设我们有docker-compose.db。Yml和docker-compose.alpine.yml

docker-compose.apline。Yml是:

version: '3.8'

services:

  alpine:
    image: alpine:3.14
    container_name: alpine
    networks:
      - net-for-alpine
  
    # these two command keeps apline container running
    stdin_open: true # docker run -i
    tty: true # docker run -t



networks:
  net-for-alpine:
    name: test-db-net

docker-compose.db。Yml是:

version: '3.8'

services:

  db:
    image: postgres:13.4-alpine
    container_name: psql
    networks:
      - net-for-db
  
networks:
  net-for-db:
    name: test-db-net

要测试网络,请进入alpine容器

docker exec -it alpine sh 
      

然后使用以下命令可以检查网络

# if it returns 0 or see nothing as a result, network is established
nc -z psql (container name)  

or

ping pgsql

我正在运行多个相同的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的数据库。

更新:从docker-compose文件3.5版开始:

我遇到过类似的问题,我通过在docker-compose中添加一个小更改来解决它。yml项目。

例如,我们有两个API的评分和ner。评分API需要向ner API发送请求以处理输入请求。为了做到这一点,他们都应该共享同一个网络。

注意:每个容器都有自己的网络,这是在docker中运行应用程序时自动创建的。例如,一个API网络将创建像ner_default和评分API网络将命名为评分默认。此解决方案适用于版本:'3'。

在上面的场景中,我的评分API想要与另一个API通信,然后我将添加以下行。这意味着每当我为ner API创建容器时,它会自动添加到scoring_default网络。

networks:
  default:
      external:
        name: scoring_default

ner/docker-compose.yml

version: '3'
services:
  ner:
    container_name: "ner_api"
    build: .
    ...

networks:
  default:
      external:
        name: scoring_default

得分/ docker-compose.yml

version: '3'
services:
  api:
    build: .
    ...

我们可以看到上面的容器现在是同一个名为scoring_default的网络的一部分:

Docker检查scoring_default

{
    "Name": "scoring_default",
        ....
    "Containers": {
    "14a6...28bf": {
        "Name": "ner_api",
        "EndpointID": "83b7...d6291",
        "MacAddress": "0....",
        "IPv4Address": "0.0....",
        "IPv6Address": ""
    },
    "7b32...90d1": {
        "Name": "scoring_api",
        "EndpointID": "311...280d",
        "MacAddress": "0.....3",
        "IPv4Address": "1...0",
        "IPv6Address": ""
    },
    ...
}