超絶シンプルなブログを作ろうとして逆算していくとRedmineが障壁になったのでRedmineを単独で動かすことにしました。
今までRedmineはPassengerを使ってApacheやNginxで動かして来ましたが、今回はunicornで動かすことにしました。unicornで動かすと言ってもポート80はウェブサーバで使うのでリバースプロキシで接続することになります。多くの場合Redmineはチーム内であったりして使う人が限られていると思うのでそれで多少パフォーマンスが落ちても問題ないと思っています。それよりも環境を独立して動かすことを優先するという形です。
- rbenvでrubyは入れる
- nginxからproxyでunicornに接続する
- Redmineはgitでいれる
- Redmineに必要なgemはvendor/bundleに入れる
- Redmineのデータベースはmysqlを使う
- RedmineはSubURI/redmineで公開する
これによりRedmine(Railsアプリ)の実行環境を完全に独立できます。OSに依存する部分は少ないですがDebian/Ubuntu向けの内容になります。基本的に最後の仕上げらへんのsudoコマンドを使っている部分を除いて一般ユーザでセットアップします。
rbenvをセットアップ
OS XならHomebrewでbrew install rbenv
で入れると楽です。aptはパッケージが古かったので直接入れることにします。
git clone git://github.com/sstephenson/rbenv.git ~/.rbenv git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.profile echo 'eval "$(rbenv init -)"' >> ~/.profile
Debian/Ubuntuなので.profileに書いています。rbenvのセットアップ詳細はrbenvを参照。
Redmineのruby環境をセットアップ
Redmineで使うrubyをインストールします。とりあえず1.9.xのこの時点の最新を使いました。
rbenv install 1.9.3-p392 ...
Bundlerのインストール
rbenv shell 1.9.3-p392 gem install bundler rbenv rehash
Redmineのインストール
どこにインストールしても問題ないです。~/redmineでも可。この時点の最新2.3を使いました。
git clone https://github.com/redmine/redmine redmine cd redmine git checkout -b release/2.3.0 2.3.0
Redmineの依存解決
データベースはmysqlを使うのでsqlite, postgresqlを除外します。--path vendoer/bundle
を設定しているのでRedmineで使うgemはそこにインストールされ他のRubyアプリケーションに影響させないようにします。
rbenv local 1.9.3-p392 bundle install --without development test rmagick sqlite postgresql --path vendor/bundle
データベースのセットアップ
例です。データベースユーザやパスワードはちゃんとしたものを使ってください。
mysql -u root -p create database redmine character set utf8; create user 'redmine'@'localhost' identified by 'redmine'; grant all privileges on redmine.* to 'redmine'@'localhost'; exit;
cp -p config/database.yml.example config/database.yml
config/database.ymlを編集します。
# mysql production: adapter: mysql2 database: redmine host: localhost username: redmine password: redmine encoding: utf8
Redmineのセットアップ
cd /path/to/redmine bundle exec rake generate_secret_token RAILS_ENV=production bundle exec rake db:migrate RAILS_ENV=production bundle exec rake redmine:load_default_data mkdir tmp tmp/pdf public/plugin_assets
Sub URIで動作させるためにconfig.ruを修正します。Root(/)で動かすならこの作業は不要です。
# This file is used by Rack-based servers to start the application. require ::File.expand_path('../config/environment', __FILE__) #run RedmineApp::Application if ENV['RAILS_RELATIVE_URL_ROOT'] map ENV['RAILS_RELATIVE_URL_ROOT'] do run RedmineApp::Application end else run RedmineApp::Application end
unicorn追加でインストール
cd /path/to/redmine echo 'gem "unicorn"' >> Gemfile.local bundle
unicorn設定ファイル
cd /path/to/redmine curl -o config/unicorn.rb https://raw.github.com/defunkt/unicorn/master/examples/unicorn.conf.rb
パスのみ変更してあとはデフォルトのままです。必要に応じて調整してください。
# See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete # documentation. APP_PATH = File.expand_path('../../', __FILE__) worker_processes 4 working_directory APP_PATH # available in 0.94.0+ listen "#{APP_PATH}/tmp/unicorn.sock", :backlog => 64 timeout 30 pid "#{APP_PATH}/tmp/unicorn.pid" stderr_path "#{APP_PATH}/log/unicorn.stderr.log" stdout_path "#{APP_PATH}/log/unicorn.stderr.log" preload_app true GC.respond_to?(:copy_on_write_friendly=) and GC.copy_on_write_friendly = true check_client_connection false before_fork do |server, worker| defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect! end after_fork do |server, worker| defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection end
unicorn実行
テスト実行。Root(/)で動かすなら--path /redmine
は不要です。
cd /path/to/redmine bundle exec unicorn_rails -c config/unicorn.rb -E production --path /redmine
nginx設定
config/unicorn.rbでリスニングしているunix socketに接続させます。
upstream redmine { server unix:/path/to/redmine/tmp/unicorn.sock; } server { ... location /redmine { root /path/to/redmine/public; if (-f $request_filename) { break; } proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://redmine; } ... }
仕上げ
問題なければ起動スクリプトを/etc/init.d/redmineに置いて実行。USER, APPPATH, URIPATHあたりを修正してください。
#! /bin/sh ### BEGIN INIT INFO # Provides: redmine # Required-Start: $all # Required-Stop: $network $local_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: starts the redmine web server # Description: starts redmine ### END INIT INFO USER=username APP_PATH=/path/to/redmine RAILS_ENV=production URI_PATH=/redmine SET_PATH="cd $APP_PATH" DAEMON="bundle exec unicorn_rails" DAEMON_OPTS="-c $APP_PATH/config/unicorn.rb -E $RAILS_ENV -D --path $URI_PATH" CMD="$SET_PATH; $DAEMON $DAEMON_OPTS" NAME=redmine DESC="Unicorn app for redmine" PID="$APP_PATH/tmp/unicorn.pid" OLD_PID="$PID.oldbin" cd $APP_PATH || exit 1 sig () { test -s "$PID" && kill -$1 `cat $PID` } oldsig () { test -s $OLD_PID && kill -$1 `cat $OLD_PID` } case ${1-help} in start) sig 0 && echo >&2 "Already running" && exit 0 su - $USER -c "$CMD" ;; stop) sig QUIT && exit 0 echo >&2 "Not running" ;; force-stop) sig TERM && exit 0 echo >&2 "Not running" ;; restart|reload) sig HUP && echo reloaded OK && exit 0 echo >&2 "Couldn't reload, starting '$CMD' instead" su - $USER -c "$CMD" ;; upgrade) sig USR2 && exit 0 echo >&2 "Couldn't upgrade, starting '$CMD' instead" su - $USER -c "$CMD" ;; rotate) sig USR1 && echo rotated logs OK && exit 0 echo >&2 "Couldn't rotate logs" && exit 1 ;; *) echo >&2 "Usage: $0 <start|stop|restart|upgrade|rotate|force-stop>" exit 1 ;; esac exit 0
sudo service redmine start sudo update-rc.d redmine defaults
起動時に動かすようにもしておきます。
その他
Redmineを初期セットアップ風に書いているけど実際は2.2->2.3のアップグレード。
Ruby 1.9にあげたらgem install activerecord-mysql-adapterというエラーになった。bundlerで依存関係解決しているのに・・・調べたらconfig/database.ymlのadapter: mysqlをadapter: mysql2にすると直った。
実は最初はpassenger-standaloneで進めていたがSubURIで動かせないという問題に遭遇した。proxy redirectで無理やり変換できそうだが面倒なのとunicornつかってみたかったので諦めた。ルートディレクトリで公開できるなら行けた。
- http://www.modrails.com/documentation/Users%20guide%20Standalone.html
- Phusion Passenger & running multiple Ruby versions
- Phusion Passenger Discussions › rails3 + standalone passenger in a /subdirectory
参考
- rbenvでRubyのバージョンを指定する方法
- Redmineテーマやプラグイン開発環境を構築する (RVM版)
- Unicorn
- Setting up Unicorn with Nginx
- etcinit.dunicorn_example.co.uk
This markdown is rendered by wp-gfm