docker镜像的vhost配置

时间:2017-11-25 17:29:56

标签: php apache docker vhosts opensuse

我正在尝试为基于openSUSE,PHP7和Apache 2.4的本地PHP开发构建一个docker镜像。 Apache应解决...

http://localhost -> /srv/www/htdocs (openSUSE standard)
http://myapp -> /srv/www/myapp/public 
...

http://myapp.localhosthttp://myapp.dev等也可以,如果这更容易实现。)

为了配置vhost,我在/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>

这个文件似乎被Apache使用。 apachectl -S导致此输出:

VirtualHost configuration:
*:80                   is a NameVirtualHost
         default server localhost (/etc/apache2/vhosts.d/myapp.conf:2)
         port 80 namevhost localhost (/etc/apache2/vhosts.d/myapp.conf:2)
         port 80 namevhost myapp (/etc/apache2/vhosts.d/myapp.conf:10)
ServerRoot: "/srv/www"
Main DocumentRoot: "/srv/www/htdocs"
Main ErrorLog: "/var/log/apache2/error_log"
Mutex ssl-stapling-refresh: using_defaults
Mutex rewrite-map: using_defaults
Mutex ssl-stapling: using_defaults
Mutex ssl-cache: using_defaults
Mutex default: dir="/run/" mechanism=default 
Mutex mpm-accept: using_defaults
PidFile: "/var/run/httpd.pid"
Define: SYSCONFIG
Define: DUMP_VHOSTS
Define: DUMP_RUN_CFG
User: name="wwwrun" id=30
Group: name="www" id=8

现在,localhost已正确解析而myapp未正确解析。 Chrome说“ERR_NAME_NOT_RESOLVED”。

我想,这是因为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 - &gt; 127.0.0.1到/ etc / hosts。但是,docker build说

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

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

1 个答案:

答案 0 :(得分:1)

这并不令人惊讶,你问你的网页浏览器的DNS解析器,你本地主机上的任意程序可能使用系统解析器而且不知道Docker容器,以某种方式找出哪个Docker容器IP将该名称解析为。

应用程序级配置

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

对此有什么好处是:

  • 您可以要求Docker引擎设置别名,这样您就可以使用完全任意的域名(即使在ICANN控制的TLD下,例如您的生产域),这些域名有时可以用来调试X.509证书问题等等。
  • 如果您在启动计算机时自动启动SSH代理,例如使用浏览器扩展来轻松启用/禁用/切换代理,则所有新容器都可以开箱即用,无需额外配置。当然这假设所有容器都连接到单个Docker桥接网络,如果您正在使用多个Docker桥接网络,则需要重新配置(事实上,如果您正在使用Docker Compose等工具)。这种感觉可以完全自动化(使用合作的浏览器扩展),因此某些工具可能已经存在(或者您可以编写它们)。我能想到的一个不错的用户体验将有一个浏览器扩展,允许您快速选择一个Docker网络,以便连接到&#34; (请记住,不同Docker网络中不相关的容器可能会使用相同的名称)。

当然,您不需要SSH来实现这种方法,只需要与SOCKS进行对话并且可以与任意虚拟网络接口进行交互。只是SSH客户端和服务器组合使得今天很容易设置和试验而无需编写任何代码。免责声明:我从未亲自试过这种方法,但我认为没有理由不会这样做。

系统范围的配置

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

另外,您可以想象一个非模糊的方案,如$container_name.$network_name.localhost,尽管您现在需要一些容器(如在您的设置中执行虚拟主机的HTTP服务器)来了解系统级问题(他们希望在哪个网络中保持透明(团队中的不同开发人员可能会使用不同的网络名称,也许他们甚至会同时测试相同代码库的多个分支)不同的网络)。您可以在docker-compose中使用环境替换之类的东西,使其在没有任何配置的情况下仍然运行(假设您始终可以通过环境变量/配置文件模板将这些设置传递给容器进程),但这在实践中可能比较棘手。 / p>

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