オーマイガー東京

オーマイガー東京というブログを24歳東京暮らし新卒2年目のエンジニアが書いています。

【最新2018年】Capistrano3でrailsアプリをデプロイする個人的完全版

f:id:maru_33:20181111165619p:plain

Capistranoとは

Capistranoとは、複数のサーバ上で同時にスクリプトを実行するためのソフトウェアツールです。

主に、同一の役割のサーバが複数台存在する環境での自動化であったり、アプリケーションのデプロイ自動化に利用されています。

同じようなソフトウェアにChefがあります。
そのChefとの違いは、Chefは主にプル型であるのに対し、Capistranoはプッシュ型だと言う点です。

プッシュ型なので、対象のサーバ上にエージェントのようなものをインストールする必要はなく、SSHでアクセス可能であればすぐに利用できます。

よし、じゃあ使い方まとめて行きます。

Capistrano3でRails5.2のアプリをデプロイする手順書

必要なライブラリを追加

Gemfileに以下を追加し、プロジェクトに必要なライブラリをインストールします。

group :deployment do
  # 本体
  gem 'capistrano', '~> 3.11.0', require: false 

  # bundler系のtaskをまとめてくれてるやつ
  # bundle installとかを高度にcapistrano内でうまくやってくれる
  # https://github.com/capistrano/bundler
  gem 'capistrano-bundler', '~> 1.4.0', require: false

    # rails系のtaskをまとめてくれてるやつ
  # 例えば、migration, assets系のやつ 
  # https://github.com/capistrano/rails
  gem 'capistrano-rails', '~> 1.4.0', require: false

  # rbenv系のtaskをまとめてくれるやつ
  # rubyのversionもちゃんと指定しよう!
  # https://github.com/capistrano/rbenv
  gem 'capistrano-rbenv', '~> 2.1.4', require: false
  gem 'sshkit-sudo', '~> 0.1.0', require: false

  # puma系のtaskをまとめてくれるやつ
  # unicorn使ってたら他のやつ使ってね
  # https://github.com/seuros/capistrano-puma
  gem 'capistrano3-puma', '~> 3.1.1', require: false
end

※ バージョンは現時点(2018.11.02)で最新の3.11.0にしました。

Capistranoをアプリにインストール

以下のコマンドでCapistranoをアプリにインストールします。

$ 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
# create Capfile
# Capified

Capfileの設定

作成された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/git"
install_plugin Capistrano::SCM::Git

# Include tasks from other gems included in your Gemfile
require "capistrano/rbenv"
require "capistrano/bundler"
require "capistrano/rails/assets"
require "capistrano/rails/migrations"
require 'capistrano/puma'
require 'sshkit/sudo'

# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
install_plugin Capistrano::Puma

Capistrano共通の設定

config/deploy.rbに共通の処理を書いていきます。

# config valid for current version and patch releases of Capistrano
lock "~> 3.11.0"

# アプリ名
set :application, "capistrano-test"
set :repo_url, "git@github.com:maru-u/capistrano-test.git"
set :user, "maru"

# デプロイ先のパス
set :deploy_to, "/home/maru/capistrano-test"

# ログ関係の設定( 詳しくはこちら -> https://qiita.com/hirokishirai/items/50b319133f19f20382f4 )
set :format, :airbrussh
set :format_options, command_output: true, log_file: "log/capistrano.log", color: :true, truncate: :false

# Sudoするために必要な設定 ( 詳しくはこちら -> https://qiita.com/kasei-san/items/3edb52359ff288d2f435 )
set :pty, true

# リリースをどこまで残すか
set :keep_releases, 5

# puma の設定
set :puma_threads,    [4, 16]
set :puma_workers,    0
set :puma_bind,       "unix://#{shared_path}/tmp/sockets/puma.sock"
set :puma_state,      "#{shared_path}/tmp/pids/puma.state"
set :puma_pid,        "#{shared_path}/tmp/pids/puma.pid"
set :puma_access_log, "#{release_path}/log/puma.access.log"
set :puma_error_log,  "#{release_path}/log/puma.error.log"
set :puma_preload_app, true
set :puma_worker_timeout, nil
set :puma_init_active_record, true

# rbenv の設定
set :rbenv_type, :user
set :rbenv_path, '/home/maru/.rbenv'
set :rbenv_ruby, File.read('.ruby-version').strip
set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} RBENV_VERSION=#{fetch(:rbenv_ruby)} #{fetch(:rbenv_path)}/bin/rbenv exec"
set :rbenv_map_bins, %w[rake gem bundle ruby rails puma pumactl]

# シンボリックリンク貼る系(dir)
set :linked_dirs, fetch(:linked_dirs, []).push(
  'log',
  'tmp/pids',
  'tmp/cache',
  'tmp/sockets',
  'vendor/bundle',
  'public/system',
  'public/uploads'
)
# シンボリックリンク貼る系(file)
set :linked_files, fetch(:linked_files, []).push(
  'config/database.yml',
  'config/master.key',
  '.env'
)

