rails4.xを使って新規プロジェクトを作成する際に、毎回行う定型作業が面倒なので、スクリプトベースで記載します。環境はnginx+unicornです。Apache用ではないので注意してください。
やっている事は下記の通り。環境固有のパラメータは一番最初に設定する環境変数に集約しておいたので、環境に合わせて内容は書き換えてください。
- プロジェクト名やMySQLのパスワードを環境変数にセットする
- MySQLのDB作成
- Railsプロジェクトの作成
- gitによるバージョン管理対象にする
- database.ymlにDB名、DBパスワードをセットする
- capistranoを入れる
- unicornの設定
- サービスの登録
大抵の場合には、railsアプリケーションを作成する場合には、rails serverコマンドで3000番ポートで起動させながらアプリケーションを作成すると思いますが、外部公開していないようなサーバだと、ちょこっと開発して、そのまま運用に載せてしまう場合もあるので、(先輩諸兄からは怒られそうですが)動かしながら適宜修正する為に、こんな感じでセットアップしてしまう事も有ります。自分用のオリジナルのスクリプトは全部1ファイルにまとまっていますが、BLOGへ載せるために、わざと大項目毎にタイトルをつけて載せています。
環境変数を設定する
# RAILSのバージョン指定。 # gemを使っているとRCとかが設定される事があるので、明示的に。 RAILS_VERSION=_4.1.8_ # MySQLのルートパスワード。DB作成時にのみ使用 MYSQL_ROOT_PASS=mysql_root_password # アプリケーション名。ドメイン指定ではなく、testapp等が一般的かも APPNAME=testapp.senritu.net # 作成しようとしているアプリケーションでのみ使用するDBパスワードは # opensslでランダムに作成する。 APP_DB_PASS=`openssl rand -hex 10` # rails newするディレクトリ。 # /var/www/testapp.senritu.netを作成したい場合には、下記のように指定。 WEB_ROOT=/var/www # ドットをアンダースコアに変更してDBNAME変数を設定 DBNAME=`echo $APPNAME | sed -e "s/\./_/g"` # DBのユーザー名。あまり長いとエラーとなるので注意 DB_USER_NAME=`echo $APPNAME | sed -e "s/\..*//g"` # 開発者のアカウント(単純にパーミッションつけるときに使う) # $USERは、ログインしたユーザー名が入っている環境変数 EDIT_USER=$USER WEB_ACCOUNT=www-data
DBをセットアップする。
# 同名のデータベースがあれば削除(間違って削除しないように注意!!!) mysql -uroot -p$MYSQL_ROOT_PASS -e \ "drop database if exists $DBNAME;" # utf8でDB作成。テスト用DBは必要に応じて作成して mysql -uroot -p$MYSQL_ROOT_PASS -e \ "CREATE DATABASE $DBNAME character set utf8;" # アクセス権を設定する mysql -uroot -p$MYSQL_ROOT_PASS -e \ "grant all privileges on $DBNAME.* to '$DB_USER_NAME'@'localhost' identified by '$APP_DB_PASS';" # DBの再起動なしにアクセス権変更を有効にする mysql -uroot -p$MYSQL_ROOT_PASS -e \ "flush privileges;" # 動作確認。作成したDBが出来ているか確認しているだけ mysql -u$DB_USER_NAME -p$APP_DB_PASS -e \ 'show databases;'
Railsアプリケーションを作成してgitで管理できるようにする。
sudo rails $RAILS_VERSION new $APPNAME --database=mysql sudo chown -R $EDIT_USER:$WEB_ACCOUNT $APPNAME cd $WEB_ROOT/$APPNAME # コミットしておく git init git add . git commit -m 'first commit' # DBの設定値を反映しておく cd $WEB_ROOT/$APPNAME/config sed -i "s/username.*/username: $DB_USER_NAME/g" ./database.yml sed -i "s/password:$/password: $APP_DB_PASS/g" ./database.yml # _developmentと_productionはそのままでも良いですし、 # 下記のコマンドを叩いて、両方とも同じDBを見ても良いと思います。 # ちなみに、同じDBを見ているのは、開発機と本番機が物理的に違うので、 # DB名が同じ方が覚えやすいと言う事情でそうしています。 sed -i "s/_development//g" ./database.yml sed -i "s/_production//g" ./database.yml # コミット git commit -a -m 'database.yml is changed' # secrets.xmlの更新 sed -i "s/secret_key_base: [0-9a-f]+/secret_key_base: `bundle exec rake secret`/1" ./secrets.yml sed -i "s/secret_key_base: [0-9a-f]+/secret_key_base: `bundle exec rake secret`/2" ./secrets.yml
capistranoの初期セットアップをする。
capistranoは開発環境から本番環境へのデプロイを支援してくれるツールです。よって、『取りあえず動かしたい』場合には、ここに記載してある内容以上の設定は不要かと。デプロイ時の設定は環境毎に異なると思いますので、必要に応じて設定してください。
cd $WEB_ROOT/$APPNAME gem install capistrano source ~/.bash_profile # rails関係のパッケージを本パッケージ内に配置する bundle install git add vendor/bundle git commit -a -m 'bundle install --deployment' # capistranoの初期セットアップ cap install git add Capfile config/deploy* git commit -a -m 'capistrano first commit' echo "gem 'unicorn'" >> Gemfile bundle install
unicornの設定ファイルを用意する。
cat <<- __EOT__ >> $WEB_ROOT/$APPNAME/config/unicorn.rb worker_processes 2 working_directory("$WEB_ROOT/$APPNAME") listen File.expand_path("tmp/unicorn.sock", ENV['RAILS_ROOT']) pid File.expand_path("tmp/unicorn.pid", ENV['RAILS_ROOT']) preload_app true stdout_path "$WEB_ROOT/$APPNAME/log/unicorn.stdout.log" stderr_path "$WEB_ROOT/$APPNAME/log/unicorn.stderr.log" 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 __EOT__ git add $WEB_ROOT/$APPNAME/config/unicorn.rb git commit -a -m 'add unicorn.rb'
/etc/init.d/以下に格納するunicornのinitスクリプトから参照される設定ファイルを作成する。
このファイルを作成した後、UNICORN_OPTSで設定しているオプションがproductionになっているので、unicornを起動した際にはdevelopment環境として起動します。productionが良ければproductionに書き換えてからスクリプトを実行してください。
cat <<- __EOT__ | sudo tee -a /etc/default/unicorn_$APPNAME CONFIGURED=yes TIMEOUT=60 APP_ROOT=$WEB_ROOT/$APPNAME CONFIG_RB="\$APP_ROOT/config/unicorn.rb" PID=/run/unicorn_$APPNAME.pid SECRET_KEY_BASE=`bundle exec rake secret` UNICORN_OPTS="-E development -c $WEB_ROOT/$APPNAME/config/unicorn.rb -D" __EOT__
nginxの設定ファイルにunicornを呼び出す設定を追記する
設定内容は必要に応じて追記してください。
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default_bak cat <<- __EOT__ | sudo tee -a /etc/nginx/sites-available/default upstream $APPNAME { server unix:$WEB_ROOT/$APPNAME/tmp/unicorn.sock; } server { server_name $APPNAME; root $WEB_ROOT/$APPNAME; location / { proxy_pass http://$APPNAME; } } __EOT__
unicornの起動スクリプト
cat <<- __EOT__ | sudo tee -a /etc/init.d/unicorn_$APPNAME #!/bin/sh ### BEGIN INIT INFO # Provides: unicorn_$APPNAME # Required-Start: \$local_fs \$remote_fs # Required-Stop: \$local_fs \$remote_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: unicorn_$APPNAME initscript # Description: unicorn_$APPNAME ### END INIT INFO set -e NAME=unicorn_$APPNAME DESC="unicorn_$APPNAME web server" . /lib/lsb/init-functions if [ -f /etc/default/unicorn_$APPNAME ]; then . /etc/default/unicorn_$APPNAME fi DAEMON=/usr/bin/unicorn PID=$WEB_ROOT/$APPNAME/tmp/unicorn.pid run_by_init() { ([ "\${previous-}" ] && [ "\${runlevel-}" ]) || [ "\${runlevel-}" = S ] } exit_with_message() { if ! run_by_init; then log_action_msg "\$1 Not starting." fi exit 0 } check_config() { if [ \$CONFIGURED != "yes" ]; then exit_with_message "unicorn_$APPNAME is not configured (see /etc/default/unicorn_$APPNAME)." fi } check_app_root() { if ! [ -d \$APP_ROOT ]; then exit_with_message "Application directory \$APP_ROOT is not exist." fi } set -u case "\$1" in start) check_config check_app_root log_daemon_msg "Starting \$DESC" \$NAME || true if start-stop-daemon --start --quiet --oknodo --pidfile \$PID --exec \$DAEMON -- \$UNICORN_OPTS; then log_end_msg 0 || true else log_end_msg 1 || true fi ;; stop) log_daemon_msg "Stopping \$DESC" \$NAME || true if start-stop-daemon --stop --signal QUIT --quiet --oknodo --pidfile \$PID; then log_end_msg 0 || true else log_end_msg 1 || true fi ;; force-stop) log_daemon_msg "Forcing stop of \$DESC" \$NAME || true if start-stop-daemon --stop --quiet --oknodo --pidfile \$PID; then log_end_msg 0 || true else log_end_msg 1 || true fi ;; restart|force-reload) log_daemon_msg "Restarting \$DESC" \$NAME || true start-stop-daemon --stop --quiet --oknodo --pidfile \$PID sleep 1 if start-stop-daemon --start --quiet --oknodo --pidfile \$PID --exec \$DAEMON -- \$UNICORN_OPTS; then log_end_msg 0 || true else log_end_msg 1 || true fi ;; reload) log_daemon_msg "Reloading \$DESC" \$NAME || true if start-stop-daemon --stop --signal HUP --quiet --oknodo --pidfile \$PID; then log_end_msg 0 || true else log_end_msg 1 || true fi ;; reopen-logs) log_daemon_msg "Relopening log files of \$DESC" \$NAME || true if start-stop-daemon --stop --signal USR1 --quiet --oknodo --pidfile \$PID; then log_end_msg 0 || true else log_end_msg 1 || true fi ;; status) status_of_proc -p \$PID \$DAEMON \$NAME && exit 0 || exit \$? ;; *) log_action_msg "Usage: \$0 <start|stop|restart|force-reload|reload|force-stop|reopen-logs|status>" || true exit 1 ;; esac __EOT__
DBのマイグレーション
cd $WEB_ROOT/$APPNAME bundle install # 対象は、productionなり、environmentなり適宜修正してください。 RAILS_ENV=production rake db:migrate
起動する前にconfig/database.yml内のproductionに設定されているproduction環境のDBパスワードが環境変数となっています。productionのpassword:の行をコメントアウトすればdefaultに設定したパスワードが使用されます。環境変数に設置されたものを使いたい場合には、/etc/default/以下にあるunicorn用の設定ファイル中に環境変数を定義すれば良いと思います。
# 一番下の方にある vi $WEB_ROOT/$APPNAME/config/database.yml
追加したunicornサービスを起動させる
# Linux起動時に自動起動するように設定する sudo chmod +x /etc/init.d/unicorn_$APPNAME sudo update-rc.d unicorn_$APPNAME defaults # 今起動させてみる sudo service unicorn_$APPNAME start # ログはここで見る。 tail -f $WEB_ROOT/$APPNAME/log/*
同一サーバ上にあるgitサーバにコミットして、redmineと連携させる
# 下記、開発サーバとgitのリポジトリが存在するサーバが # 同一サーバである前提で設定を行っている。 # 別サーバにする場合には、別サーバでgitのセットアップを行ってください。 if [ ! -e /opt/git ]; then sudo mkdir /opt/git sudo chown $EDIT_USER:$GIT_GROUP /opt/git fi if [ ! -e /opt/git/$APPNAME ]; then mkdir /opt/git/$APPNAME cd /opt/git/$APPNAME git --bare init fi cd $WEB_ROOT/$APPNAME git remote add origin file:///opt/git/$APPNAME git push origin master git push --set-upstream origin master # redmineに設定するgitのリポジトリ情報 echo /opt/git/$APPNAME
Redmineの設定
redmineの初期セットアップはこちらを参照。以降は、Redmineの初期設定は終わっているものとしてその続きを記載する。
Redmineにログインして、新しいプロジェクトを作成する。
該当プロジェクトの設定>リポジトリ>新しいリポジトリを選択。
上記のような感じで、設定値を入力する。
該当プロジェクトのリポジトリを参照して、コミットされたファイル群が参照できればOK。
適当なページを作成して動かしてみる
cd $WEB_ROOT/$APPNAME rails generate scaffold testpage test:string suuzi:integer rake db:migrate # この$DBNAMEの環境変数、書いている途中で変数名が間違っていると気づきながらも書いていました。 sudo service unicorn_$DBNAME restart # 接続先のURLを表示 echo http://$APPNAME/tests/
hostsファイルに$APPNAMEとRails環境をセットアップしたIPアドレスの対を記載して、ウェブブラウザでechoコマンドで表示したURLにアクセスすればページが参照できると思います。