- 更新日: 2014年6月26日
- Rails
Capistrano3でRails4.1アプリケーションをデプロイ
先日 Capistrano3 を使って簡単なデプロイを試したのですけど、今回はもっと完璧にデプロイを行います。Bundler による gem インストール、DBマイグレーション、Unicorn 再起動などまでコマンド一発で自動で行えるように設定。
— 環境 —
rails 4.1
capistrano 3.2.1
事前にデプロイ先となる、staging, production などのサーバー環境を用意しておきます。また、Bitbucket のリポジトリと鍵設定をやっておく。以下参考。
Rails4.1 で staging 環境を用意する | EasyRamble
Capistrano3とBitbucketを使ってRailsアプリをデプロイ | EasyRamble
deploy 用スクリプトの書き方としては、一気に変更を追加するとはまることが多そうでしたので、少しずつ変更を追加しながら進めました。
1 2 3 4 |
$ bundle exec cap staging deploy:check $ bundle exec cap staging deploy |
上記コマンドの手順で、deploy に必要なファイル・ディレクトリが存在するかどうかをチェックしつつ、デプロイをこまめに試しつつ進めました。では以降、デプロイ設定で行った作業です。
Capistrano インストール
Gemfile
1 2 3 4 5 6 7 |
group :development do gem "capistrano" gem 'capistrano-rails' gem "capistrano-rbenv" gem 'capistrano-bundler' gem 'capistrano3-unicorn' end |
unicorn を使わない場合は、gem ‘capistrano3-unicorn’ の行は必要ありません。
bundle install と cap install。cap install で Capistrano3 でのデプロイに必要なファイルが作成されます。
1 2 3 4 5 6 7 8 9 10 |
$ bundle install $ bundle exec cap install mkdir -p config/deploy create config/deploy.rb create config/deploy/staging.rb create config/deploy/production.rb mkdir -p lib/capistrano/tasks Capified |
続いて、Capistrano インストールで作成されたファイルを実際のデプロイ用に編集していきます。
Capfile を編集
Capfile を編集。ここで、デプロイに必要な gems をインクルードします。
Capfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# Load DSL and Setup Up Stages require 'capistrano/setup' # Includes default deployment tasks require 'capistrano/deploy' # Includes tasks from other gems included in your Gemfile require 'capistrano/bundler' require 'capistrano/rails/assets' require 'capistrano/rails/migrations' require 'capistrano3/unicorn' # Loads custom tasks from `lib/capistrano/tasks' if you have any defined. Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r } |
unicorn を使わない場合は、require ‘capistrano3/unicorn’ の行は不要です。
deploy.rb デプロイ用スクリプトを作成
config/deploy.rb がデプロイのロジックを書く本体スクリプトとなります。以下のように編集。
config/deploy.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# config valid only for Capistrano 3.1 lock '3.2.1' set :application, 'app_name' set :repo_url, 'ssh://git@bitbucket.org/user_name/repo_name.git' # Default deploy_to directory is /var/www/my_app set :deploy_to, '/path/to/deploy_dir' # Default value for :scm is :git set :scm, :git # Default value for :linked_files is [] set :linked_files, %w{config/database.yml} # Default value for linked_dirs is [] set :linked_dirs, %w{log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system} # Default value for default_env is {} set :default_env, { rbenv_root: "/usr/local/rbenv", path: "/usr/local/rbenv/shims:/usr/local/rbenv/bin:$PATH" } # Default value for keep_releases is 5 set :keep_releases, 5 set :unicorn_rack_env, "none" set :unicorn_config_path, 'config/unicorn.rb' namespace :deploy do desc 'Restart application' task :restart do invoke 'unicorn:restart' end after :publishing, :restart after :restart, :clear_cache do on roles(:web), in: :groups, limit: 3, wait: 10 do # Here we can do anything such as: # within release_path do # execute :rake, 'cache:clear' # end end end desc 'Upload database.yml' task :upload do on roles(:app) do |host| if test "[ ! -d #{shared_path}/config ]" execute "mkdir -p #{shared_path}/config" end upload!('config/database.yml', "#{shared_path}/config/database.yml") end end before :starting, 'deploy:upload' after :finishing, 'deploy:cleanup' end |
デプロイ先は、以下のようなディレクトリ構造となります。current が releases 以下の一番新しいバージョンへのシンボリックリンクです。
1 2 3 4 5 6 7 8 |
deploy_dir |- current -> /path/to/deploy_dir/releases/20140626054454 |- releases |- repo |- revisions.log |- shared |
Apache, Nginx などでの DocumentRoot には、/path/to/deploy_dir/current/public を指定します。
deploy.rb についてはコメントを読めば大体分かると思いますが、linked_files, linked_dirs について少し。linked_files, linked_dirs で指定したファイル、ディレクトリは、shared ディレクトリ以下の実体ファイル、ディレクトリへのシンボリックリンクとなります。
database.yml は .gitignore に書いてあるので、linked_files に指定し shared ディレクトリ以下ファイルへのシンボリックリンクとしました。
linked_files で指定しても、アップロードは自動で行ってはくれないので、アップロード用タスクを書く必要があります。そのため、最後のほうの deploy:upload タスクで、database.yml ファイル本体を、ローカルから shared ディレクトリへアップロードさせる処理を書いています。
また、before :starting, ‘deploy:upload’ で、デプロイ処理の開始前に upload タスクが走るようにフックを設定しました。
以上の設定により、database.yml は shared ディレクトリへとアップロードされ、shared/config/database.yml への current/config/database.yml というシンボリックが作成されます。
【追記 2014/06/27】
Rails4.1 から config/secrets.yml が追加されていますので、config/database.yml 同様に、config/secrets.yml も .gitignore に追記して、linked_files 指定と shared にアップロードを行うほうが良いかと思います。
【追記ここまで】
staging, production など環境別ファイル
staging, production など環境ごとに個別のファイルを config/deploy 以下に作成します。
config/deploy/staging.rb
1 2 3 4 5 6 7 8 9 10 |
set :rails_env, :staging # Simple Role Syntax # ================== # Supports bulk-adding hosts to roles, the primary server in each group # is considered to be the first unless any hosts have the primary # property set. Don't declare `role :all`, it's a meta role. role :app, %w{user@centos.staging} role :web, %w{user@centos.staging} role :db, %w{user@centos.staging} |
それぞれ、アプリケーションサーバー、ウェブサーバー、DBサーバーの role を設定します。今回は1台のサーバーでまかなうので、全部同じです。
以上で、デプロイの設定は終了です。
初回のデプロイでは、shared 以下にファイルがないためエラーが発生するかもしれないので、最初一回だけ事前にアップロード・タスクを実行しておきます。
1 2 3 |
$ bundle exec cap staging deploy:upload |
続いて、デプロイを実行したところ、アセットのプリコンパイルでエラーが発生しました。
1 2 3 4 5 6 |
$ bundle exec cap staging deploy ... INFO[1c616f8b] Running /usr/local/rbenv/bin/rbenv exec bundle exec rake assets:precompile on centos.staging DEBUG[1c616f8b] ExecJS::RuntimeUnavailable: Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes. |
JavaScript runtime がないと怒られたので、デプロイ先サーバーで node.js をインストール。
1 2 3 4 |
$ ssh centos.staging $ sudo yum install nodejs npm --enablerepo=epel |
もう一度デプロイ実行。
1 2 3 4 |
$ bundle exec cap staging deploy:check $ bundle exec cap staging deploy |
今度は上手く行きました。Bitbucket からのチェックアウト、Bundler での gem インストール、DBマイグレーション、Unicorn 再起動まで全て自動化されて超楽ちん。デプロイはセッティングし終わるまでは大変ですが、一度設定してしまえばコマンド一発での自動化の恩恵は大きいです。Capistrano 便利!
- Rails の関連記事
- RailsでMySQLパーティショニングのマイグレーション
- Rails ActiveRecordでdatetime型カラムのGROUP BY集計にタイムゾーンを考慮する
- RailsプラグインGemの作成方法、RSpecテストまで含めたrails pluginの作り方
- RailsでAMPに対応するgemをリリースしました
- Railsでrequest.urlとrequest.original_urlの違い
- Railsでwheneverによるcronバッチ処理
- Google AnalyticsのRails Turbolinks対応
- Railsアプリにソーシャル・シェアボタンを簡単設置
- Rails監視ツール用にErrbitをHerokuで運用
- Facebook APIバージョンのアップグレード手順(Rails OmniAuth)
Leave Your Message!