我有两个独立的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 3.5+版本在docker-compose之外创建的网络(“外部”网络)。

进一步的解释可以在这里找到。

第一个docker-compose。yml文件应该定义名为giveItANamePlease的网络,如下所示。

networks:
  my-network:
    name: giveItANamePlease
    driver: bridge

第一码头的服务。Yml文件可以使用网络如下:

networks:
  - my-network

在第二个docker-compose文件中,我们需要使用我们在第一个docker-compose文件中使用的网络名来代理网络,在本例中是giveItANamePlease:

networks:
  my-proxy-net:
    external:
      name: giveItANamePlease

现在你可以在第二个docker-compose服务中使用my-proxy-net了。Yml文件如下。

networks:
  - my-proxy-net

其他回答

您只需要确保希望相互通信的容器位于同一网络上。网络是一流的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都放在这个网络中, 你可以用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

这么多答案!

首先,避免在实体名称中使用连字符,如服务、网络等。它们会导致名称解析问题。

例如:my-api不能工作。Myapi或API可以工作。

对我有用的是:

# api/docker-compose.yml
version: '3'

services:
  api:
    container_name: api
    ...
    ports:
      - 8081:8080
    networks:
      - mynetwork

networks:
  mynetwork:
    name: mynetwork

and

# front/docker-compose.yml
version: '3'

services:
  front:
    container_name: front
    ...
    ports:
      - 81:80
    networks:
      - mynetwork

networks:
  mynetwork:
    name: mynetwork

注意:我添加端口是为了展示服务如何相互访问,以及如何从主机访问它们。

重要提示:如果您没有指定网络名称,docker-compose将为您创建一个。它使用文件夹的名称docker_compose。Yml文件已导入。本例中为api_mynetwork和front_mynetwork。这将阻止容器之间的通信,因为它们将位于不同的网络上,具有非常相似的名称。

请注意,两个文件中对网络的定义完全相同,因此可以先启动其中一个服务,然后它就可以工作了。不需要指定哪个是外部的,docker-compose会为你管理它。

来自主持人

你可以使用docker-compose.yml中定义的已发布端口来访问任何一个容器。

您可以访问Front容器:curl http://localhost:81

您可以访问API容器:curl http://localhost:8081

从API容器

您可以使用原始端口访问Front容器,而不是您在docker-compose.yml中发布的端口。

例如:curl http://front:80

从前面的容器

你可以使用原始端口访问API容器,而不是你在docker-compose.yml中发布的端口。

例如:curl http://api:8080

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

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

更新:作为撰写文件版本3.5:

现在可以工作了:

version: "3.5"
services:
  proxy:
    image: hello-world
    ports:
      - "80:80"
    networks:
      - proxynet

networks:
  proxynet:
    name: custom_network

Docker-compose up -d将加入一个名为“custom_network”的网络。如果它不存在,它将被创建!

root@ubuntu-s-1vcpu-1gb-tor1-01:~# docker-compose up -d
Creating network "custom_network" with the default driver
Creating root_proxy_1 ... done

现在,你可以这样做:

version: "2"
services:
  web:
    image: hello-world
    networks:
      - my-proxy-net
networks:
  my-proxy-net:
    external:
      name: custom_network

这将创建一个位于外部网络上的容器。

我在文档中找不到任何参考资料,但它是有效的!