php - Docker镜像的虚拟主机配置

标签 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等也可以,如果更容易实现。)

为了配置虚拟主机,我在/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

现在,本地主机已正确解析,而myapp无法解析。 Chrome会显示“ERR_NAME_NOT_RESOLVED”。

我猜这是因为/ etc / hosts中没有myapp条目。但是,据我了解,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?

最佳答案

这不足为奇,您要询问网络浏览器的DNS解析器,本地主机上的任意程序(可能使用系统解析器,并且不了解Docker容器),以某种方式找出要解析该名称的Docker容器IP 。

应用程序级配置

我过去见过的一个不错的方法是将一个运行SSH守护程序的容器附加到目标服务的Docker桥网络上。然后,您可以使用SSH的动态应用程序级端口转发功能,并将浏览器配置为使用SSH客户端在您选择的端口上以及Docker网络中的哪些隧道上设置的SOCKS代理。如果将浏览器配置为还通过代理解析DNS查询,则应该能够访问Docker嵌入式DNS服务器,默认情况下,它将正确地查询与容器名称相对应的域名查询。

这样做的好处是:

  • 您可以要求Docker引擎设置别名,因此您可以使用完全任意的域名(即使在ICANN控制的TLD下,例如您的生产域),有时可以方便地调试X.509证书问题等。
  • 如果在启动计算机时自动启动SSH代理,例如使用浏览器扩展程序轻松启用/禁用/切换代理,则对于所有新容器,它都可以直接使用,而无需其他配置。当然,这假设所有容器都连接到单个Docker桥接网络,如果您正在使用多个Docker桥接网络(实际上,如果使用的是Docker Compose之类的工具),则需要重新配置。感觉这可以完全自动化(具有协作的浏览器扩展),因此某些工具可能已经存在(或可以编写它们)。我能想到的一个不错的UX将具有浏览器扩展,可让您快速选择要“连接”的Docker网络(请记住,不同Docker网络中不相关的容器可能期望使用相同的名称)。

  • 您当然不需要SSH来使用这种方法,只需要使用SOCKS并可以与任意虚拟网络接口(interface)进行接口(interface)即可。仅仅是SSH客户端和服务器的组合使得无需编写任何代码即可非常轻松地进行设置和试验。免责声明:我从未亲自尝试过这种方法,但是我认为没有任何理由不可行。

    系统范围的配置

    您可以在本地主机文件中为每个容器添加一个条目,如前所述。这显然更简单,但是可能需要更多自动化该方法的工具。实际上,您将需要编写一个与Docker(也许与UI)集成的DNS解析器或服务器,以消除由不同Docker网络中的不同容器声明的名称之间的歧义。同样,可能已经存在一些工具,但是我个人还没有听说过任何工具。

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

    如果这样做,您可以将默认系统解析器定位到该DNS服务器(并回退到普通服务器),这取决于您想做什么,可以是好事或坏事。请注意,以我的经验,我不知道有多少程序可以让您选择一个任意的名称解析器甚至是任意的DNS服务器(因为大多数服务器都依赖于系统解析器)。因此,如果要进行应用程序级配置,这可能不是最佳方法(更常见的是SOCKS支持)。

    关于php - Docker镜像的虚拟主机配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47488722/

    相关文章:

    docker - 列出Docker Compose中使用的图像

    python - 需要检查容器是否在运行

    PHP 添加选项到<select multiple></select>

    php - 使用CRON导入远程.sql文件

    apache - 内网无法访问虚拟主机

    apache - 如果 tomcat 宕机让 apache 提供另一个页面

    Apache 无法访问 Tomcat : AH00957, AH00959 和 AH00896

    php - 从数据库中获取数据并在 php 中使用循环

    PHP MySQL 多维数组 - 下拉菜单

    docker - 使用 Docker 上的 Hadoop 无法访问站点