使用主机名访问Docker容器中的Apache服务器

时间:2014-12-31 03:30:08

标签: apache dns docker

我有一个使用Apache 2.4.6和CentOS在Docker容器中运行的Web应用程序;这个应用程序反过来通过Docker链接与其他几个Docker容器(如后端服务和mysql)进行通信。我可以使用boot2docker vm的ip在本地连接到app容器,即http://192.168.59.103:80/。但是,我希望能够通过具有子域名的域名在本地访问它,即http://test.mydomain.com。原因是应用程序使用$_SERVER[ 'HTTP_HOST' ]变量来验证请求,而后端服务使用HTTP_ORIGIN标头来验证来自Web应用程序的请求来自有效的子域。因此,在浏览器中测试应用程序时,我需要它正确发送这些HTTP标头。我只需要为本地环境配置它,而不是部署(特别是为了对应用程序运行持续集成测试)。我真的不知道如何配置本地系统(OS X Mavericks)和CI环境(Ubuntu 12.04)以使域名可访问。

这是我目前的配置:

的httpd.conf

<VirtualHost *:80>
    DocumentRoot /var/www/site
    ServerAlias 172.*
    ServerName mydomain.com
    UseCanonicalName On

    <Directory "/var/www/site">
        Options FollowSymLinks
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

这是我运行以启动Web应用程序容器的命令:

docker run -d -p 80:80 -h mydomain.com --name web --link mysql:mysql --link memcached:memcached --link service:service --link api:base-api myorg/mywebapp:develop

在此设置下,我可以在http://192.168.59.103成功导航到该应用,但由于HTTP_HOST是IP,因此该应用不会解析子域,也不会对登录进行身份验证。有没有办法我可以这样做本地请求something.mydomain.com将重定向到docker容器? ServerName mydomain.com行在apache配置中有什么用途,-h mydomain.com命令中有docker run参数?

3 个答案:

答案 0 :(得分:2)

来自docker networking

docker run -h

  

-h HOSTNAME或--hostname = HOSTNAME - 设置容器知道自己的主机名。这被写入/ etc / hostname,作为容器面向主机的IP地址的名称写入/ etc / hosts,并且是容器内的/ bin / bash在其提示符中显示的名称。但是容器外部不容易看到主机名。它不会出现在docker ps中,也不会出现在任何其他容器的/ etc / hosts文件中。

因此,您无法使用主机名ping容器,但此命令对于apache设置非常有用。

Apache ServerName从Apache Docs执行以下操作:

  

ServerName指令设置服务器用于标识自身的请求方案,主机名和端口。这在创建重定向URL时使用。

     

此外,在使用基于名称的虚拟主机时,使用ServerName(可能与ServerAlias结合使用)来唯一标识虚拟主机。

要访问子域,您需要Serverpath directive。您还必须在名称为mydomain.com的hosts文件中输入vm(192.168.59.103)的IP地址。如果你这样做了,你应该可以ping mydomain.com。

Here就是一个例子(来自askubuntu的问题)。

答案 1 :(得分:2)

您可以定义容器的主机名和域名,并使用shell脚本为您更新/ etc / hosts。

在这里,您可以找到有关如何:http://www.intrapesite.ro/access-docker-application-by-hostname的一些内容。

可以创建一个docker应用程序,它将监听docker api(启动和停止)并更新主机和guest虚拟机之间的共享/ etc / hosts文件(作为一个优雅的自动化解决方案)。看看,例如在ruby api:https://github.com/swipely/docker-api#events,也许与bjeanes / ghost主机经理(github)一起。

更新:

另一种方法是在主机上添加网桥,提供静态IP地址,例如192.168.33.100

http://www.intrapesite.ro/wp-content/uploads/2015/11/Captur%C4%83-de-ecran-de-la-2015-12-11-21-51-36.png

之后使用接收IP地址的docker端口转发。在docker撰写yaml时,语法为:

港口:
- “192.168.33.100:80:80”

需要使用指向domain_url的IP更新文件/etc/hosts。这种方式可以添加多个具有不同静态IP的网桥,只需修改每个docker项目的/ etc / hosts文件。

最后一个解决方案看起来最优雅。

答案 2 :(得分:1)

显然,我需要做的就是在我的/ etc / hosts文件中添加一行:

192.168.59.103 sub.mydomain.com

我可以在浏览器中找到该地址,并且可以正确解析子域。我仍然不明白这是如何受docker run -h选项的影响,但至少它是有效的。这不是非常可扩展的,因为我可能希望将来使用多个子域,并将它们全部路由到Web应用程序容器(根据子域提供不同的页面)。