redmineをunicorn+nginxで動かすためのchef用のCookbookです。http://t.nzk.me/entry/2012/12/28/144730で紹介されている手順を元に作成しています。
前提条件
-
OS: Ubuntu 12.04
-
DB: mysql
mysqlについては、chefにより自動的なインストールが可能ですが、このcookbookでは、mysqlパッケージ自体のインストールは含んでいません。mysqlのインストールについては、別のcookbookを使用する必要があります。
-
Redmine: 2.3.1
-
chef-solo
変更が必要なファイル
chef-repo/nodes/redmine.example.com.jsonを環境に合わせて編集してください。
download-urlについて
redmineパッケージをダウンロードするURLを指定します。
run_listについて
mysql::serverについては、このcookbookには含まれていません。以下のコマンドで事前にmysqlインストール用のcookbookを導入してください。
knife cookbook site install mysql
実行手順
chefを実行する端末から、OSインストール直後のサーバ(sshで接続出来る必要はあります)に対してredmineをインストールする場合、以下のコマンドでredmineの起動可能な状態まで自動的に設定されます(たぶん)。
knife solo prepare redmine.exampl.ecom
knife solo cook redmine.example.com
nginxとunicornの起動は以下の通りです。
sudo /etc/init.d/unicorn start
sudo /etc/init.d/nginx start
関連ファイル
-
chef-repo/nodes/redmine.example.com.json
インストールするホスト毎の設定ファイルです。
-
chef-repo/cookbooks/redmine-unicorn-nginx/recipes/default.rb
redmineパッケージをダウンロードし、インストールするためのレシピです。必要なパッケージも自動的に取得します。unicorn及びnginxのインストール、設定も行いますが、mysqlパッケージのインストールは含まれていないため、事前に別のcookbookを用意する必要があります。
-
chef-repo/cookbooks/redmine-unicorn-nginx/templates/default/database.yml.erb
redmineがデータベースに接続するための設定ファイルです。mysqlを前提としています。
-
chef-repo/cookbooks/redmine-unicorn-nginx/templates/default/initd_unicorn.erb
uncornを起動するための設定ファイルです。http://www.mk-mode.com/octopress/2013/01/23/unicorn-start-script/を参考にさせて頂きました。
-
chef-repo/cookbooks/redmine-unicorn-nginx/templates/default/nginx.conf.erb
nginxの設定ファイルです。
-
chef-repo/cookbooks/redmine-unicorn-nginx/templates/default/virtual.vconf.erb
nginxの設定ファイルです。
-
chef-repo/cookbooks/redmine-unicorn-nginx/templates/default/unicorn.rb.erb
unicornの設定ファイルです。
{
"mysql": {
"server_root_password": "password",
"server_repl_password": "password",
"server_debian_password": "password"
},
"redmine": {
"db_user": "redmine",
"db_server": "localhost",
"db_password": "password",
"download-url": "http://rubyforge.org/frs/download.php/76933/redmine-2.3.1.tar.gz"
},
"nginx": {
"server_name": "redmine.example.com"
},
"run_list": [
"mysql::server",
"mysql::client",
"redmine-unicorn-nginx"
]
}
# -*- coding: utf-8 -*-
execute "echo \"CREATE DATABASE redmine character set utf8\" | mysql -u root -p#{node['mysql']['server_root_password']}" do
returns [0, 1]
end
execute "echo \"CREATE USER '#{node['redmine']['db_user']}'@'#{node['redmine']['db_server']}' IDENTIFIED BY '#{node['redmine']['db_password']}'\" | mysql -u root -p#{node['mysql']['server_root_password']}" do
returns [0, 1]
end
execute "echo \"GRANT ALL PRIVILEGES ON redmine.* to #{node['redmine']['db_user']}\" | mysql -u root -p#{node['mysql']['server_root_password']}"
# ruby 1.9.3で動作させる場合の設定です。必須ではありません。
# apt_package "ruby1.9.3" do
# action :install
# end
# execute "" do
# command <<-EOH
# update-alternatives --install /usr/bin/ruby ruby /usr/bin/ruby1.9.3 500 \
# --slave /usr/bin/ri ri /usr/bin/ri1.9.3 \
# --slave /usr/bin/irb irb /usr/bin/irb1.9.3 \
# --slave /usr/bin/erb erb /usr/bin/erb1.9.3 \
# --slave /usr/bin/rdoc rdoc /usr/bin/rdoc1.9.3
# EOH
# end
# execute "update-alternatives --set ruby /usr/bin/ruby1.9.3"
base_name = File.basename(node['redmine']['download-url'])
remote_file "redmine-archive" do
source "#{node['redmine']['download-url']}"
path "/usr/local/#{base_name}"
not_if do
File.exists?("/usr/local/#{base_name}")
end
end
execute "tar zxvf #{base_name}" do
cwd "/usr/local"
end
dir_name = base_name.gsub(/^(.+?)(\.tar\.gz)|(\.zip)$/, "\\1")
link "/usr/local/redmine" do
to "/usr/local/#{dir_name}"
end
template "database.yml" do
path "/usr/local/redmine/config/database.yml"
end
apt_package "make" do
action :install
end
apt_package "ruby-dev" do
action :install
end
apt_package "rake" do
action :install
end
apt_package "libxml2-dev" do
action :install
end
apt_package "libxslt-dev" do
action :install
end
apt_package "libmagickwand-dev" do
action :install
end
# apt_package "graphicsmagick-libmagick-dev-compat" do
# action :install
# end
execute "gem install bundler" do
cwd "/usr/local/redmine"
end
execute "bundle install" do
cwd "/usr/local/redmine"
end
execute "bundle check" do
cwd "/usr/local/redmine"
end
execute "rake generate_secret_token" do
cwd "/usr/local/redmine"
end
execute "rake db:migrate" do
environment(
"RAILS_ENV" => "production"
)
cwd "/usr/local/redmine"
end
directory "/usr/local/redmine/public/plugin_asserts" do
mode 777
end
execute "gem install unicorn"
# /usr/local/redmine/Gemfileにgem "unicorn"の記述が無いと、unicornの起動に失敗するため、gem "unicorn"の記述を追加します。
ruby "adding unicron text into redmine/Gemfile." do
code <<-EOC
f = open("/usr/local/redmine/Gemfile", "r")
t = open("/tmp/redmine-uniconr-nginx-Gemfile.new", "w")
if f.grep(/^gem \"unicorn\"/).empty? then
f.seek 0
f.each do |line|
if line =~ /^source .+/ then
t.write line
t.write "gem 'unicorn'\n"
else
t.write line
end
end
end
f.close
t.close
EOC
end
execute "mv /tmp/redmine-uniconr-nginx-Gemfile.new /usr/local/redmine/Gemfile"
template "unicorn.rb" do
path "/usr/local/redmine/config/unicorn.rb"
end
apt_package "nginx" do
action :install
end
template "nginx.conf" do
path "/etc/nginx/nginx.conf"
end
template "virtual.vconf" do
path "/etc/nginx/conf.d/virtual.conf"
end
template "initd_unicorn" do
path "/etc/init.d/unicorn"
mode 755
end
# !/bin/sh
PATH=/bin:/usr/bin:/usr/local/bin
# move to project root directory
NAME=unicorn
ENVIROMENT=production
ROOT_DIR=/usr/local/redmine
PID="${ROOT_DIR}/tmp/pids/unicorn.pid"
CONF="${ROOT_DIR}/config/unicorn.rb"
start()
{
cd $ROOT_DIR
if [ -e $PID ]; then
echo "$NAME already started";
exit 1;
fi
echo "start $NAME";
bundle exec unicorn_rails -c ${CONF} -E ${ENVIROMENT} -D -p 5001
}
stop()
{
if [ ! -e $PID ]; then
echo "$NAME not started";
exit 1;
fi
echo "stop $NAME";
kill `cat ${PID}`
rm -f $PID
}
graceful_stop()
{
if [ ! -e $PID ]; then
echo "$NAME not started";
exit 1;
fi
echo "stop $NAME";
kill -QUIT `cat ${PID}`
rm -f $PID
}
reload()
{
if [ ! -e $PID ]; then
echo "$NAME not started";
start
exit 0;
fi
echo "reload $NAME";
kill -USR2 `cat ${PID}`
}
restart()
{
if [ ! -e $PID ]; then
echo "$NAME not started";
start
exit 0;
fi
echo "restart $NAME";
stop
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
graceful_stop)
graceful_stop
;;
reload)
reload
;;
restart)
reload
;;
*)
echo "Syntax Error: release [start|stop|graceful_stop|reload|restart]"
;;
esac
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
##
# nginx-naxsi config
##
# Uncomment it if you installed nginx-naxsi
##
#include /etc/nginx/naxsi_core.rules;
##
# nginx-passenger config
##
# Uncomment it if you installed nginx-passenger
##
#passenger_root /usr;
#passenger_ruby /usr/bin/ruby;
upstream redmine {
server 127.0.0.1:5001;
}
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
# mail {
# # See sample authentication script at:
# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
# # auth_http localhost/auth.php;
# # pop3_capabilities "TOP" "USER";
# # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
# server {
# listen localhost:110;
# protocol pop3;
# proxy on;
# }
#
# server {
# listen localhost:143;
# protocol imap;
# proxy on;
# }
# }
worker_processes 2
listen File.expand_path("tmp/sockets/unicorn.sock", ENV['RAILS_ROOT'])
pid File.expand_path("tmp/pids/unicorn.pid", ENV['RAILS_ROOT'])
timeout 60
preload_app true
stdout_path File.expand_path("log/unicorn.stdout.log", ENV['RAILS_ROOT'])
stderr_path File.expand_path("log/unicorn.stderr.log", ENV['RAILS_ROOT'])
GC.respond_to?(:copy_on_write_friendly=) and GC.copy_on_write_friendly = true
before_fork do |server, worker|
defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
old_pid = "#{server.config[:pid]}.oldbin"
if old_pid != server.pid
begin
sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
Process.kill(sig, File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
end
end
sleep 1
end
after_fork do |server, worker|
defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end
server {
listen 80;
server_name <%= node[:nginx][:server_name] %>;
access_log /var/log/nginx/redmine_access.log;
error_log /var/log/nginx/redmine_error.log;
proxy_connect_timeout 60;
proxy_read_timeout 60;
proxy_send_timeout 60;
# auth_basic "Secret Area";
# auth_basic_user_file "/home/www/rails/redmine/.htpasswd";
location / {
root /usr/local/redmine/public;
if (-f $request_filename){
break;
}
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://redmine;
proxy_redirect off;
}
}