我正在创建一个类似于博客的应用程序,我们允许客户使用他们自己的自定义域名,如domainexample.com,因此每个不同的域都为相同的应用程序提供服务,但内容不同。
但是我很难弄清楚如何在生产服务器上设置这个。如果我的生产服务器有一个静态IP,那么我肯定可以在每个域上设置一个a记录到生产服务器的IP。
但是如果生产服务器没有一个静态的IP地址怎么办?例如,如果我们想把它托管在heroku或engineyard上?我在网上看到过一些需要使用重写规则的解决方案,但是它们需要重新启动服务器,并且不能在新用户注册时真正动态地添加和删除新域。有人知道让多个域访问一个rails应用程序的好解决方案吗?
2条答案
按热度按时间ktca8awb1#
Heroku并不是您唯一的选择。如果您能预测客户的域名,可以看看this。如果不能,Rails路由约束和上面链接的问题的公认答案的组合应该会让您达到您需要的目的。听起来您不想重新启动服务器--因此不需要编辑路由。您也可以将domains作为模型的一部分,或者在Web服务器层中使用URL重写。
在我看来,问题在于Rails在这里打破了它对配置的看法。有 * 许多 * 方法可以从多个域提供服务。这可能是一个内在的复杂性,但Rails指南至少可以记录一个可能的解决方案。
zd287kbt2#
如果您的客户只是将CNAME添加到您的域或创建A记录到您的IP,而您不处理这些自定义域的TLS终止,则您的应用将不支持HTTPS,如果没有HTTPS,您的应用将无法在这些自定义域上的现代浏览器中运行。
您需要在Web服务器前面设置一个TLS终止反向代理。此代理可以在单独的计算机上运行,但您也可以在Web服务器所在的同一台计算机上运行。
CNAME与A记录
如果您的客户希望将您的应用放在他们的子域上,例如
app.customer.com
,他们可以创建指向您的代理的CNAMEapp.customer.com
。如果他们想让你的应用在他们的根域上,例如
customer.com
,那么他们必须在customer.com
上创建一个指向你的代理IP的A记录。如何处理TLS终止?
要使TLS终止生效,您必须为这些自定义域颁发TLS证书。您可以使用Let 's Encrypt来实现这一点。您的代理将看到传入请求的
Host
头,例如app.customer1.com
或customer2.com
等,然后它将通过检查SNI来决定使用哪个TLS证书。可以将代理设置为自动为这些自定义域颁发和续订证书。在新自定义域的第一次请求中,代理将发现它没有合适的证书。它将要求“加密”提供新证书。"加密“将首先发出质询以查看您是否管理该域,由于客户已创建指向您的代理的CNAME或A记录,它告诉Let 's Encrypt您确实管理该域,并且它将允许您为其颁发证书。
要自动颁发和更新证书,我建议使用Caddyserver、greenlock.js、OpenResty(Nginx)。
这里发生了什么; Caddyserver监听443和80,它自动接收请求、颁发和更新证书,代理到后端的流量。
如何在后端处理
您的代理服务器正在终止TLS并将请求代理到您的后端。但是,您的后端并不知道请求背后的原始客户是谁。这就是为什么您需要告诉您的代理服务器在代理的请求中包含额外的标头以识别客户。只需添加
X-Serve-For: app.customer.com
或X-Serve-For: customer2.com
或原始请求的任何Host
标头即可。现在,当您在后端接收到代理请求时,您可以读取这个自定义头,并知道请求背后的客户是谁,您可以在此基础上实现您的逻辑,显示属于此客户的数据等。
更多
在您的代理服务器群前放置一个负载平衡器以提高可用性。您还必须使用分布式存储来处理证书和Let 's Encrypt挑战。如果出现故障,请使用AWS ECS或EBS进行自动恢复,否则,您可能会在半夜醒来重新启动机器或手动启动代理服务器。
如果你需要更多的细节,你可以DM我在Twitter @dragocrnjac