Загрузка...
Linux
Новости, статьи, обсуждения, - все что связано с GNU Linux, FreeBSD, OpenBSD, Sun Solaris, Mac OS X и другими системами. Если вы интересуетесь данной темой - добро пожаловать в сообщество.
     

настройка rails сервера на ubuntu 10.04 server edition

17.08.10, 23:43
Автор ggg

Для того, чтобы начать разрабатывать приложение Ruby on Rails достаточно пары команд, которые можно найти на каждом втором rails-сайте в Интернет, а вот настройка Production-сервера для не так тривиальна и часто приходится выцеплять материал на эту тему из разных источников, буквально по крупицам. В этой статье мне хочется хочется описать настройку production-сервера "от и до" на основе наиболее популярного Linux-дистрибутива Ubuntu, чтобы выполнив набор шагов можно было получить в итоге настроенный сервер с возможностью простых релизов и системой контроля версий проекта.

Для начала определимся с оборудованием: предположим, что у нас имеется production-сервер со свережустановленной Ubuntu 10.04 доступный по ssh по адресу 192.168.56.10 (это адрес мы будем использовать в различных командах) и локальная машина с какой-нибудь Debian-based системой (Debian, Ubuntu, Kubuntu и т.п.). По большому счету ОС локальной машины не имеет значения, отличия будут только в способе установки пакетов. В этой статье внимание читателя не будет заостряться на проблеме настройки локальной машины, просто упомяну, что на ней должы присутствовать следующие программы:

  1. ruby on rails
  2. git
  3. sudo
  4. какой-нибудь текстовый редактор (vim, emacs, gedit, nano, kwrite и т.п.)

Выполняемы команды будут выделяться жирным шрифтом. Введем следующие обозначения:

  1. команды, выполняемые на сервере будут снабжаться префиксом prod$
  2. команды, выполняемые на локальной машине будут снабжаться префиксом local$
  3. команды, выполняемые в PostgreSQL-коносоли на production-севрере будут снабжаться префиксом postgres=#
  4. если текст выделен жирным шрифтом, но не содержит ни одного из префиксов, то он является содержимым текстового файла

При настройке системы будут использоваться следующие инструменты:

  1. Ruby EE - серверная версия Ruby, которая работает быстрее и при этом расходует меньше памяти.
  2. Git - распределённая система управления версиями файлов. Проект был создан Линусом Торвальдсом для управления разработкой ядра Linux
  3. Apache - один из наиболее распространенных web-серверов
  4. Passanger - так же известное как mod_rails и mod_rack средство, позволяющее запускать rails приложения с помощью сервера Apache и Nginx.
  5. PostgreSQL - свободная объектно-реляционная система управления базами данных
  6. Capistrano - утилита для развертывания rails-приложений
Итак, приступим. Подключим дополнительный репозиторий для получения более свежей версии rubygems и нстановим необходимые пакеты на production-сервере:
prod$ sudo apt-get update
prod$ sudo apt-get install python-software-properties
prod$ sudo add-apt-repository ppa:maco.m/ruby
prod$ sudo apt-get update
prod$ sudo apt-get install git-core apache2 rubygems1.8 postgresql postgresql-server-dev-8.4 build-essential ruby1.8-dev libopenssl-ruby apache2-prefork-dev libapr1-dev libaprutil1-dev
prod$ sudo dpkg -i ruby-enterprise_1.8.7-2010.02_i386_ubuntu10.04.deb

На production-сервере дописываем в файл /etc/profile строчку (чтобы были доступны команды типа rails, rake и т.п.):
PATH=$PATH:/var/lib/gems/1.8/bin

И выполняем команду:
prod$ . /etc/profile

чтобы обновить конфигурацию текущей сессии bash (альтернатива данной команды - перелогиниться). Установим необходимые gem-ы на production-сервер:
prod$ sudo gem install rails
prod$ sudo gem install postgres
prod$ sudo gem install passenger