# pumaの追加タスク
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

# デプロイ用の追加タスク
namespace :deploy do
  desc 'Make sure local git is in sync with remote.'
  task :check_revision do
    on roles(:app) do
      unless `git rev-parse HEAD` == `git rev-parse origin/master`
      end
    end
  end

  desc 'Initial Deploy'
  task :initial do
    on roles(:app) do
      # 403 Forbidden対策
      # https://qiita.com/hatorijobs/items/8b57f9a89c3bfb442755
      execute 'chmod 701 /home/maru'
      before 'deploy:restart', 'puma:start'
      invoke 'deploy'
    end
  end

  desc 'Restart application'
  task :restart do
    on roles(:app), in: :sequence, wait: 5 do
      invoke 'puma:restart'
    end
  end

  desc 'reload the database with seed data'
  task :seed do
    on roles(:db) do
      with rails_env: fetch(:rails_env) do
        within release_path do
          execute :bundle, :exec, :rake, 'db:seed'
        end
      end
    end
  end

  before :starting,     :check_revision
  before :check,        'setup:config'
  after  :finishing,    :compile_assets
  after  :finishing,    :cleanup
  after  :migrate,      :seed
end

namespace :setup do
  desc 'setup config'
  task :config do
    on roles(:app) do |host|
      # rails5.2以前だとmaster.keyではなくて、secret.ymlになるはずです。
      %w[master.key database.yml].each do |f|
        upload! "config/#{f}", "#{shared_path}/config/#{f}"
      end

      %w[.env].each do |f|
        upload! "#{f}", "#{shared_path}/#{f}"
      end
    end
  end

  desc 'setup nginx'
  task :nginx do
    on roles(:app) do |host|
      # 後ほど作成するnginxのファイル名を記述してください
      %w[perican3.conf].each do |f|
        upload! "config/#{f}", "#{shared_path}/config/#{f}"
        sudo :cp, "#{shared_path}/config/#{f}", "/etc/nginx/conf.d/#{f}"
        sudo "nginx -s reload"
      end
    end
  end
end

各環境毎の設定

config/deploy/production.rb等に環境ごとの設定を書いていきます。

# デプロイに使用するbranch
set :branch, 'master'

# デプロイ先のip
server '1xx.xx.xxx.xx',
  user: 'USER_NAME',
  roles: %w[web app db],
  port: 63xx,
  ssh_options: {
    user: 'USER_NAME',
    keys: [File.expand_path('~/.ssh/id_rsa')],
    forward_agent: true,
}

ssh先の設定

色々設定とインストール

// 必要なもんをDL
sudo yum install -y git gcc gcc-c++ openssl-devel readline-devel

// rbenvをDL
git clone git://github.com/sstephenson/rbenv.git ~/.rbenv

// Pathを通す
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

// ruby-buildをDL
sudo git clone git://github.com/sstephenson/ruby-build.git /usr/local/src/rbenv/plugins/ruby-build

// rbenvでinstallできるリストを更新
sudo yum upgrade ruby-build
sudo yum updade ruby-build

// rubyをインストール
rbenv install 2.5.1
rbenv global 2.5.1

// bundlerをインストール
gem install bundler

nginxの設定ファイルを作成

nginxの簡易的な設定ファイルを作成します。 config/APP_NAME.confで僕は作成しました。

※unicornを使ってる人はそっちに合わせて書くこと

upstream puma {
    server unix:///path/to/APP/shared/tmp/sockets/puma.sock;
}

server {
    listen       4001 default_server; # 各自port設定して
    listen       [::]:4001 default_server;
    server_name  localhost;
    root         /path/to/APP/current/public;

    include /etc/nginx/default.d/*.conf;

    location / {
        try_files $uri $uri/index.html $uri.html @webapp;
    }

    location @webapp {
        proxy_read_timeout 300;
        proxy_connect_timeout 300;
        proxy_redirect off;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://puma;
    }

    error_page 404 /404.html;
        location = /40x.html {
    }

    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }
}

初回インストール

初回は以下のコマンドでインストールしてください。

$ bundle exec cap production deploy:initial

nginxの設定ファイルをあっちに送る

設定ファイルの書き方間違ってるとエラー出るので見直してください。

$ bundle exec cap production setup:nginx

デプロイ

2回目以降のデプロイはこちら

$ bundle exec cap production deploy

アクセスできるか確認して見てください

ちなみに! rootの設定してない人は、/public/index.htmlをおいてください

VPSはこれがおすすめ

デプロイ先には僕は、さくらVPSをよく使っています。

さくらVPSの特徴

  • 月685円から始められる!安い!
  • 専門の技術者が24時間365日サーバー状況を監視、万一の障害にも安心な運用体制!
  • コントロールパネルからいつでも簡単に上位プランへの変更可能。上位プランにスケールアップ!アクセス増えても安心

2週間無料で使えるので気軽にこちらから使ってください↓↓↓↓

さくらのVPS