FreeBSD: Установка Redmine

Появилась задача установить на сервер под управлением FreeBSD 8.2 программу Redmine (веб сервер для управления проектами). Подробнее о программе можно прочитать на сайте производителя. Так как Redmine работает под ruby решил поставить все из портов. Соотвественно ruby – это passenger и база данных – mysql.

Выношу статью наверх по нескольким изменениям:
1- решил попробовать redmine не из портов, а через svn
2- как всегда некоторые изменения

Ну чтож – начнем. Перед установкой желательно уже установить и настроить apache и mysql.

Решил попробовать вместо mysql – mariadb (установка с рекомендациями). Кроме установки – все остальное не меняется.
!!! Не забываем менять кодировку по умолчанию !!!

Заходим в порты и производим установку пакета.

# cd /usr/ports/www/redmine
# make install clean

Ставится довольно приличное количество зависимых пакетов (если сервер новый).

Если мы хотим поставить не из портов – а через svn, то заходим в нужную директорию (например /usr/local/www) и запускаем

# svn co http://redmine.rubyforge.org/svn/trunk redmine

Также доставляем:
– ruby19(/usr/ports/lang/ruby19)
– ruby-gems(/usr/ports/devel/ruby-gems)
– ruby-iconv(/usr/ports/converters/ruby-iconv)
– ruby-mysql(/usr/ports/databases/ruby-mysql)
– postgresql-libpq++(/usr/ports/databases/postgresql-libpq++)
– ruby-rmagick(/usr/ports/graphics/ruby-rmagick)
и установим еще:

# gem19 install rails --version=2.3.14

После установки необходимо настроить базу данных. Создаем в mysql три базы данных:

CREATE DATABASE redmine CHARACTER SET utf8 COLLATE utf8_general_ci;
GRANT ALL PRIVILEGES on redmine.* to redmine_user@localhost identified by 'redmine_user_pass';

CREATE DATABASE redmine_development CHARACTER SET utf8 COLLATE utf8_general_ci;
GRANT ALL PRIVILEGES on redmine_development.* to redmine_development_user@localhost identified by 'redmine_development_user_pass';

CREATE DATABASE redmine_test CHARACTER SET utf8 COLLATE utf8_general_ci;
GRANT ALL PRIVILEGES on redmine_test.* to redmine_test_user@localhost identified by 'redmine_test_user_pass';

В папке config (все файлы Redmine по умолчанию ставятся в папку /usr/local/www/redmine) копируем

# cp database.yml.example database.yml

вводим данные и комментируем ненужные настройки – получаем файл вида

production:
  adapter: mysql
  database: redmine
  host: localhost
  username: redmine_user
  password: redmine_user_pass
  encoding: utf8

development:
  adapter: mysql
  database: redmine_development
  host: localhost
  username: redmine_development_user
  password: redmine_development_user_pass
  encoding: utf8

test:
  adapter: mysql
  database: redmine_test
  host: localhost
  username: redmine_test_user
  password: redmine_test_user_pass
  encoding: utf8

Заходим в директорию /usr/local/www/redmine и подготавливаем к запуску и заполняем базы данных

# rake generate_session_store
# RAILS_ENV=production rake db:migrate
# RAILS_ENV=production rake redmine:load_default_data

Если после rake generate_session_store выдало ошибку:

Some gems may need to be installed or updated.
Please run `bundle install --without development test`.

смело ввыполняем команду bundle install –without development test и терпиливо ждем – чтобы она правильно отработала. Если мы видим ошибки – то, скорее всего. вы не доставили нужные библиотеки (находим какие и смело доставляем).

Очередное исправление – запускать passenger будем не от именни пользователя www, а создадим для него отдельного пользователя:

# pw groupadd -n redmine -g 3000
# pw useradd -n redmine -u 3000 -g 3000 -d /usr/local/www/redmine -s /bin/sh -h -

и раздадим права

mkdir tmp public/plugin_assets
sudo chown -R redmine:redmine files log tmp public/plugin_assets
sudo chmod -R 755 files log tmp public/plugin_assets

и также webrick запустим от этого пользователя:

# su - redmine
$ ruby19 script/server webrick -e production

И тестируем используя веб сервер webrick (не рекомендуется использовать данное решение для работы – только для проверки работоспособности)

# ruby script/server webrick -e production

Проверяем – заходим на http://server:3000. Если все работает – переходим к следующему шагу.

Теперь необходимо подружить наш redmine с apache. Для этого проведем настройку apache – после последнего LoadModule вводим следующие данные:

LoadModule passenger_module /usr/local/lib/ruby/gems/1.8/gems/passenger-3.0.7/ext/apache2/mod_passenger.so

PassengerRoot /usr/local/lib/ruby/gems/1.8/gems/passenger-3.0.7
PassengerRuby /usr/local/bin/ruby18
# от имени какго пользователя запускать passenger
PassengerDefaultUser www
# ограничивают количество процессов/ресурсов потребляемых passenger`ом
PassengerMaxPoolSize 1
PassengerUseGlobalQueue on
PassengerMaxInstancesPerApp 1
# время простоя до выгрузки из памяти. по умолчанию 300 секунд
PassengerPoolIdleTime 43200

В связи с обновлениями программ и gem меняем пути. А также меняем пользователя (остальное остается без изменений):

PassengerRoot /usr/local/lib/ruby/gems/1.9/gems/passenger-3.0.11
PassengerRuby /usr/local/bin/ruby19
PassengerDefaultUser redmine

Теперь создаем еще один виртуальный хост

