とーますメモ

Ruby on Rails / Goなどの学習メモ

【Rails】CapistranoでBitbucketからcloneしデプロイするまで試してみた

【環境】
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 (公開鍵)」ができる。

[参考]
gitHubでssh接続する手順~公開鍵・秘密鍵の生成から~ - Qiita

ssh-agentに秘密鍵を登録

$ ssh-add -K ~/.ssh/id_psa

Bitbucket側に公開鍵を登録

表示された内容をコピペ

$ cat ~/.ssh/id_rsa.pub | pbcopy

Bitbucketの設定の「SSH Keys」から「Add Key」で設定

f:id:Thoames1212:20180410024005p:plain

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

タスクの追加

$ bundle exec cap -T

デプロイタスクの詳細は以下が詳しい。
Capistrano3のデプロイフレームワークの使い方 - Qiita

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