Одно приложение для нескольких доменных имен - PullRequest
4 голосов
/ 01 сентября 2010

У меня есть одно приложение для рельсов, которое необходимо развернуть с помощью пассажирского модуля nginx Это приложение должно быть подано на сотню доменных имен. У меня недостаточно памяти для запуска сотен экземпляров 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 доменах. У кого-нибудь есть предложения?

Ответы [ 2 ]

9 голосов
/ 01 сентября 2010

Просто настройте несколько псевдонимов домена для этой записи сервера.

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

Это будет обслуживать запросы к каждому из этих доменов, и все они попадут в один и тот же пул приложений.

0 голосов
/ 05 февраля 2015

В комментариях к ответу Криса я упоминал, что вы можете использовать подстановочные знаки и регулярные выражения в имени_сервера, и они будут переданы вашему экземпляру rails.

server_name *;  # handle requests from all domains

Существует четыре способа использования этого вваше Rails-приложение (о котором я знаю).

Метод "Big Bag of Content"

Ничего не делать

Если вы просто разрешите Nginx отправлять все домены наодно и то же приложение, они получают одинаковое содержимое.В этом случае 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 Way"

Использование объекта запроса Rails вApplicationController

Вы можете использовать свой контроллер приложений для выделения содержимого, связанного с доменным именем, используя объект Rails 'request.

В этом примере мы будем использовать ApplicationController для поискаучетная запись пользователя, связанная с именем домена.Предполагая, что у вас есть модель User с атрибутом 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 и выше имеют ограничения, функции, которые существуют в вашем файле маршрутов, которые генерируют маршрутизациюстол полудинамически.Я говорю «полудинамически», потому что таблица маршрутизации генерируется при запуске приложения.Если модель User (в нашем примере) изменяется, особое внимание следует уделить перестройке таблицы маршрутов.Для приложений, распределенных по нескольким серверам, это может стать громоздким для управления, хотя люди сделали это .

Пока что все мои приложения в конечном итоге, если не изначально, использовали решение ApplicationControllerпотому что он оказался самым чистым и легко реализуемым.Это также имеет большой смысл с точки зрения MCV.

...