<VirtualHost server:*>
ServerAdmin serveradmin@email.ru
ServerName  server.name.ru 
DocumentRoot /usr/local/www/redmine/public 
<Directory "/usr/local/www/redmine/public/">
    AllowOverride all 
    Options Indexes ExecCGI FollowSymLinks
    Order allow,deny
    Allow from all
    </Directory>
ErrorLog /usr/local/www/redmine/log/error.log
LogLevel warn
CustomLog /usr/local/www/redmine/log/access.log combined   
ServerSignature Off
</VirtualHost>

Не забываем прописать хост в http.conf. Далее настраиваем непосредственно redmine. Заходим в папку public, копируем

# cp dispatch.cgi.example dispatch.cgi

правим

вместо
require "dispatcher"
пишем
require "/usr/local/www/redmine/vendor/rails/railties/lib/dispatcher.rb"

меняем права и даем возможность запуска

# chown www:www dispatch.cgi
# chmod 755 dispatch.cgi

Перегружаем apache и заходим http://server (по стандартному порту – 80). Заходим под аккаунтом администратора (admin/admin) и уже настраиваем непосредственно из веб интерфейса – добавляем пользователей/начинаем проекты.

PS при установке на debian/ubuntu не забываем поставить passenger (# apt-get install libapache2-mod-passenger)
http://www.redmine.org

Некоторые дополнения
Если необходимо – чтобы доступ в redmine был не в формате ‘http://server/’, а например ‘http://server/redmine’ – меняем настроки виртуального хоста (добавляем к уже имеющимся):

<VirtualHost *:80>
    ServerAdmin serveradmin@email.ru
    ServerName  server.name.ru
   .....
    RAILS_ENV=production -initial-env PATH=/usr/local/bin -processes 2
    PassengerAppRoot /usr/local/www/redmine
    RailsBaseURI /redmine
    Alias /redmine /usr/local/www/redmine/public
    <Directory /usr/local/www/redmine/public/>
        Order allow,deny
        Allow from all
        AllowOverride all
        Options +Indexes +FollowSymLinks +ExecCGI -MultiViews
    </Directory>
   .....
</VirtualHost> 

ну и на всякий случай – сделал линк папки public в папку виртуального хоста.

На форуме http://forums.freebsd.org пользователь royvandam выложил отличный скрипт для установки:

# Install required dependancies
echo "RUBY_VERSION=1.9.3" >> /etc/make.conf
cd /usr/ports/lang/ruby19
make install clean
cd /usr/ports/devel/ruby-gems
make install clean
cd /usr/ports/converters/ruby-iconv
make install clean
cd /usr/ports/databases/ruby-mysql
make install clean
gem19 install rails --version=2.3.14

# Install Redmin Trunk
mkdir /usr/local/www/ 
cd /usr/local/www/
svn co http://redmine.rubyforge.org/svn/trunk redmine
cd redmine

# Copy default Redmine configuration
cp config/configuration.yml.example config/configuration.yml
cp config/database.yml.example config/database.yml

# Configure Redmine according your environment and needs
# More detail is provided in the configuration files themselves.
vi config/configuration.yml
vi config/database.yml

# Generate a session store secret.
rake generate_session_store

# Create and populate database
rake db:migrate RAILS_ENV=production
rake redmine:load_default_data RAILS_ENV=production

# Create Redmine group and user
pw groupadd -n redmine -g 3000
pw useradd -n redmine -u 3000 -g 3000 -d /usr/local/www/redmine -s /bin/sh -h -

# Configure permissions
mkdir tmp public/plugin_assets
sudo chown -R redmine:redmine files log tmp public/plugin_assets
sudo chmod -R 755 files log tmp public/plugin_assets

# Login as Redmine user
su - redmine

# Test the configuration using Webrick
# (Note: Webrick is not suitable for normal use)
ruby19 script/server webrick -e production 

найти его можно здесь

Если возникает проблема при установки gem:

Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.
        /usr/local/bin/ruby19 extconf.rb 
checking for sqlite3.h... no

и при этом файл /usr/local/include/sqlite3.h существует – необходимо путь в переменных окружения прописать явно и продолжить установку

# export CONFIGURE_ARGS="with-sqlite3-include=/usr/local/include" && gem install sqlite3-ruby

Если возникает проблема при попытки использовать кирилицу:

ActionView::TemplateError (incompatible character encodings: ASCII-8BIT and UTF-8) on line #70 of app/views/layouts/base.html.erb:
67: 
68:     <div id="content">
69:         <%= render_flash_messages %>
70:         <%= yield %>
71:         <%= call_hook :view_layouts_base_content %>
72:         <div style="clear:both;"></div>
73:     </div>

Нашел два решения. Первое – добавляем в файл config/environment.rb

Encoding.default_internal = Encoding::UTF_8
Encoding.default_external = Encoding::UTF_8

И второе – добавляем в файл config/initializers/patches.rb

# Patching MySQL:
#
require 'mysql'

class Mysql::Result
def encode(value, encoding = "utf-8")
String === value ? value.force_encoding(encoding) : value
end

def each_utf8(&block)
each_orig do |row|
yield row.map {|col| encode(col) }
end
end
alias each_orig each
alias each each_utf8

def each_hash_utf8(&block)
each_hash_orig do |row|
row.each {|k, v| row[k] = encode(v) }
yield(row)
end
end
alias each_hash_orig each_hash
alias each_hash each_hash_utf8
end

# Patching ActionController:
#
module ActionController
class Request
private
def normalize_parameters_with_force_encoding(value)
(_value = normalize_parameters_without_force_encoding(value)).respond_to?(:force_encoding) ?
_value.force_encoding(Encoding::UTF_8) : _value
end
alias_method_chain :normalize_parameters, :force_encoding
end
end

Взято отсюда