我在两个不同的文件夹中有两个单独的docker-compose.yml
文件:
如何确保front
中的容器可以向api
中的容器发送请求?
我知道可以使用--default-gateway
为单个容器设置docker run
选项,以便可以为此容器分配特定的IP地址,但似乎此选项在使用时不可用docker-compose
。
目前我最终做了docker inspect my_api_container_id
并查看输出中的网关。它有效,但问题是这个IP是随机归因的,所以我不能依赖它。
这个问题的另一种形式可能是:
但最终我正在照顾的是:
答案 0 :(得分:190)
您只需要确保要彼此通信的容器位于同一网络中。网络是一流的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_
然后他们可以使用服务名称相互交谈。从front
开始,您可以ping api
,反之亦然。
答案 1 :(得分:54)
只是对@ johnharris85的一个小小的调整,这是一个很好的答案,
当您运行泊坞窗撰写文件时," default
"网络已创建
所以你可以把它作为外部网络添加到另一个撰写文件中:
# front/docker-compose.yml
version: '2'
services:
front_service:
...
...
# api/docker-compose.yml
version: '2'
services:
api_service:
...
networks:
- front_default
networks:
front_default:
external: true
对我而言,这种方法更适合,因为我没有第一个docker-compose文件并想与之通信。
答案 2 :(得分:44)
更新:从撰写文件版本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
这将创建一个位于外部网络上的容器。
我在文档中找不到任何引用但它有效!
答案 3 :(得分:22)
来自api
的所有容器都可以通过以下配置加入front
默认网络:
# api/docker-compose.yml
...
networks:
default:
external:
name: front_default
请参阅docker撰写指南:using a pre existing network(参见底部)
答案 4 :(得分:7)
以前的帖子信息是正确的,但它没有关于如何链接容器的详细信息,这些容器应该连接为“external_links”。
希望这个例子让你更清楚:
假设你有app1 / docker-compose.yml,有两个服务(svc11和svc12),app2 / docker-compose.yml有两个服务(svc21和svc22),假设你需要连接一种交叉的方式:
svc11需要连接到svc22的容器
所以配置应该是这样的:
这是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
答案 5 :(得分:3)
从Compose 1.18(规范3.5)开始,您可以使用自己的自定义名称覆盖默认网络,以获取所需的所有Compose YAML文件。它就像向他们追加以下内容一样简单:
networks:
default:
name: my-app
以上假设您将
version
设置为3.5
(如果他们不在4 +内弃用,则为以上)。
其他答案也有相同的说法;这是一个简化的摘要。
答案 6 :(得分:2)
您可以在所有包含.env
的项目中添加COMPOSE_PROJECT_NAME=somename
文件。
COMPOSE_PROJECT_NAME会覆盖用于命名资源的前缀,因为您的所有项目都将使用somename_default
作为其网络,从而使服务可以像在同一项目中一样相互通信。
注意:您将收到从其他项目创建的“孤立”容器的警告。
答案 7 :(得分:1)
我会确保所有容器docker-compose
通过同时将它们组合在同一个网络中,使用:
docker compose --file ~/front/docker-compose.yml --file ~/api/docker-compose.yml up -d
答案 8 :(得分:1)
更新:从撰写文件版本3.5开始:
我遇到了类似的问题,并通过在docker-compose.yml项目之一中添加了一个小的更改来解决了这个问题。
例如,我们有两个API scoring
和ner
。 Scoring
api需要向ner
api发送请求以处理输入请求。为了做到这一点,他们俩都假定共享同一网络。
注意:每个容器都有其自己的网络,该网络是在docker内部运行应用程序时自动创建的。例如,将创建像ner_default
这样的ner api网络,并将评分api网络命名为scoring default
。此解决方案适用于版本“ 3”。
在上述情况下,我的计分api要与ner api通信,那么我将添加以下几行。这意味着每当我为ner api创建容器时,它就会自动添加到scoring_default网络。
networks:
default:
external:
name: scoring_default
version: '3'
services:
ner:
build: .
...
networks:
default:
external:
name: scoring_default
version: '3'
services:
api:
build: .
...
使用以下命令,我们可以看到上述容器现在如何成为称为scoring_default
的同一网络的一部分:
泊坞窗检查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": ""
},
...
}
答案 9 :(得分:0)
version: '2'
services:
bot:
build: .
volumes:
- '.:/home/node'
- /home/node/node_modules
networks:
- my-rede
mem_limit: 100m
memswap_limit: 100m
cpu_quota: 25000
container_name: 236948199393329152_585042339404185600_bot
command: node index.js
environment:
NODE_ENV: production
networks:
my-rede:
external:
name: name_rede_externa
答案 10 :(得分:0)
要使用其他docker-compose网络,只需执行以下操作(在docker-compose之间共享网络):
- 通过
AB
运行第一个docker-compose项目- 通过以下方式查找第一个docker-compose的网络名称:
up -d
(其中包含根目录项目的名称)- 然后在下面的第二个docker-compose文件中通过此结构使用该名称。
第二个docker-compose.yml
docker network ls
答案 11 :(得分:0)
另一种选择是使用“ docker-compose”运行第一个模块,检查与该模块相关的ip,然后将第二个模块与先前的网络(例如外部)连接,并指向内部ip
示例 app1-在服务行中创建的新网络,标记为外部:底部为true app2-向上显示由app1创建的“新网络”,在底部标记为external:在true,然后在配置中进行设置以连接app1在该网络中拥有的ip。
有了这个,你应该能够互相交谈
*此方法仅用于本地测试,以免进行过于复杂的配置 **我知道这是非常“修补方式”,但对我有用,我认为其他人可以利用此方法很简单
答案 12 :(得分:0)
如果您是
Connection refused
您想
api_a
与api_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_a
到api_b
连接,那么api_b
容器的URL将为:
http://<get_ip_from_script_above>:8001/
如果您要使用两个(三个或更多)docker-compose项目,并且很难为所有项目提供通用网络,这将是非常有价值的-这是一个很好的解决方法和解决方案