【環境】
Ubuntu + Rbenv + Rails + Puma + MySQL
1)SSH周りの設定
前提
公開リポジトリの場合は、Capistranoの設定は簡単だが、BitbucketのPrivateリポジトリからcloneする場合は、SSH認証が絡んでくるため、設定が少し複雑になる。
ちなみにGithubのPrivateリポジトリを使用する場合は、「Personal Access Token」を使用すれば、すごい簡単にPrivateリポジトリからcloneできる。
BitbucketでSSH認証を行う方法としては
① SSH agent forwardingを使用する
② デプロイするサーバで秘密鍵・公開鍵を作り、公開鍵をBitbucketに登録する
がある。
①の「SSH agent forwarding」については以下のサイトが詳しい。
SSH agent forwardingまとめ - Code Life
②を使用する場合は、サーバが増えるたびに鍵が増えていき管理が手間になるため
①をここでは推奨する。
以降の説明では①の「SSH agent forwarding」を用い、
Capistranoを使用したデプロイを行う手順を説明していく。
[参考]
Capistrano 3.x で GitHub(プライベートリポジトリ)からソースコードを取得する3種類の方法について - Qiita
Capistrano3でgithubのプライベートリポジトリを簡単にデプロイする方法 · polidog lab++
ssh-agentを利用して、安全にSSH認証を行う - Qiita
capistrano3でssh agent forwarding - Qiita
capistranoでデプロイする時のssh-key周りのTips - Qiita
Capistrano3とBitbucketを使ってRailsアプリをデプロイ | EasyRamble
(②の方法で対応する場合)
ローカルで秘密鍵・公開鍵を作成
$ cd ~/.ssh
$ ssh-keygen -t rsa
ずっとエンターを押し続けていれば、「id_rsa (秘密鍵)」と「id_rsa.pub (公開鍵)」ができる。
ssh-agentに秘密鍵を登録
$ ssh-add -K ~/.ssh/id_psa
Bitbucket側に公開鍵を登録
表示された内容をコピペ
$ cat ~/.ssh/id_rsa.pub | pbcopy
Bitbucketの設定の「SSH Keys」から「Add Key」で設定
2)Gemfile & インストール
group :development do gem 'capistrano', require: false gem 'capistrano-rails', require: false gem 'capistrano-bundler', require: false gem 'capistrano3-puma', require: false gem 'capistrano-rbenv', require: false end
$ bundle install --path vendor/bundle
3)Capistranoのデフォルトファイル作成
例)development, staging, produtionの3つの環境を作成
$ bundle exec cap install STAGES=development,staging,production
mkdir -p config/deploy create config/deploy.rb create config/deploy/development.rb create config/deploy/staging.rb create config/deploy/production.rb mkdir -p lib/capistrano/tasks create Capfile Capified
Capistranoファイルの設定
設定するファイルは
① Capfile
② deploy.rb
③ development.rb(開発環境へデプロイするため。staging環境ならstaging.rbにする)
を設定する。
Capfile
# Load DSL and set up stages require "capistrano/setup" # Include default deployment tasks require "capistrano/deploy" # Load the SCM plugin appropriate to your project: # # require "capistrano/scm/hg" # install_plugin Capistrano::SCM::Hg # or # require "capistrano/scm/svn" # install_plugin Capistrano::SCM::Svn # or require "capistrano/scm/git" install_plugin Capistrano::SCM::Git require "capistrano/rbenv" require "capistrano/bundler" require "capistrano/rails/assets" require "capistrano/rails/migrations" require 'capistrano/puma' install_plugin Capistrano::Puma # Load custom tasks from `lib/capistrano/tasks` if you have any defined Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
development.rb(ユーザはroot)
role :app, %w{root@xxx.xxx.xxx.xxx} role :web, %w{root@xxx.xxx.xxx.xxx} role :db, %w{root@xxx.xxx.xxx.xxx} server 'xxx.xxx.xxx.xxx, user: 'root', roles: %w{web app db}, ssh_options: { user: 'root', # overrides user setting above keys: %w(/Users/hogehoge/.ssh/id_rsa), forward_agent: true, # ssh agent forwardを使用するのでtrue auth_methods: %w(publickey) }
deploy.rb
set :application, "SampleApp" set :repo_url, "git@bitbucket.org:nutrisan/sample.git" # Default branch is :master ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp # Default deploy_to directory is /var/www/my_app_name set :deploy_to, "/var/www/sample_app" # Default value for :pty is false set :pty, true # Default value for :linked_files is [] append :linked_files, "config/puma.rb", "config/database.yml", "config/secrets.yml" # Default value for linked_dirs is [] append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system" # Default value for keep_releases is 5 set :keep_releases, 5 # migrate setting set :migration_role, :db set :conditionally_migrate, false set :rbenv_type, :user set :rbenv_ruby, '2.3.1' set :rails_root, 'web' set :bundle_without, nil # (default: %w{development test}.join(' ') ) set :bundle_flags, nil # (default: '--deployment --quiet') # for puma set :puma_conf, "#{shared_path}/config/puma.rb" namespace :puma do desc 'Create Directories for Puma Pids and Socket' task :make_dirs do on roles(:app) do execute "mkdir #{shared_path}/tmp/sockets -p" execute "mkdir #{shared_path}/tmp/pids -p" end end before :start, :make_dirs end before 'deploy:starting', 'deploy:upload' namespace :deploy do # below task must run before linked_files task. desc 'upload linked_files' task :upload do on roles(:app) do |host| execute :mkdir, '-p', "#{shared_path}/config" upload!('config/puma.rb',"#{shared_path}/config/puma.rb") upload!('config/database.yml',"#{shared_path}/config/database.yml") upload!('config/secrets.yml',"#{shared_path}/config/secrets.yml") end end after :restart, :clear_cache do on roles(:web), in: :groups, limit: 3, wait: 10 do within release_path do execute :rm, '-rf', release_path.join('tmp/cache') end end end desc "Restart Application" task :restart do on roles(:app), in: :sequence, wait: 5 do invoke 'puma:restart' end end end
Pumaについて
pumaには、pumaコマンドとpumactlコマンドがあるが
基本的にできることに差はないが、pumactlはデフォルトでconfig/puma.rbを読み込んでくれたり
startだけでなく、stopやrestartといったコマンドも使用できるためpumactlを使うのが良いだろう。
※ちなみにstateファイルはpumactl使用時に使用される。
「gem 'capistrano3-puma'」を入れることによって
設定ファイルのpuma.rbがリモートの「shared/puma.rb」に自動作成される。
またCapistranoのdeploy.rbに設定するpuma関連の設定はすべてこのファイル内に設定される。
しかしこのshared/puma.rbではなく、Railsのconfig/puma.rbを使用したい場合は、
以下のように書くと良いっぽい。
set :puma_conf, "#{shared_path}/config/puma.rb"
※この設定を使用すると、deploy.rb内の設定は使用されなくなる。
[bindについて]
サーバーをどのように接続するかをURIで指定できます。 シンプルにTCPで接続する場合tcp://0.0.0.0:80、またWebサーバーの前段にnginxをなどを置き、そこからUNIX Socket経由で接続する場合はunix:///var/run/puma.sockのように指定します。
by RackサーバーのPumaについて調べてみる - ゆーじのろぐ
[puma.rbの設定例]
puma/config.rb at master · puma/puma · GitHub
[参考]
Pumaの起動におけるpumaコマンドとpumactlコマンドの違い - Qiita
Digesting pumactl - Ruby Journal
Ruby on Rails 5の上手な使い方 現場のエンジニアが教えるRailsアプリケーション開発の ... - 太田智彬, 株式会社リクルートテクノロジーズ, 宗像亜由美, 寺下翔太, 手塚亮 - Google ブックス
4) 実行
$ bundle exec cap development deploy