Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php docker映像的vhost配置_Php_Apache_Docker_Vhosts_Opensuse - Fatal编程技术网

Php docker映像的vhost配置

Php docker映像的vhost配置,php,apache,docker,vhosts,opensuse,Php,Apache,Docker,Vhosts,Opensuse,我正试图为基于openSUSE、PHP7和Apache2.4的本地PHP开发构建一个docker映像。Apache应该解决 http://localhost -> /srv/www/htdocs (openSUSE standard) http://myapp -> /srv/www/myapp/public ... (,等等,如果更容易实现,也可以。) 为了配置vhosts,我添加了/etc/apache2/vhosts.d/myapp.conf,其中包含以下内容: <V

我正试图为基于openSUSE、PHP7和Apache2.4的本地PHP开发构建一个docker映像。Apache应该解决

http://localhost -> /srv/www/htdocs (openSUSE standard)
http://myapp -> /srv/www/myapp/public 
...
(,等等,如果更容易实现,也可以。)

为了配置vhosts,我添加了/etc/apache2/vhosts.d/myapp.conf,其中包含以下内容:

<VirtualHost *:80>
  ServerName localhost
  DocumentRoot /srv/www/htdocs
</VirtualHost>

<VirtualHost *:80>
  ServerName myapp
  DocumentRoot "/srv/www/myapp/public"
  <Directory "/srv/www/myapp/public">
    AllowOverride None
  </Directory>
</VirtualHost>
现在,localhost已正确解析,而myapp未正确解析。Chrome显示“错误名称未解决”

我猜,这是因为myapp的/etc/hosts中没有条目。然而,据我所知,docker不允许修改/etc/hosts。我试图在Dockerfile中使用sed执行此操作:

RUN sed -i 's/^127.0.0.1.*$/127.0.0.1    localhost    myapp/g' /etc/hosts
为了将映射myapp->127.0.0.1添加到/etc/hosts。然而,docker build说

sed: cannot rename /etc/sedLXNJtt: Device or resource busy

因此,我的问题是:如何告诉我的容器正确解析myapp?

这并不奇怪,您正在询问web浏览器的DNS解析程序,这是本地主机上的一个任意程序,可能使用系统解析程序,但它不知道Docker容器,以某种方式找出将该名称解析为哪个Docker容器IP

应用程序级配置 我在过去见过的一种很好的方法是将运行SSH守护进程的容器连接到目标服务的Docker桥网络。然后,您可以使用SSH的动态应用程序级端口转发功能,并将浏览器配置为使用SSH客户端在您选择的端口上设置的SOCKS代理,以及Docker网络中的哪个隧道。如果将浏览器配置为也通过代理解析DNS查询,则应能够访问Docker embedded DNS服务器,默认情况下,该服务器将适当地回答与容器名称对应的域名查询

这件事的好处在于:

  • 您可以要求Docker引擎设置别名,这样您就可以使用完全任意的域名(即使在ICANN控制的TLD下,如您的生产域),这有时可以方便地调试X.509证书问题等
  • 如果您在启动计算机时自动启动SSH代理,例如使用浏览器扩展轻松启用/禁用/切换代理,那么对于所有新容器来说,这一切都是现成的,无需额外配置。当然,这假设所有容器都连接到一个Docker桥网络,如果您正在使用多个Docker桥网络(如果您使用Docker Compose之类的工具,事实上很可能是这样),则需要重新配置内容。这感觉像是可以完全自动化(通过协作的浏览器扩展),因此一些工具可能已经存在(或者您可以编写它们)。我能想到的一个好的用户体验是,它有一个浏览器扩展,允许您快速选择要“连接到”的Docker网络(请记住,不同Docker网络中的不相关容器可能会使用相同的名称)
当然,这种方法不需要SSH,只需要与SOCKS对话并可以与任意虚拟网络接口接口的东西。只是SSH客户机和服务器组合使得现在的设置和实验非常容易,而无需编写任何代码。免责声明:我从未亲自尝试过这种方法,但我认为没有理由不起作用

全系统配置 您可以在本地主机文件中为已找到的每个容器添加一个条目。这显然更简单,但自动化该方法的工具可能更复杂。实际上,您需要编写一个与Docker集成的DNS解析器或服务器,可能还需要使用UI来消除不同Docker网络中不同容器所声明的名称之间的歧义。同样,一些工具可能已经存在,但我个人没有听说过

或者,您可以想象一个不含糊的方案,如
$container\u name.$network\u name.localhost
,尽管您现在需要一些容器(如在您的设置中进行虚拟托管的HTTP服务器)来了解系统级关注点(它们所在的网络),而您更希望它是透明的(您团队中的不同开发人员可能使用不同的网络名称,甚至可能他们在不同的网络上同时测试同一代码库的多个分支)。您可以使用docker compose中的环境替换之类的方法,使其在没有任何配置的情况下仍能运行(假设您始终可以通过环境变量/配置文件模板将这些设置传递给容器进程),但在实践中这可能更为棘手


如果您这样做,您可以将默认系统解析程序的目标设置为DNS服务器(并退回到正常服务器),这可能是一件好事,也可能是一件坏事,具体取决于您想做什么。请注意,根据我的经验,我不知道有多少程序允许您选择任意名称解析程序,甚至任意DNS服务器(因为大多数都依赖于系统解析器)。因此,如果您想要应用程序级配置,这可能不是最好的方法(SOCKS支持更常见).

您是否尝试在基本计算机/etc/hosts中设置myapp?您是否公开了一个端口并将其映射到主计算机?我正在公开-p 80:80。我刚刚尝试将我的本地/etc/hosts中的myapp映射到127.0.0.1,并且…它可以工作!但是,我想知道这是否是应该的方式。通常,配置应该发生在docker映像中,不是吗?谢谢你提供了这些非常有用的信息。现在,我知道即使是像
--add host
--dns
,等等这些都不能使用,因为它们只能处理来自dontainer内部的路由。现在,我认为主机系统的/etc/hosts中的fixex条目可能是最方便的解决方案。或者是其他的我们知道一个解决方案,如何
docker以拦截特定URL的方式运行容器?
sed: cannot rename /etc/sedLXNJtt: Device or resource busy