Ошибки Rails и FastCGI

Здесь я кратко опишу основные ошибки, которые могут возникнуть при размещении Rails-приложения на fcgi и методы их решения. Основные симптомы нижеописанных ошибок:
  • Вместо приложения, отображается:
    • Содержимое файла dispatch.fcgi
    • 505 Rails application failed to start
  • В логе ошибок появляются строки вида:
    • [warn] mod_fcgid: Read data error, fastcgi server has close connection
    • [error] [client xxx.xxx.xxx.xxx] Premature end of script headers: dispatch.fcgi
  • Загрузка каждой страницы приложения занимает несколько секунд

CGI вместо FCGI

По умолчанию, в файле public/.htaccess используется CGI, а не FCGI. CGI более старая технология, требующая запуска нового процесса для обработки каждого запроса. Это значит, что для загрузки каждой страницы приложения будет создаваться новый экземпляр интерпретатора и загружаться весь фреймворк. А это весьма длительная процедура)) Для того, чтобы использовать FCGI необходимо найти в файле .htaccess строку
RewriteRule ^(.*)$ dispatch.cgi [QSA,L]
и заменить в ней dispatch.cgi на dispatch.fcgi

AddHandler

Существует два различных модуля Apache, предоставляющих функциональность FCGI: fastcgi и fcgid. fastcgi обычно используется в версии 1.x, в то время, как более новый fcgid в версии 2.x. По умолчанию, рельсы настроены чтобы использовать fastcgi, поэтому если Вы используете fcgid, приложение работать не будет. В частности, вместо него может отображаться содержимое файла dispatch.fcgi. Чтобы исправить это необходимо в файле .htaccess найти строку
AddHandler fastcgi-script .fcgi
И заменить ее на
AddHandler fcgid-script .fcgi

RAILS_ENV

Когда приложение запущено из-под FCGI, оно использует development среду. Для того, чтобы использовать production среду, необходимо в файле environment.rb раскомментировать строку
ENV['RAILS_ENV'] ||= 'production'

Ruby Executable

По умолчанию, файлы dispatch.cgi и dispatch.fcgi первой строкой содержат директиву #!..., соответствующие конфигурации машины, на которой было сгенерировано приложение. Соответственно, если на новом сервере расположение исполняемых файлов другое, то приложение не будет запущено. Необходимо проверить расположение исполняемых файлов руби и прописать в первой строке правильный путь. Например, у меня после исправления путь стал:
#!/usr/bin/ruby1.8

suexec

Приложение не будет запущено, если Apache не имеет соответствующих прав на директорию. Обычно это решается использованием suexec. Для этого в конфигурацию Apache добавляются строка:
SuexecUserGroup admin admin
Важно! При задании пользователя и группы в конфиге, имя пользователя должно совпадать с владельцем директории приложения, группа с группой директории. Проверить наличие ошибок можно, просмотрев лог suexec. Чтобы определить его местоположение необходимо вызвать suexec с параметром -V. Например, у меня это приводит к следующему выводу:
alno# suexec -V
-D AP_DOC_ROOT="/"
-D AP_GID_MIN=1000
-D AP_HTTPD_USER="www"
-D AP_LOG_EXEC="/var/log/httpd-suexec.log"
-D AP_SAFE_PATH="/usr/local/bin:/usr/local/bin:/usr/bin:/bin"
-D AP_UID_MIN=1000
После этого можно просмотреть лог на предмет ошибок. Иногда, приложение не запускается и в логе suexec появляются ошибки вида:
[2008-11-19 09:44:35]: directory is writable by others: (XXXXX)
Для решения этой прроблемы необходимо проверить что владельцем директории с приложением является пользователь, для которого делается SuExec, а group и others не имеют прав на запись в директорию. Чтобы оставить права на запись только владельцу, необходимо выполнить команду:
chmod -R go-w <app_dir>

Timeout

Иногда приложение не может запуститься и выводи 505 ошибку, если апач не дожидается момента запуска. В этом случае, лог ошибок содержит строку, подобную следующей:
[warn] mod_fcgid: read data timeout in 40 seconds
Для того, чтобы выделить приложению больше времени на запуск, необходимо в конфиге Apache прописать директиву TimeOut, увеличив значение ожидания, например, до 360 секунд:
TimeOut 360

 Подписаться на RSS

 #  #  #  #  #  #  #  #  #  #

Добавить комментарий