假设仅在开发的某些阶段(烟熏测试一些api调用)很少需要这样做,最简单的方法是让Project Bar中的dockerized Web服务访问Project Foo中的dockerized web服务?
在开发Mac上,Docker Engine:18.09.2,Compose:1.23.2,我们有Project Foo和Project Bar,它们各自具有自己的docker-compose文件,每个文件都具有Web服务和数据库服务。>
通常它们是独立运行的,并且是独立开发的。
但是Project Foo的网络服务托管的API仅偶尔需要我们从Project Bar的网络容器中访问
它们被分配给不同的主机端口,docker ps
显示Project Foo使用端口0.0.0.0:3000-> 3000 / tcp(例如,我们使用localhost:3000从Mac的浏览器访问Web服务。 Bar使用端口0.0.0.0:3010-> 3010 / tcp
docker inspect
对于Foo表示其IP地址为“ 172.18.0.3”(网关“ 172.18.0.1”),对于Bar表示其IP地址为“ 172.22.0.4”(网关“ 172.22.0.1”)< / p>
docker network ls
显示它们都使用相同的“桥”驱动程序。
两个项目都在Mac上运行,总共有4个容器(Foo上的web + db和Bar上的web + db)
如果在Bar上运行的程序(Ruby)需要访问Foo上的REST URL,那么Foo上“ / api_test”的URL是什么?
在Bar Web容器中,我尝试了http://localhost:3000/api_test
和http://127.0.0.1:3000/api_test
(这是我们在网络浏览器中使用的功能,因此并不真正希望它可以在容器到容器中使用) ),而我尝试了http://172.18.0.3:3000/api_test
和http://172.18.0.3/api_test
都不起作用。
我看到了有关建立链接或Docker网络的在线参考,但是所有示例都是针对使用docker run而不是docker-compose的。我希望,如果您知道每个容器的Web服务器的IP和端口,那么应该使用正确的URL而无需任何额外的网络设置吗?
任何帮助将不胜感激。
首选手动分配的静态IP解决方案 ......在Docker之前,我们使用Vagrant,这很简单,在每个项目的Vagrantfile中,我们只需在同一私有子网192.168上手动为其分配IP .50.50和192.168.50.51,它们彼此“交谈”就很好了,我们可以简单地将这些IP“编码”到我们的开发代码中。 Docker似乎又增加了一层抽象,这让我感到困惑。
答案 0 :(得分:0)
我终于找到了针对较新版本的Docker提及的SO线程,例如我正在使用主机名host.docker.internal
访问主机,所以我的问题的一个答案是-因为我已经为Foo分配了不同的端口和Bar-Bar容器可以使用网址http://host.docker.internal:3000/api_test
但是仍然能够为每个容器分配静态IP仍然是首选,因此我将这个问题留待解决。
答案 1 :(得分:0)
您可以使用docker网络将容器A接入B。https://docs.docker.com/network/
使用docker网络-帮助。
创建网络
docker network create mynetwork
将容器ContainerA和containerB都放入此网络中,在本例中为mynetwork。
docker network connect mynetwork containerA
docker network connect mynetwork containerB
您现在可以将一个容器访问到另一个具有容器名称的容器。
您也可以使用ping对其进行测试。进行A或B容器打击并使用;
apt-get update
apt-get install iputils-ping
像在容器A中使用ping containerB
一样进行测试。
例如1:
如果要在带有端口的apache虚拟主机设置中使用它;
ProxyPass "/" "http://containerB:3000"
例如2:
我有两个容器;分别命名为base
和myphp
。我正在端口3000
上的基本容器中运行nodejs应用。而且我正在第二个容器myphp上运行apache和php。
基本上,我的nodejs应用程序为我提供了“ Hello Word”输出。它正在容器base
上工作,下面是代码:
'use strict';
const express = require('express');
// Constants
const PORT = 3000;
const HOST = '0.0.0.0';
// App
const app = express();
app.get('/', (req, res) => {
res.send('Hello world\n');
});
app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);
基本上,我的php应用程序为我提供了所有源代码的连接地址。它正在容器myphp
上工作。这是代码:
<?php
$domain = 'http://base:3000';
$handle = fopen($domain, 'r');
$content = stream_get_contents($handle);
fclose($handle);
echo "<textarea rows='20' cols='80'>$content</textarea>";
?>
然后,我将这两个容器放在同一个网络中。当我运行index.php,这是myphp容器应用程序。它给我“你好词”;
因此,如果将容器放置在同一网络中,则可以使用"http://containerB:3000"
之类的名称彼此访问,或者如果路由器正在监听“ / api_test” "http://containerB:3000/api_test"
。
最后,这就是我正在做的通信容器。我希望它也对您有用。
答案 2 :(得分:0)
TLDR :使用http://host.docker.internal
从https://docs.docker.com/docker-for-mac/networking/,
主机的IP地址正在更改(如果没有网络访问权限,则没有IP地址)。从18.03开始,我们的建议是连接到特殊的DNS名称host.docker.internal,它将解析为主机使用的内部IP地址。这是出于开发目的,不适用于Docker Desktop for Mac以外的生产环境。
我尝试过,这也适用于Windows。
例如,如果您在端口5000上的容器中运行python应用程序/微服务,则可以使用它来连接到它:
requests.get('http://host.docker.internal:5000')