为具有子域的自定义域和指向它们的CNAMES更正DNS设置

时间:2012-05-04 23:11:59

标签: ruby-on-rails heroku dns hosting

我有一个多租户Rails应用程序,在http://myapp.herokuapp.com以Heroku托管。租户/帐户通过子域(和Postgresql架构)分开。然后我将自己的域作为自定义域添加到Heroku应用程序中。由于Heroku真的建议不要使用A记录,因为“正常运行时间影响”(https://devcenter.heroku.com/articles/avoiding-naked-domains-dns-arecords)我首先尝试将自定义域中的CNAME记录放到myapp.herokuapp.com。对于像http://clientaccount.mydomain.com这样的子域名,这也很好。

当我的客户希望自己的域名指向其帐户以便http://www.clientdomain.com显示http://clientaccount.mydomain.com时,问题就出现了,最明显的解决方案似乎是在我的客户端DNS中创建CNAME记录以指向http://clientaccount.mydomain.com。这不起作用,当访问该地址时出现错误消息“该主机名没有配置应用程序”,同时host www.clientdomain.com给出了:

www.clientdomain.com is an alias for clientaccount.mydomain.com
clientaccount.mydomain.com is an alias for myapp.herokuapp.com
myapp.herokuapp.com is an alias for ar.herokuapp.com

在Heroku的一些非常困惑的支持之后,他们建议我使用A记录而不是指向他们的三个顶点IP。所以改了它但它仍然没有用。然后他们告诉我将我的客户域名添加为我的Heroku设置中的自定义域名,但我没有取得好成绩。

所以我目前的配置如下:

Heroku的Myapp有以下自定义域名:

*。mydomain.com www.clientdomain.com

mydomain.com DNS

* .mydomain.com有三条指向Heroku apex IPs的A记录

clientdomain.com DNS

在针对clientdomain.com的DNS中,clientdomain.com(没有www)被重定向到www.clientdomain.com(不确定他们是如何做到的,但似乎有效。)

对于www.clientdomain.com,有一条指向clientaccount.mydomain.com的CNAME记录

当前状态

www.mydomain.com正确解析。

clientaccount.mydomain.com正确解析。

www.clientdomain.com访问www.mydomain.com(没有子域名)

所以问题是在DNS中以某种方式显而易见,因为我的应用程序显然没有收到它,所以子域是否会在某处掉落?或者我是否必须更改Rails中的一些代码才能处理这个问题?

子域名作为路由约束处理,子域名类:

class Subdomain
  def self.matches?(request)
    request.subdomain.present? && Account.find_by_subdomain(request.subdomain)
  end
end

感谢任何输入!

修改

我已经做了所有建议,我是否也必须更改我的应用程序控制器?

application_controller.rb

def handle_subdomain
  if @account = Account.find_by_subdomain(request.subdomain)
    PgTools.set_search_path @account.id
    @current_account = @account
  else
    @current_account = nil
    PgTools.restore_default_search_path
  end
end

2 个答案:

答案 0 :(得分:5)

这里最好的选择是首先按如下方式设置您的主域名:

*.mydomain.com作为heroku-appname.herokuapp.com

的CNAME

并将*.mydomain.com作为域名添加到您的应用中:

$ heroku domains:add *.mydomain.com

下一步您需要为用户/客户设置一种简便的方法,将他们的自定义域添加到您的多租户应用中。这需要两件事,将域名添加到您的应用并让他们设置DNS。这是最好的方法:

www.myclientdomain.com添加到您的应用中:

$ heroku domains:add www.myclientdomain.com

然后设置DNS指向Heroku。你最好从Heroku的设置中吸取教训,让你的客户CNAME成为你拥有的域名。这有助于避免锁定,并让您更好地控制您指导流量的位置。这样:

CNAME www.myclientdomain.comproxy.mydomain.com

CNAME将跟随proxy.mydomain.comheroku-appname.herokuapp.com,然后解析为Heroku IP。

然后你应该全力以赴。

理想情况下,您将使用自定义域名吸引新客户,而不是手动添加域名,因此您需要自动执行该步骤。使用heroku api和客户端,您可以在应用程序中以编程方式管理自定义域。

答案 1 :(得分:2)

您需要执行以下操作:

def handle_subdomain
  if @account = Account.find_by_subdomain(request.subdomain) || Account.find_by_domain(request.domain)
    PgTools.set_search_path @account.id
    @current_account = @account
  else
    @current_account = nil
    PgTools.restore_default_search_path
  end
end

注意Account.find_by_domain(request.domain) - 尽管您可能需要request.host来获取完整主机,而不仅仅是域组件。