Добавляем символьную ссылку на rake в каталог /usr/bin чтобы команда rake была доступна всем пользователям (без этого у меня были проблемы при развертывании приложения):
prod$ sudo ln -s /var/lib/gems/1.8/bin/rake /usr/bin/rake

Устанавливаем нативное расширение passenger для Apache:
prod$ sudo `which passenger-install-apache2-module`

Если скрипт найдет какие-то недостающие зависимости, то любезно сообщит об этом и расскажет как их нужно доустановить, а также расскажет как писать конфигурационные файлы с поддержкой rails-приложений для Apache. Создаем файл /etc/apache2/mods-available/passenger.load с таким содержимым:
LoadModule passenger_module /usr/local/lib/ruby/gems/1.8/gems/passenger-2.2.14/ext/apache2/mod_passenger.so
PassengerRoot /usr/local/lib/ruby/gems/1.8/gems/passenger-2.2.14
PassengerRuby /usr/local/bin/ruby

И подключаем модуль командой:
sudo a2enmod passenger
После этого Apache будет без нашего участия определять, использует ли приложение Ruby on Rails и автоматически подгружать все что нужно для комфортной жизни.
В нашей конфигурации будет два пользователя: commiter и rails, причем доступ к репозиторию проекта имеют оба пользователя, а релизить может только rails. Создадим необходимых пользователей:
prod$ sudo adduser rails
prod$ sudo adduser commiter
Apache будет работать от имени пользователя rails, для этого меняем настройки в файле /etc/apache2/envvars:
export APACHE_RUN_USER=rails
Создадим папку для развернутой версии нашего проекта и назначим ей правильных владельца и группу:
prod$ sudo mkdir /var/www/project
prod$ sudo chown -R rails.www-data /var/www
Настроим профиль нашего проекта в Apache: добавим файл /etc/apache2/sites-available/project следующего содержания:
NameVirtualHost *:80
< VirtualHost *:80>
  ServerName 192.168.56.10
  DocumentRoot /var/www/project/current/public
< /VirtualHost>
Активируем созданную конфигурацию командой:
prod$ sudo a2ensite project
Ruby on Rails активно использует модуль Apache, который называется ModRewrite, поэтому перед тем как выполнять дальнейшие действия необходимо убедиться в том, что ModRewrite включен на нашем сервере, для этого выполним следующую команду (если ModRewrite отключен, то он будет активирован):
prod$ sudo a2enmod rewrite
В конфигурации Apache по-умолчанию активирован тестовый vhost. Поскольку в дальнейшей работе нам он не понадобится - отключим его с помощью команды

prod$ sudo a2dissite default
Для того, чтобы сделанные изменения вступили в силу перезагрузим Apache командой

prod$ sudo /etc/init.d/apache2 restart
Теперь пришло время настроить git репозиторий. Создадим группу git, пользователи которой смогут пользоваться git-ом:
prod$ sudo groupadd git
Добавляем в эту группу наших пользователей:
prod$ sudo usermod -a -G git rails
prod$ sudo usermod -a -G git commiter
Добавим папку репозитория:
prod$ sudo mkdir -p /home/repo/project.git
Инициализацию папки выполняем от пользователя rails:
prod$ su rails
prod$ cd /home/repo/project.git
prod$ git init --bare --shared
Немного поясню про опции команды инициализации:
  • --bare - создать репозиторий без рабочей директории
  • --shared - добавляет правильные права на запить в репозиторий для группы пользователей (чтобы коммиты от пользователей группы git обрабатывались корректно)
