我有两个独立的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项目如何相互通信?


当前回答

如果你是

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 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

更新:作为撰写文件版本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

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

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

回答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

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

之前的帖子信息是正确的,但是没有详细说明如何链接容器,应该连接为“external_links”。

希望这个例子能让你更清楚:

假设您有app1/docker-compose。Yml,包含两个服务(svc11和svc12),以及app2/docker-compose。Yml和另外两个服务(svc21和svc22),假设你需要以交叉方式连接: Svc11需要连接到svc22的容器 Svc21需要连接到svc11的容器。

所以构型应该是这样的:

这是app1/docker-compose.yml:


version: '2'
services:
    svc11:
        container_name: container11
        [..]
        networks:
            - default # this network
            - app2_default # external network
        external_links:
            - container22:container22
        [..]
    svc12:
       container_name: container12
       [..]

networks:
    default: # this network (app1)
        driver: bridge
    app2_default: # external network (app2)
        external: true

这是app2/docker-compose.yml:


version: '2'
services:
    svc21:
        container_name: container21
        [..]
        networks:
            - default # this network (app2)
            - app1_default # external network (app1)
        external_links:
            - container11:container11
        [..]
    svc22:
       container_name: container22
       [..]

networks:
    default: # this network (app2)
        driver: bridge
    app1_default: # external network (app1)
        external: true

要连接两个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