Capistrano3で快適デプロイ生活!!
Capistrano3で快適なデプロイ生活を目指しています。Railsで定数設定ファイルをgitから外して管理する方法。と組あわせれば、最高なデプロイ生活が待っていること間違い無しです。
が、Capistrano3のまとまった情報があまり手に入らず(Capistrano2とどっちかよくわからんし)、導入の際にかなり苦労したので、インストールから設定までをさらしておきます。
環境: Ruby 2.0.0-p247 Rails 4.0.0 Apache Passenger
Server:CentOS6.4 公開鍵認証設定済み
Capistranoとは
Rubyでできたソフトウェアデプロイメントツールです。 Capistranoは分散環境へのウェブアプリケーションのソフトウェアデプロイメントを簡素化および自動化するために設計されています。 アプリのデプロイの際に生じるいろいろな作業をコマンドで自動化することで、ミスを無くしたり、楽をしたりするためのツールです。
今回は分散環境ではないですが、勉強のため使って行きたいと思います。
github:capistrano / capistrano
Capistranoでデプロイしたアプリのディレクトリ構造は以下のようになっている。
shared以下のファイルからcurrentディレクトリに、linked_files,linked_dirsで指定した通りにシンボリックリンクが張られている。基本的にバージョン管理すると都合の悪いものをsharedにいれて運用するようです。
またディレクトリ構造から考えられる通り、過去のリリースに戻ることも可能です。(cap deploy:rollback
)
詳細コマンドは cap -T
で確認してください。
├── current #現在起動しているアプリケーションのディレクトリ │ └── app #現在のアプリ ├── releases │ ├── app_02 #1つ前のアプリ │ └── app_01 #2つ前のアプリ ├── repo └── shared
サーバーの設定
何をすれば良いかというと、デプロイ用のユーザー作成 デプロイ用ユーザーに公開鍵でアクセス出来るようにする
ということを行います。 今回、こちらの設定は済んでいたので省略させて頂きます(スイマセン)
こちらを見れば、だいたいどんなことをしなければいけないかわかると思います。
ローカルでの設定
設定ファイルをgit管理化から外しておきます
cp config/database.yml{,.example}
echo config/database.yml >> .gitignore
cd rails_dir
vim Gemfile
Gemfile
gem 'capistrano' gem 'capistrano-rails' gem 'capistrano-bundler' gem 'capistrano-rbenv'
インストール
bundle install
bundle exec cap install
├── Capfile
├── config
│ ├── deploy
│ │ ├── production.rb
│ │ └── staging.rb
│ └── deploy.rb
└── lib
└── capistrano
└── tasks
詳しい図はこちらにCapistrano Version 3
まずはCapfileの編集
Capfile
# 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 # # For documentation on these, see for example: # # https://github.com/capistrano/rvm # https://github.com/capistrano/rbenv # https://github.com/capistrano/chruby # https://github.com/capistrano/bundler # https://github.com/capistrano/rails/tree/master/assets # https://github.com/capistrano/rails/tree/master/migrations # # rbenvを使用しているので or 'capistrano/rvm' require 'capistrano/rbenv' #rbenvをシステムにインストールした or ユーザーローカルにインストールした set :rbenv_type, :user # :user or :system # rubyのversion set :rbenv_ruby, '2.0.0-p247' # Rails,bundlerをデプロイするので必須 require 'capistrano/bundler' require 'capistrano/rails' # Loads custom tasks from `lib/capistrano/tasks' if you have any defined. Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r }
つづいてデプロイ先のサーバーの設定。 今回はweb,app,dbすべて1つのサーバーに詰め込みます。
config/deploy/production.rb
set :stage, :production #サーバーのロールを指定.ついでにユーザーも指定しています。 role :app, %w{deploy@yoshiso.net} role :web, %w{deploy@yoshiso.net} role :db, %w{deploy@yoshiso.net} # you can set custom ssh options # it's possible to pass any option but you need to keep in mind that net/ssh understand limited list of options # you can see them in [net/ssh documentation](http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start) # set it globally #> サーバーにアクセスするためのsshkeyを指定する. #> サーバーから直接githubのプライベートリポジトリにアクセスするためにforward_agentをtrueにしておく。 set :ssh_options, { keys: [File.expand_path('~/.ssh/id_rsa')], forward_agent: true } #> サーバー個別の設定が多い場合は下記の方がいいかも。 # and/or per server # server 'example.com', # user: 'user_name', # roles: %w{web app}, # ssh_options: { # user: 'user_name', # overrides user setting above # keys: %w(/home/user_name/.ssh/id_rsa), # forward_agent: false, # auth_methods: %w(publickey password) # # password: 'please use keys' # } # setting per server overrides global ssh_options #fetch(:default_env).merge!(rails_env: :production)
そして最後にデプロイ用のタスクを作ります。 Rails用のタスクに関してはcapistrano-railsが行っていてくれるので、その補完を行うタスクを作っていきます。
config/deploy.rb
set :application, '<app_name>' #=> アプリケーション名 set :repo_url, 'git@github.com:<username>/<repos_name>.git' #=> githubのurl。プロジェクトのgitホスティング先を指定する #ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp } set :branch, 'master' #> デプロイするのはマスターブランチに固定 set :deploy_to, '/var/www/<app_name>' #> デプロイ先のサーバーのディレクトリ。フルパスで指定した。 set :scm, :git #> Version管理はgitですよ、と set :format, :pretty set :log_level, :debug # :info or :debug #> ログはたくさん見れるようにしておきます。 # set :pty, true set :linked_files, %w{config/database.yml} #> デプロイ先のサーバーの :deploy_to/shared/config/database.yml のシンボリックリンクを # :deploy_to/current/config/database.yml にはる。 # 先にshared以下にファイルをアップロードする必要あり # 説明下記に set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system public/assets} #>同じくsharedに上記のディレクトリを生成し、currentにシンボリックリンクを張る # set :default_env, { path: "/opt/ruby/bin:$PATH" } set :keep_releases, 5 #> 5リリース分保持しておく。 namespace :deploy do #>アプリの再起動を行うタスク desc 'Restart application' task :restart do on roles(:app), in: :sequence, wait: 5 do execute :mkdir, '-p', release_path.join('tmp') execute :touch, release_path.join('tmp/restart.txt') end end #> 上記linked_filesで使用するファイルをアップロードするタスク # deployが行われる前に実行する必要がある。 desc 'upload importabt files' task :upload do on roles(:app) do |host| upload!('config/database.yml',"#{shared_path}/config/database.yml") end end #> webサーバー再起動時にキャッシュを削除する 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 :rmdir, '-rf', release_path.join('tmp/cache') end end end #> Flowのbefore,afterのタイミングで上記タスクを実行する. # 詳細のhookタイミングはここでcheck:http://www.capistranorb.com/documentation/getting-started/flow/ before :started, 'deploy:upload' after :finishing, 'deploy:cleanup' end #> dbサーバーのデータベースを生成するタスク。 #> デプロイ前に実行する必要がある。 task :db_create do on roles(:db) do |host| q1 = 'CREATE DATABASE IF NOT EXISTS <app_name>;' q2 = 'GRANT ALL ON <app_name>.* TO <app_user>@localhost IDENTIFIED BY "<app_passsword>";' q3 = "FLUSH PRIVILEGES;" sql = "#{q1}#{q2}#{q3}" execute "mysql --user=<mysql_user> --password=<msql_password> -e '#{sql}' " end end
これで準備は完了。
タスクの実行
あとはタスクを実行するだけです。
bundle exec cap produciton db_create
bundle exec cap production deploy:update
bundle exec cap production deploy
以上でデプロイ完了! 自分はApache Passengerの環境が構築してあったので、virtualhostの設定を書いてあげれば、公開完了です。
参考文献
Capistrano3についてまとまっている順に