Поменяем владельца и группу у файлов репозитория:
prod$ sudo chown -R rails:git /home/repo/project.git
Создаем базу данных и пользователя для для доступа к этой базе (для того, чтобы оперировать с пользователями нужно открыть postgresql консоль от имени пользователя postgres):
prod$ sudo su postgres
prod$ psql
postgres=# create user project_user with password '123456';
postgres=# create DATABASE project;
postgres=# grant all privileges on database project to project_user;
После того как большинство настроек production-сервера произведено перейдем на локальную машину и создадим новый rails проект:
local$ rails project -d postgresql
Добавляем контроль версий в только что созданный проект:
local$ cd project
local$ git init
В rails-приложении есть ряд файлов, которые не жетально добавлять в репозиторий (логи, настройки базы данных, временные файлы), поэтому мы создадим файл .gitignore с таким содержимым:
log/*.log
tmp/**/*
log/*.pid
log/call_*
db/schema.rb
db/*.bkp
db/*.sqlite3
.DS_Store
*.swp
*~
index/**/*
config/database.yml
config/s3.yml
config/mail_servers.yml
config/backup_fu.yml
config/billing_on_rails.yml
После этого добавим первый коммит в наш локальный репозиторий:
local$ git commit -a -m "Initial commit."
Для того, чтобы убедиться что мы корректно настроили базу данных и rails приложение может его использовать добавим тестовую модель Post и немного логики для работы с ней:
local$ ./script/generate scaffold post title:string body:text
local$ git add .
local$ git ci -a -m 'posts scaffold added'
На данном этапе у нас есть простое приложение, использующее базу данных, мы можем опубликовать его на сервере. Сначала "запушим" его на наш сервер:
local$ git remote add origin ssh://commiter@192.168.56.10/home/repo/project.git
local$ git push origin master
Добавим поддержку Capistrano:
local$ sudo gem install capistrano
local$ capify .
После этого у нас создадутся два файла ./Capfile и ./config/deploy.rb. Для настройки параметров развертки приложения необходимо отредактировать второй из них. Приведу пример конфигурации с небольшими комментариями:

set :application, "project" # название приложения
set :user, "rails" # пользователь под которым будет происходить деплой
set :use_sudo, false # не использовать команду sudo при деплое
set :local_repository,  "ssh://rails@192.168.56.10/home/repo/project.git" # путь до репозитория
set :repository,  "/home/repo/project.git" # путь до репозитория
set :deploy_to, "/var/www/#{application}" # путь, куда будет разворачиваться приложение
set :deploy_via, :export
set :scm, :git # система контроля версий
set :git_enable_submodules, 1 # использовать git сабмодули, если вы не используете сабмодули - то данная строка все равно не помешает
set :port, 22 # ssh-порт сервера
server "192.168.56.10", :app, :web, :db, :primary => true
namespace :deploy do
  desc "Restart Application"
  task :restart, :roles => :app do
    run "touch #{current_path}/tmp/restart.txt"
  end
  desc "Make symlink for database.yml" 
  task :symlink_dbyaml do
    run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml" 
  end
  desc "Create empty database.yml in shared path" 
  task :create_dbyaml do
    run "mkdir -p #{shared_path}/config" 
    put '', "#{shared_path}/config/database.yml" 
  end
  deploy.task :start do 
    # nothing 
  end 
end
after 'deploy:setup', 'deploy:create_dbyaml'
after 'deploy:update_code', 'deploy:symlink_dbyaml'
after "deploy", "deploy:cleanup"
Добавим новые файлы в наш локальный репозиторий и запушим на удаленный:
local$ git add .
local$ git ci -a -m 'capistrano support added'
local$ git push origin master
А теперь создадим служебные папки проекта на сервере с помощью команды:
local$ cap deploy:setup
Данная команда создаст директории /var/www/project/shared и /var/www/project/releases, куда будут помещаться соответственно общие файлы для всех релизов проекта project (такие как логи и настройки базы данных) и файлы специфичные для каждого релиза (исходный код приложения). На каждую публикцию Capistrano создает отдельную папку, чтобы в случае неудачного релиза всегда можно было бы откатиться на предыдущий или на любой другой релиз. Одним из важных файлов конфигурации, который необходимо отредактировать, является /var/www/project/shared/config/database.yml. В нашем случае настройки будут следующими:
production:
  adapter: postgresql
  encoding: unicode
  database: project
  pool: 5
  username: project_user
  password: 123456
  host: 127.0.0.1
