我正在尝试为基于openSUSE,PHP7和Apache 2.4的本地PHP开发构建docker镜像。 Apache应该解决...
http://localhost -> /srv/www/htdocs (openSUSE standard)
http://myapp -> /srv/www/myapp/public
...
(http://myapp.localhost,http://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服务器,默认情况下,它将正确地查询与容器名称相对应的域名查询。
这样做的好处是:
您当然不需要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/