我正在尝试为基于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等也可以,如果这更容易实现。)
为了配置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?
答案 0 :(得分:1)
这并不令人惊讶,你问你的网页浏览器的DNS解析器,你本地主机上的任意程序可能使用系统解析器而且不知道Docker容器,以某种方式找出哪个Docker容器IP将该名称解析为。
我过去看到的一个很好的方法是将运行SSH守护程序的容器附加到目标服务的Docker桥接网络。然后,您可以使用SSH的动态应用程序级端口转发功能,并将浏览器配置为使用SSH客户端在您选择的端口上设置的SOCKS代理以及Docker网络内的隧道。如果您将浏览器配置为也通过代理解析DNS查询,您应该能够访问Docker嵌入式DNS服务器,默认情况下会对与容器名称对应的域名的查询做出适当的回答。
对此有什么好处是:
当然,您不需要SSH来实现这种方法,只需要与SOCKS进行对话并且可以与任意虚拟网络接口进行交互。只是SSH客户端和服务器组合使得今天很容易设置和试验而无需编写任何代码。免责声明:我从未亲自试过这种方法,但我认为没有理由不会这样做。
您可以在本地主机文件中为已找到的每个容器添加一个条目。这显然更为直接,但可能更多地涉及自动化该方法的工具。实际上,您需要编写与Docker集成的DNS解析器或服务器,可能需要使用UI来消除不同Docker网络中不同容器声明的名称之间的歧义。有些工具可能已经存在,但我个人没有听说过。
另外,您可以想象一个非模糊的方案,如$container_name.$network_name.localhost
,尽管您现在需要一些容器(如在您的设置中执行虚拟主机的HTTP服务器)来了解系统级问题(他们希望在哪个网络中保持透明(团队中的不同开发人员可能会使用不同的网络名称,也许他们甚至会同时测试相同代码库的多个分支)不同的网络)。您可以在docker-compose中使用环境替换之类的东西,使其在没有任何配置的情况下仍然运行(假设您始终可以通过环境变量/配置文件模板将这些设置传递给容器进程),但这在实践中可能比较棘手。 / p>
如果你这样做,你可以让你的默认系统解析器目标是DNS服务器(并回退到普通服务器),这可能是好事还是坏事,具体取决于你想做什么。请注意,根据我的经验,我不知道许多程序允许您选择任意名称解析程序甚至任意DNS服务器(因为大多数程序依赖于系统解析程序)。因此,如果您想要应用程序级配置,这可能不是最好的方法(SOCKS支持更常见)。