2010-09-01 52 views
3

我有一個需要由乘客模塊nginx部署的rails應用程序。這個應用程序需要爲上百個域名提供服務。我沒有足夠的內存來啓動100個導軌實例。我不確定在少數情況下啓動rails的正確方法。這是不同域名下的相同應用程序。多個域名的一個rails應用程序

server { 
    listen 80; 
    server_name www.a_domain.com; 
    root /webapps/mycook/public; 
    passenger_enabled on; 
} 
server { 
    listen 80; 
    server_name www.b_domain.com; 
    root /webapps/mycook/public; 
    passenger_enabled on; 
} 
server { 
    listen 80; 
    server_name www.c_domain.com; 
    root /webapps/mycook/public; 
    passenger_enabled on; 
} 

正如你可以上面的代碼,它會啓動三個rails實例。如果只啓動實例在這3個域下進行服務將會很好。任何人都有一些建議?

回答

7

只需爲該服務器條目設置多個域別名即可。

server { 
    listen 80; 
    server_name www.a_domain.com www.b_domain.com www.c_domain.com; 
    root /webapps/mycook/public; 
    passenger_enabled on; 
} 

這將爲這些域中的每個域提供請求,並且所有域都會訪問同一個應用程序池。

+1

+1設置多個別名並讓你的Rails應用程序檢測應執行哪一個檢查主機變量。 – 2010-09-01 19:18:28

+0

感謝您的評論。 – Chamnap 2010-09-02 10:49:52

+0

我們完全按照克里斯描述的方式完成了Simone的建議,並且它工作正常。 – pjmorse 2010-10-18 11:55:10

0

我在Chris的回答中提到您可以在server_name中使用通配符和正則表達式,並且這些將會傳遞給您的rails實例。

server_name *; # handle requests from all domains 

有四種方法可以在你的Rails應用程序中使用它(我知道這一點)。

「內容的大包」方法

什麼都不做

如果你讓Nginx的把所有的域相同的Rails應用程序,他們都得到了相同的內容。在這種情況下,www.abc.com和www.xyz.com可以訪問相同的數據。這是最容易做到的,因爲你什麼都不做。

此解決方案的侷限性在於您希望讓域具有不同的內容。例如,如果www.abc.com/about和www.xyz.com/about應該是不同的頁面,那麼它就會變得棘手。

的「幕後的那個人」方法

使用的Nginx的「改寫」

在某些情況下,你可以讓Nginx的重寫域名成子域,並傳遞到您的Rails應用程序。例如:

server_name *; # handle requests from all domains 
rewrite ^(?:www.)?([^.]*)\..*$ $1.yourdomain.com last; 

該正則表達式需要一點解釋。它只是說從任何這些獲得xyz:www.xyz.com,xyz.com,xzy.co.uk,www.xyz.co.uk.重寫將這些請求中的任何一個更改爲xyz.yourdomain.com。

這樣做的好處是Nginx很快就做到了這一點,rails應用程序直到以後纔會涉及,並且請求的內容可以限制在子域。例如,Page.where(subdomain: request.subdomain, permalink: params[:permalink])

雖然這是相當嚴格的,因爲它意味着子域名和域名必須相同。也許這對你的應用程序來說是一個問題,可能不是。但是,儘管我在此子域中使用了$1,但您可以輕鬆地將其作爲url中的參數插入。例如,yourdomain.com/$1會將來自www.xyz.com的請求重寫到yourdomain.com/xyz。

此問題的另一個問題是「幕後男子」。雖然用戶訪問www.xyz.com重寫意味着他們會在地址欄中看到xyz.yourdomain.com。

的「Rails的路」法

在ApplicationController中

使用Rails的請求對象,你可以使用你的應用程序控制器範圍使用Rails的request對象域名相關的內容。

在本例中,我們將使用ApplicationController來查找與域名關聯的用戶帳戶。假設你有一個用戶模型與domain_name屬性:

def domain_user 
    @domain_user ||= User.where(domain_name: request.domain()).take 
end 

Redis的可用於如果附加命中你的數據庫中創建一個性能障礙緩存這些查找。到目前爲止,我的應用還沒有達到這一點。

這個解決方案的弱點是,雖然查找可能會發現www.xyz.com,它會錯過xyz.com。爲了適應這種情況,我們可以使用一些正則表達式:

def domain_user 
    request.domain.match /(?:www.)?(.*)/ 
    @domain_user ||= User.where(domain_name: $1).take 
end 

這個正則表達式去掉www。如果它存在。剩下的就成了域名(我們在$1裏爲我們存儲紅寶石)。

與Nginx重寫解決方案不同,如果用戶訪問www.xyz.com,那麼他們在地址欄中仍然可以看到。

使用路由約束

的「對我不起作用」法

另外,Rails的3及以上的有約束的,存在於產生路由表半動態的路由文件的功能。我說「半動態」,因爲路由表是在應用程序啓動時生成的。如果用戶模型(在我們的示例中)發生變化,則需要特別注意重建路由表。對於分佈在多個服務器上的應用程序,這可能難以管理,儘管people have done it

到目前爲止,我的所有應用程序最終(如果不是最初的話)都使用ApplicationController解決方案,因爲它實際上是最乾淨和最容易實現的。從MCV的角度來看,這也很有意義。

相關問題