1

我有一个多租户 Rails 应用程序,由 Heroku 在http://myapp.herokuapp.com托管。租户/帐户通过子域(和 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 指向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 顶点 IP 的 A 记录

clientdomain.com DNS

在 clientdomain.com 的 DNS 中,clientdomain.com(不带 www)被重定向到 www.clientdomain.com(不确定他们是如何做到的,但它似乎可以工作。)

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

当前状态

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
4

2 回答 2

6

您最好的选择是首先设置您的主域,如下所示:

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

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

$ heroku domains:add *.mydomain.com

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

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

$ heroku domains:add www.myclientdomain.com

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

CNAMEwww.myclientdomain.comproxy.mydomain.com

CNAME 将跟随proxy.mydomain.comheroku-appname.herokuapp.com解析到 Heroku IP。

那么你应该准备好了。

理想情况下,您会比手动添加域名更快地使用自定义域来吸引新客户,因此您需要自动化该步骤。使用 heroku api 和客户端,您可以在您的应用程序中以编程方式管理您的自定义域。

于 2012-05-05T02:52:31.217 回答
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完整的主机,而不仅仅是域组件。

于 2012-05-09T08:23:12.693 回答