После того как конфигурация базы задана выполняем команду:
local$ cap deploy:cold
И на этом разворачивание нашего приложения заканчивается. Чтобы посмотреть что приложение работает как надо можно перейти по адресу http://192.168.56.10/posts в браузере.
Для дальнейших коммитов процесс разворачивания выглядит следующим образом:
  1. коммитим в локальный репозиторий
  2. пушим ветку master на наш production-сервер
  3. на локальной машине выполняем команду cap deploy (или cap deploy:migrations если добавились новые миграции).
P.s. буду рад отзывам, исправлениям и дополнениям к данной статье в комментариях.

Комментарии

надо попробовать, спасибо !

приятно видеть, что статья кому-то пригодилась, не зря старался =)

И мне пригодилась, спасибо)

Еще важно, чтобы работала команда
local$ rake test
Для этого у локального пользователя должны быть права для создания баз данных.
Полезно написать как это сделать.

это уже настрока локальной машины, а не сервера, т.е. если кто-то в комментах для конкретной системы это спросит – я напишу

Кстати, сейчас уже по умолчанию устанавливается rails 3.0. :)
В итоге имеем:


$ sudo gem install rails
ERROR: Error installing rails:
i18n requires RubyGems version >= 1.3.6

На моей памяти Rubygems из репозитория всегда отставало от жизни. Необходимо устанавливать свежие rubygems непосредственно с http://rubygems.org/pages/download.

ставить из сырков – не наш метод:

sudo add-apt-repository ppa:maco.m/ruby
sudo aptitude update
sudo aptitude upgrade

и RubyGems 1.3.7 будет установлен

добавил это в статью

Andrey Chernih 7 ноября 2010, 23:34
1

На продакшне всё-таки лучше ставить Ruby Enterprise Edition (ree), который побыстрее обычного руби будет.

Да, все верно, обновил статью

вот две полезные ссылки в нагрузку:
https://github.com/jnstq/rails-nginx-passenger-ubuntu
https://github.com/jnstq/munin-nginx-ubuntu

а насколько сильно данный манул будет отличатся для debian 6.0

думаю не очень, в debian-е насколько я помню, разве что ppa репозиториев нет (хотя могу и в этом ошибаться)

prod$ sudo chown -R rails:git /home/repo/project.git
Инициализацию папки выполняем от пользователя rails:
prod$ su rails
prod$ cd /home/repo/project.git
…………..
………..

Поменяем владельца и группу у файлов репозитория:
prod$ sudo chown -R rails:git /home/repo/project.git

для чего два раза дублировать права на папку для rails:git

первая команда была действительно лишней, убрал

для наглядности разбейте статью на разделы и подразделы.

ок, разобью на разделы в ближайшее время

я вот думаю, добавить ли в статью информацию по настройке RVM или не стоит?

виду того что статья о настройке production-сервера, мне кажется RVM лишним

да, наверное вы правы
кстати, я смотрю от вас достаточно много интересных комментариев, не хотите присоединиться к сообществу?

по подробнее о сообществе.

после регистрации не надо будет каждый раз вводить капчу, да и можно будет свои посты писать…

аноним 15 мая 2011, 13:12
0

по-моему предпочительнее использовать bundler вместо установки gem-ов вручную, было бы неплохо освятить эту тему в статье

да, наверное так и сделаю как только найду чуть-чуть свободного времени

http://blog.lunarlogicpolska.com/2013/setup-fresh-ubuntu-server-for-ruby-on-rails/ – наткнулся на более свежую статейку, пока что особо сильно не смотрел

Войдите, чтобы оставить комментарий