Capistrano
前提条件
- config 2.0.0
- dotenv-rails 2.7.5
- Capistrano 3.11.2
- slackistrano >= 4.0.1
- pushion passenger( Nginx
セットアップ
- Capistranoのインストール
$ bundle exec cap install STAGES=staging,production
bundler: command not found: cap
Install missing gem executables with `bundle install`
あら。まあそりゃそうです笑
command not found: capとなった場合
-
この場合、capistranoのGEMがインストールされていない為、GEMインストールを行う
-
Gemfileを開き、編集
# Gemfileの編集
$ vi Gemfile
group :staging, :production do
# Use Capistrano for deployment
gem 'capistrano', '3.11.2'
gem 'capistrano-rails', '1.4.0'
gem 'capistrano-rbenv', '2.1.4 '
gem 'capistrano-passenger', '0.2.0'
# 今回はSlack通知も行うため、便宜上載せています
gem 'slackistrano', '>=4.0.1'
end
- bundle install
$ bundle _1.17.2_ install --path vendor/bundle
The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
・・・
Fetching capistrano 3.11.2
Installing capistrano 3.11.2
Fetching capistrano-bundler 1.6.0
Installing capistrano-bundler 1.6.0
Fetching capistrano-passenger 0.2.0
Installing capistrano-passenger 0.2.0
Fetching capistrano-rails 1.4.0
Installing capistrano-rails 1.4.0
Fetching capistrano-rbenv 2.1.4
Installing capistrano-rbenv 2.1.4
・・・
Fetching slackistrano 4.0.1
Installing slackistrano 4.0.1
・・・
Bundle complete! 38 Gemfile dependencies, 148 gems now installed.
Bundled gems are installed into `./vendor/bundle`
Post-install message from capistrano-passenger:
==== Release notes for capistrano-passenger ====
passenger once had only one way to restart: `touch tmp/restart.txt`
Beginning with passenger v4.0.33, a new way was introduced: `passenger-config restart-app`
The new way to restart was not initially practical for everyone,
since for versions of passenger prior to v5.0.10,
it required your deployment user to have sudo access for some server configurations.
capistrano-passenger gives you the flexibility to choose your restart approach, or to rely on reasonable defaults.
If you want to restart using `touch tmp/restart.txt`, add this to your config/deploy.rb:
set :passenger_restart_with_touch, true
If you want to restart using `passenger-config restart-app`, add this to your config/deploy.rb:
set :passenger_restart_with_touch, false # Note that `nil` is NOT the same as `false` here
If you don't set `:passenger_restart_with_touch`, capistrano-passenger will check what version of passenger you are running
and use `passenger-config restart-app` if it is available in that version.
If you are running passenger in standalone mode, it is possible for you to put passenger in your
Gemfile and rely on capistrano-bundler to install it with the rest of your bundle.
If you are installing passenger during your deployment AND you want to restart using `passenger-config restart-app`,
you need to set `:passenger_in_gemfile` to `true` in your `config/deploy.rb`.
================================================
- CapistranoとCapifyアプリケーションをインストールする
$ bundle exec cap install STAGES=staging,production
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
階層構造は以下となる
[rails app root]
├─ Capfile
├─ config
│ ├─ deploy
│ │ ├─production.rb
│ │ └─staging.rb
│ └─deploy.rb
└─ lib
└─capistrano
└─tasks
└─tasks
capistranoをインストールしたので、capistrano/setup と capistrano/deploy の準備は一旦はこれでできました
capistrano/deploy タスク
- デプロイを自動化する、capistranoのタスクです
Deployタスクの一覧
実行順 | タスク名 | 意味 |
---|---|---|
1 | deploy | Deploy実行 |
2 | deploy:starting | Deploy実行開始、サーバー待機中 |
2.1 | deploy:check | - |
2.1.1 | #{scm}:check | - |
2.1.2 | deploy:check:directories | - |
2.1.3 | deploy:check:linked_dirs | - |
2.1.4 | deploy:check:make_linked_dirs | - |
2.1.5 | deploy:check:linked_files | - |
2.2 | deploy:set_previous_revision | - |
3 | deploy:started | Deploy開始中 |
4 | deploy:updating | Deploy実行中 |
4.1 | #{scm}:create_release | - |
4.2 | deploy:symlink:shared | - |
4.2.1 | deploy:symlink:linked_files | - |
4.2.2 | deploy:symlink:linked_dirs | - |
5 | deploy:updated | 更新完了 |
6 | deploy:publishing | デプロイ処理中 |
6.1 | deploy:symlink:release | - |
7 | deploy:published | デプロイ処理終了 |
8 | deploy:finishing | デプロイ終了中、サーバークリーンアップ中 |
8.1 | deploy:cleanup | - |
9 | deploy:finished | 処理終了 |
9.1 | deploy:log_revision | - |
実行順 | タスク名 | 意味 |
---|---|---|
1 | deploy:rollback | 前回リリースバージョンにロールバック |
2 | deploy:starting | Deploy実行開始、サーバー待機中 |
3 | deploy:started | Deploy開始中 |
4 | deploy:reverting | 前回リリースバージョンにrevert完了 |
5 | deploy:reverted | 前回リリースバージョンにrevert |
6 | deploy:publishing | デプロイ処理中 |
7 | deploy:published | デプロイ処理終了 |
8 | deploy:finishing_rollback | ロールバック完了 |
9 | deploy:finished | 処理終了 |
実行順 | タスク名 | 意味 |
---|---|---|
1 | install | Capistranoインストール (凡例:cap install STAGES=staging,production) |
- 参考になった技術まとめ
プラグインによるフローの追加
capistrano/rails/assets
- Assetsのプリコンパイルを行う
インストール
require capistrano/rails/assets
実行順 | タスク名 | 意味 |
---|---|---|
5 | deploy:updated | 更新完了 |
5.1 | deploy:compile_assets | 追加される |
5.1.1 | deploy:assets:precompile | 追加される |
5.1.2 | deploy:assets:backup_manifest | 追加される |
5.2 | deploy:normalize_assets | 追加される |
capistrano/rails/migrations
- DBMigrationを行う
インストール
require "capistrano/rails/migrations"
実行順 | タスク名 | 意味 |
---|---|---|
5 | deploy:updated | 更新完了 |
5.1 | deploy:migrate | 追加される |
capistrano/npm
- npm installを行う
インストール
require "capistrano/rails/migrations"
実行順 | タスク名 | 意味 |
---|---|---|
4 | deploy:updating | Deploy実行中 |
4.1 | #{scm}:create_release | - |
4.2 | deploy:symlink:shared | - |
4.2.1 | deploy:symlink:linked_files | - |
4.2.2 | deploy:symlink:linked_dirs | - |
5 | npm:install | 追加される |
前提条件
- ssh-agentを使用
セットアップ手順
-
config/settings/staging.yml
を作成 -
config/environments/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
# Include 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
# https://github.com/capistrano/passenger
#
# require "capistrano/rvm"
# require "capistrano/rbenv"
# require "capistrano/chruby"
# require "capistrano/bundler"
# require "capistrano/rails/assets"
# require "capistrano/rails/migrations"
# require "capistrano/passenger"
# if you used rbenv
require "capistrano/rbenv"
require 'capistrano/rails'
require 'capistrano/bundler'
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
-
deploy.rb
を編集する
# config valid for current version and patch releases of Capistrano
lock "~> 3.11.2"
set :application, "%app name%"
set :repo_url, "git@github.com:****/*****.git"
# Default branch is :master
# masterで良いので、特に変更は不要
ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp
# bundle exec cap %env% deploy BRANCH=feature/hogehoge
# set :branch, ENV['BRANCH'] || 'master'
# Default deploy_to directory is /var/www/my_app_name
# set :deploy_to, "/var/www/my_app_name"
set :deploy_to, "/var/www/#{fetch(:application)}"
# Default value for :format is :airbrussh.
# set :format, :airbrussh
# Configure version management tool
set :scm, :git
# You can configure the Airbrussh format using :format_options.
# These are the defaults.
# set :format_options, command_output: true, log_file: "log/capistrano.log", color: :auto, truncate: :auto
# Configure log_leve if you output the log file
# set :format, :pretty
# set :log_level, :info
# Default value for :pty is false
# set :pty, true
# sudoを使用する場合はtrue
set :pty, true
# Default value for :linked_files is []
# append :linked_files, "config/database.yml"
# ln -s deploy_to/shared/config/database.yml :deploy_to/current/config/database.yml
set :linked_files, %w{config/database.yml}
# Default value for linked_dirs is []
# append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system"
# sharedのディレクトリをcurrentにシンボリックリンクする
#set :linked_dirs, %w{bin log tmp/backup tmp/pids tmp/cache tmp/sockets vendor/bundle}
# binはrails consoleが必要なため、残す
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle')
set :rbenv_map_bins, %w{rake gem bundle ruby rails}
# Default value for default_env is {}
# capistrano用bundleするのに必要
# set :default_env, { path: "/opt/ruby/bin:$PATH" }
set :default_env, { path: "/usr/local/rbenv/shims:/usr/local/rbenv/bin:$PATH" }
# Default value for local_user is ENV['USER']
# set :local_user, -> { `git config user.name`.chomp }
# Default value for keep_releases is 5
# set :keep_releases, 5
# How many keep the component of deployed in the "releases" directory
set :keep_releases, 5
# Uncomment the following to require manually verifying the host key before first deploy.
# set :ssh_options, verify_host_key: :secure
# Configure ssh agent
set :ssh_options, {
keys: %w(~/.ssh/id_rsa),
forward_agent: true,
auth_methods: %w(publickey)
}
# Configure ur Slack's Incoming Webhook
# if you want to be disable deployment notifications to a specific stage by setting the :slackistrano configuration variable to false instead of actual settings.
set :slackistrano, false
#set :slackistrano, {
# klass: Slackistrano::CustomMessaging,
# channel: '#chatops-#{fetch(:application)}-deploy',
# webhook: 'https://hooks.slack.com/services/*/*/*'
#}
# Have you installed rbenv in the global area? Or was it installed in the user local area?
# :system or :user
set :rbenv_type, :user
# rubyのversion
set :rbenv_ruby, '2.6.5'
set :rbenv_path, '/usr/local/rbenv'
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}
set :rbenv_roles, :all # default value
# Configure
# rollback / deployを判定する為、before startingのcallbackで判定を取得する
# 参考:https://github.com/capistrano/capistrano/blob/v3.11.2/lib/capistrano/tasks/framework.rake#L57
before 'deploy:starting', 'slack:deploy:updating'
# https://github.com/capistrano/capistrano/blob/v3.11.2/lib/capistrano/dsl/task_enhancements.rb#L51
# https://www.rubydoc.info/github/capistrano/capistrano/Capistrano/TaskEnhancements
# 既存処理をOverride
module Capistrano
module TaskEnhancements
def exit_deploy_because_of_exception(ex)
set :failed_exception, ex
super ex
end
end
end
# Edited deploy task
namespace :deploy do
desc 'git confirm'
task :git_confirm do
on release_roles :all do
current = `git rev-parse --abbrev-ref HEAD`.chomp
correct = fetch(:branch) || 'master'
unless current == correct
error "git: current branch is not '#{correct}' but '#{current}'."
exit 1
end
# gitにdiffがないかどうかのチェック
git_diff = `git diff`
unless git_diff.empty?
error "git: current source has any diff. \n#{git_diff}"
exit 1
end
end
end
# 上記linked_filesで使用するファイルをアップロードするタスク
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
desc 'Restart application'
task :restart do
# on roles(:app) do
# invoke 'unicorn:restart'
# end
on roles(:app), in: :sequence, wait: 5 do
# Your restart mechanism here, for example:
execute :touch, release_path.join('tmp/restart.txt')
end
end
desc '.env publishing'
task :env_publising do
on roles(:app) do |host|
if test "[ -f #{fetch(:deploy_to)}/.env ]"
execute "cp -a #{fetch(:deploy_to)}/.env #{fetch(:release_path)}/.env"
end
end
end
end
before 'deploy', 'deploy:git_confirm'
before 'deploy:starting', 'deploy:upload'
# Enhance dotenv
after 'deploy:published', 'deploy:env_publising'
after 'deploy:published', 'deploy:restart'
- 各環境のデプロイ用ファイルの編集
# server-based syntax
# ======================
# Defines a single server with a list of roles and multiple properties.
# You can define all roles on a single server, or split them:
# server "example.com", user: "deploy", roles: %w{app db web}, my_property: :my_value
# server "example.com", user: "deploy", roles: %w{app web}, other_property: :other_value
# server "db.example.com", user: "deploy", roles: %w{db}
# role-based syntax
# ==================
# Defines a role with one or multiple servers. The primary server in each
# group is considered to be the first unless any hosts have the primary
# property set. Specify the username and a domain or IP for the server.
# Don't use `:all`, it's a meta role.
# role :app, %w{deploy@example.com}, my_property: :my_value
# role :web, %w{user1@primary.com user2@additional.com}, other_property: :other_value
# role :db, %w{deploy@example.com}
# Configuration
# =============
# You can set any configuration variable like in config/deploy.rb
# These variables are then only loaded and set in this stage.
# For available Capistrano configuration variables see the documentation page.
# http://capistranorb.com/documentation/getting-started/configuration/
# Custom SSH Options
# ==================
# You may pass any option but keep in mind that net/ssh understands a
# limited set of options, consult the Net::SSH documentation.
# http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start
#
# Global options
# --------------
# set :ssh_options, {
# keys: %w(/home/rlisowski/.ssh/id_rsa),
# forward_agent: false,
# auth_methods: %w(password)
# }
#
# The server-based syntax can be used to override options:
# ------------------------------------
# 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"
# }
set :stage, :staging
set :branch, ENV['GIT_BRANCH'] || `git rev-parse --abbrev-ref HEAD`.strip
set :rails_env, "staging"
# Only setup application server role
# role :app, %w{USER_NAME@IP_ADDRESS}
# capistrano_sample_app_v1
server "%hostname%", user: `whoami`.strip, roles: %w{app}
# server-based syntax
# ======================
# Defines a single server with a list of roles and multiple properties.
# You can define all roles on a single server, or split them:
# server "example.com", user: "deploy", roles: %w{app db web}, my_property: :my_value
# server "example.com", user: "deploy", roles: %w{app web}, other_property: :other_value
# server "db.example.com", user: "deploy", roles: %w{db}
# role-based syntax
# ==================
# Defines a role with one or multiple servers. The primary server in each
# group is considered to be the first unless any hosts have the primary
# property set. Specify the username and a domain or IP for the server.
# Don't use `:all`, it's a meta role.
# role :app, %w{deploy@example.com}, my_property: :my_value
# role :web, %w{user1@primary.com user2@additional.com}, other_property: :other_value
# role :db, %w{deploy@example.com}
# Configuration
# =============
# You can set any configuration variable like in config/deploy.rb
# These variables are then only loaded and set in this stage.
# For available Capistrano configuration variables see the documentation page.
# http://capistranorb.com/documentation/getting-started/configuration/
# Feel free to add new variables to customise your setup.
# Custom SSH Options
# ==================
# You may pass any option but keep in mind that net/ssh understands a
# limited set of options, consult the Net::SSH documentation.
# http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start
#
# Global options
# --------------
# set :ssh_options, {
# keys: %w(/home/rlisowski/.ssh/id_rsa),
# forward_agent: false,
# auth_methods: %w(password)
# }
#
# The server-based syntax can be used to override options:
# ------------------------------------
# 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"
# }
set :stage, :production
set :branch, "master"
set :rails_env, "production"
role :app, %w{USER_NAME@IP_ADDRESS}
- Slackistranoの設定
if defined?(Slackistrano::Messaging)
module Slackistrano
class CustomMessaging < Messaging::Base
# Suppress starting message.
def payload_for_updating
attachments = []
# rollback / deployを判定する為、before startingのcallbackで判定を取得する
title = fetch(:deploying, false) ? 'deploying' : 'rollback now'
color = fetch(:deploying, false) ? 'warning' : 'danger'
# https://github.com/phallstrom/slackistrano
attachments = attachments_base(title: title, color: color)
# git log
attachments << {
color: color,
title: "git log",
fields: git_last_commits_fields
}
return {attachments: attachments}
end
# Suppress updated message.
def payload_for_updated
attachments = [] + attachments_base(title: 'Deploy complete', color: 'good')
return {attachments: attachments}
end
# Supperss reverting message.
def payload_for_reverting
# Delegate payload_for_updating
end
# Suppress reverted message.
def payload_for_reverted
attachments = [] + attachments_base(title: 'Revert complete', color: 'good')
return {attachments: attachments}
end
# Suppress failred message.
def payload_for_failed
attachments = [] + attachments_base(title: 'Deploy failred', color: 'good')
# エラー内容を取得
exception = fetch(:failed_exception)
trace_message = exception.inspect + "\n" + exception.backtrace.join("\n")
# エラー内容
attachments << {
color: 'danger',
title: "エラー内容",
fields: [{
value: trace_message
}]
}
return {attachments: attachments}
end
private
def attachments_base(title = "", color = "")
{
color: color,
title: "#{application} #{title}",
fields: [
{
title: '環境',
value: stage,
short: true
},
{
title: 'ブランチ',
value: branch,
short: true
},
{
title: 'Capistrano実行者',
value: deployer,
short: true
},
{
title: '実行時間',
value: elapsed_time,
short: true
}
],
fallback: super[:text]
}
end
def deployer
`whoami`.strip
end
end
end
end
変更の構成は以下の通り
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: Gemfile
modified: Gemfile.lock
modified: config/environments/development.rb
modified: config/environments/staging.rb
modified: config/environments/production.rb
Untracked files:
(use "git add <file>..." to include in what will be committed)
Capfile
config/deploy.rb
config/deploy/
lib/slackistrano/
ADD
$ git add Gemfile*
$ git add config/environments
$ git add Capfile
$ git add config/deploy*
$ git add lib/slackistrano
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: Capfile
modified: Gemfile
modified: Gemfile.lock
new file: config/deploy.rb
new file: config/deploy/production.rb
new file: config/deploy/staging.rb
modified: config/environments/development.rb
modified: config/environments/production.rb
new file: lib/slackistrano/custom_messaging.rb
コミット&push
$ git commit -m "Capistranoの設定"
[master 26dbe1b] Capistranoの設定
9 files changed, 567 insertions(+), 3 deletions(-)
create mode 100644 Capfile
create mode 100644 config/deploy.rb
create mode 100644 config/deploy/production.rb
create mode 100644 config/deploy/staging.rb
create mode 100644 lib/slackistrano/custom_messaging.rb
$ git push --set-upstream origin master
Enumerating objects: 23, done.
Counting objects: 100% (23/23), done.
Delta compression using up to 8 threads
Compressing objects: 100% (15/15), done.
Writing objects: 100% (16/16), 9.37 KiB | 3.12 MiB/s, done.
Total 16 (delta 6), reused 0 (delta 0)
remote: Resolving deltas: 100% (6/6), completed with 5 local objects.
To https://github.com/%organization%/%repos name%.git
908k3a9..8u43k19 master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
- 参考になった技術まとめ
- Configure ssh agent
- SSH agent
SSH agentの設定
config/deploy/stating.rb
の server
で指定したホスト環境にSSH agentをセットアップする
%hostname%]$ ssh-add -l
4096 SHA256:%masking% /home/%user%/.ssh/id_rsa (RSA)
詳細は ssh-agentの使い方
を参照
Slackistrano
- Capistranoの自動デプロイをChatOpsに組み込みたいので、Incoming Webhookに連携します
セットアップ手順
-
config/deploy.rb
を編集する
# Configure ur Slack's Incoming Webhook
# if you want to be disable deployment notifications to a specific stage by setting the :slackistrano configuration variable to false instead of actual settings.
# When you desable slackistrano, comment out the description below.
set :slackistrano, false # falseの場合はslackistranoによるIncoming Webhookは発生しない
# set :slackistrano, { # こちらは発生する設定、上記かこちらのいずれかを記載する
# klass: Slackistrano::CustomMessaging,
# channel: '#chatops-#{fetch(:application)}-deploy',
# webhook: 'https://hooks.slack.com/services/*/*/*'
#}
-
Capfile
を編集する
・・・省略・・・
require 'capistrano/bundler'
# Require the slackistrano need the deploy.rb
require 'slackistrano/capistrano'
NameError: uninitialized constant Slackistrano::CustomMessaging が発生した場合
-
この場合、
Capfile
にrequireでGemがロードされていないのが原因の為、Capfileを編集する -
Capfileを開き、編集(上記セットアップ手順を忘れていることが考えられる)
デバッグ実行
-
設定が一通り終わったら、次はデバッグ実行でチェックしてみます
-
--dry-run
オプションで実行せずにデプロイをシミュレーションします -
trace
オプションでデプロイ実行中の例外スロー(スタックトレース?)をします
$ bundle exec cap staging deploy --dry-run --trace
** Invoke staging (first_time)
** Execute staging
** Invoke load:defaults (first_time)
** Execute load:defaults
[Deprecation Notice] `set :scm, :git` is deprecated.
To ensure your project is compatible with future versions of Capistrano,
remove the :scm setting and instead add these lines to your Capfile after
`require "capistrano/deploy"`:
require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git
** Invoke rbenv:validate (first_time)
** Execute rbenv:validate
** Invoke rbenv:map_bins (first_time)
** Execute rbenv:map_bins
** Invoke bundler:map_bins (first_time)
** Execute bundler:map_bins
** Invoke deploy:set_rails_env (first_time)
** Execute deploy:set_rails_env
** Invoke deploy:set_linked_dirs (first_time)
** Execute deploy:set_linked_dirs
** Invoke deploy:set_rails_env
** Invoke deploy (first_time)
** Invoke deploy:git_confirm (first_time)
** Execute deploy:git_confirm
00:00 deploy:git_confirm
** Execute deploy
** Invoke deploy:starting (first_time)
** Invoke slack:deploy:starting (first_time)
** Execute slack:deploy:starting
** Invoke slack:deploy:updating (first_time)
** Execute slack:deploy:updating
** Invoke deploy:upload (first_time)
** Execute deploy:upload
00:00 deploy:upload
01 mkdir -p /var/www/capistrano_sample_app_v1/shared/config
02 config/database.yml /var/www/capistrano_sample_app_v1/shared/config/database.yml
** Execute deploy:starting
** Invoke deploy:check (first_time)
** Invoke git:check (first_time)
** Invoke git:wrapper (first_time)
** Execute git:wrapper
00:00 git:wrapper
01 mkdir -p /tmp
02 #<StringIO:0x00000000025f9838> /tmp/git-ssh-capistrano_sample_app_v1-staging-webmaster-patche.sh
03 chmod 700 /tmp/git-ssh-capistrano_sample_app_v1-staging-webmaster-patche.sh
04 #<StringIO:0x0000000002617720> /tmp/git-ssh-capistrano_sample_app_v1-staging-webmaster-patche.sh
** Execute git:check
00:00 git:check
01 git ls-remote git@github.com:webmaster-patche/capistrano_sample_app_v1.git HEAD
** Execute deploy:check
** Invoke deploy:check:directories (first_time)
** Execute deploy:check:directories
00:00 deploy:check:directories
01 mkdir -p /var/www/capistrano_sample_app_v1/shared /var/www/capistrano_sample_app_v1/releases
** Invoke deploy:check:linked_dirs (first_time)
** Execute deploy:check:linked_dirs
00:00 deploy:check:linked_dirs
01 mkdir -p /var/www/capistrano_sample_app_v1/shared/bin /var/www/capistrano_sample_app_v1/shared/log /var/www/capistrano_sample_app_v1/shared/tmp/backup /var/www/capistrano_sample_app_v1/shared/tmp/pids /var/www/capistrano_sample_app_v1/shared/tmp/cache /var/www/capistrano_sample_app_v1/shared/t…
** Invoke deploy:check:make_linked_dirs (first_time)
** Execute deploy:check:make_linked_dirs
00:00 deploy:check:make_linked_dirs
01 mkdir -p /var/www/capistrano_sample_app_v1/shared/config
** Invoke deploy:check:linked_files (first_time)
** Execute deploy:check:linked_files
** Invoke deploy:set_previous_revision (first_time)
** Execute deploy:set_previous_revision
** Invoke deploy:started (first_time)
** Execute deploy:started
** Invoke deploy:updating (first_time)
** Invoke deploy:new_release_path (first_time)
** Execute deploy:new_release_path
** Invoke git:create_release (first_time)
** Invoke git:update (first_time)
** Invoke git:clone (first_time)
** Invoke git:wrapper
** Execute git:clone
00:00 git:clone
The repository mirror is at /var/www/capistrano_sample_app_v1/repo
The repository mirror is at /var/www/capistrano_sample_app_v1/repo
** Execute git:update
00:00 git:update
01 git remote set-url origin git@github.com:webmaster-patche/capistrano_sample_app_v1.git
02 git remote update --prune
** Execute git:create_release
00:00 git:create_release
01 mkdir -p /var/www/capistrano_sample_app_v1/releases/*******
02 git archive master | /usr/bin/env tar -x -f - -C /var/www/capistrano_sample_app_v1/releases/*******
** Invoke slack:deploy:updating
** Execute deploy:updating
** Invoke deploy:set_current_revision (first_time)
** Invoke git:set_current_revision (first_time)
** Execute git:set_current_revision
** Execute deploy:set_current_revision
00:00 deploy:set_current_revision
01 echo "" > REVISION
** Invoke deploy:symlink:shared (first_time)
** Execute deploy:symlink:shared
** Invoke deploy:symlink:linked_files (first_time)
** Execute deploy:symlink:linked_files
00:00 deploy:symlink:linked_files
01 mkdir -p /var/www/capistrano_sample_app_v1/releases/*******/config
** Invoke deploy:symlink:linked_dirs (first_time)
** Execute deploy:symlink:linked_dirs
00:00 deploy:symlink:linked_dirs
01 mkdir -p /var/www/capistrano_sample_app_v1/releases/******* /var/www/capistrano_sample_app_v1/releases/*******/tmp /var/www/capistrano_sample_app_v1/releases/*******/vendor /var/www/capistrano_sample_app_v1/releases/*******/public
** Invoke deploy:updated (first_time)
** Invoke bundler:install (first_time)
** Execute bundler:install
00:00 bundler:install
The Gemfile's dependencies are satisfied, skipping installation
The Gemfile's dependencies are satisfied, skipping installation
** Execute deploy:updated
** Invoke deploy:compile_assets (first_time)
** Invoke deploy:set_rails_env
** Execute deploy:compile_assets
** Invoke deploy:assets:precompile (first_time)
** Execute deploy:assets:precompile
** Invoke deploy:assets:backup_manifest (first_time)
** Execute deploy:assets:backup_manifest
** Invoke deploy:cleanup_assets (first_time)
** Invoke deploy:set_rails_env
** Execute deploy:cleanup_assets
** Invoke deploy:normalize_assets (first_time)
** Invoke deploy:set_rails_env
** Execute deploy:normalize_assets
** Invoke deploy:migrate (first_time)
** Invoke deploy:set_rails_env
** Execute deploy:migrate
** Invoke deploy:publishing (first_time)
** Execute deploy:publishing
** Invoke deploy:symlink:release (first_time)
** Execute deploy:symlink:release
00:00 deploy:symlink:release
01 ln -s /var/www/capistrano_sample_app_v1/releases/******* /var/www/capistrano_sample_app_v1/releases/current
02 mv /var/www/capistrano_sample_app_v1/releases/current /var/www/capistrano_sample_app_v1
** Invoke deploy:published (first_time)
** Execute deploy:published
** Invoke deploy:finishing (first_time)
** Execute deploy:finishing
** Invoke deploy:cleanup (first_time)
** Execute deploy:cleanup
** Invoke slack:deploy:updated (first_time)
** Execute slack:deploy:updated
** Invoke deploy:finished (first_time)
** Execute deploy:finished
** Invoke deploy:log_revision (first_time)
** Execute deploy:log_revision
00:00 deploy:log_revision
01 echo "Branch master (at ) deployed as release 20200108015441 by webmaster-patche" >> /var/www/capistrano_sample_app_v1/revisions.log
実行
-
設定が一通り終わったら、次はデバッグではなく実際に実行でチェックしてみます
-
trace
オプションでデプロイ実行中の例外スロー(スタックトレース?)をします
$ bundle exec cap staging deploy --trace
** Invoke staging (first_time)
** Execute staging
** Invoke load:defaults (first_time)
** Execute load:defaults
[Deprecation Notice] `set :scm, :git` is deprecated.
To ensure your project is compatible with future versions of Capistrano,
remove the :scm setting and instead add these lines to your Capfile after
`require "capistrano/deploy"`:
require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git
** Invoke rbenv:validate (first_time)
** Execute rbenv:validate
** Invoke rbenv:map_bins (first_time)
** Execute rbenv:map_bins
** Invoke bundler:map_bins (first_time)
** Execute bundler:map_bins
** Invoke deploy:set_rails_env (first_time)
** Execute deploy:set_rails_env
** Invoke deploy:set_linked_dirs (first_time)
** Execute deploy:set_linked_dirs
** Invoke deploy:set_rails_env
** Invoke deploy (first_time)
** Invoke deploy:git_confirm (first_time)
** Execute deploy:git_confirm
00:00 deploy:git_confirm
[git:confirm] Skip git confirm
** Execute deploy
** Invoke deploy:starting (first_time)
** Invoke slack:deploy:starting (first_time)
** Execute slack:deploy:starting
** Invoke slack:deploy:updating (first_time)
** Execute slack:deploy:updating
** Invoke deploy:upload (first_time)
** Execute deploy:upload
00:00 deploy:upload
Uploading config/database.yml 100.0%
** Execute deploy:starting
** Invoke deploy:check (first_time)
** Invoke git:check (first_time)
** Invoke git:wrapper (first_time)
** Execute git:wrapper
00:00 git:wrapper
01 mkdir -p /tmp
✔ 01 %user%@%hostname% 0.139s
Uploading /tmp/git-ssh-capistrano_sample_app_v1-staging-%user%.sh 100.0%
02 chmod 700 /tmp/git-ssh-capistrano_sample_app_v1-staging-%user%.sh
✔ 02 %user%@%hostname% 0.142s
** Execute git:check
00:00 git:check
01 git ls-remote git@github.com:%user%/capistrano_sample_app_v1.git HEAD
01 78ee082f5b26fcac1ad4aa25410dcc3d1b32d51e HEAD
✔ 01 %user%@%hostname% 1.904s
** Execute deploy:check
** Invoke deploy:check:directories (first_time)
** Execute deploy:check:directories
00:02 deploy:check:directories
01 mkdir -p /var/www/capistrano_sample_app_v1/shared /var/www/capistrano_sample_app_v1/releases
✔ 01 %user%@%hostname% 0.097s
** Invoke deploy:check:linked_dirs (first_time)
** Execute deploy:check:linked_dirs
00:02 deploy:check:linked_dirs
01 mkdir -p /var/www/capistrano_sample_app_v1/shared/log /var/www/capistrano_sample_app_v1/shared/tmp/pids /var/www/capistrano_sample_app_v1/shared/tmp/cache /var/www/capistrano_sample_app_v1/shared/tmp/sockets /var/www/capistrano_sample_app_v1/shared/vendor/bundle /var/www/capistrano_sample_app_v1/shared/public/ass…
✔ 01 %user%@%hostname% 0.140s
** Invoke deploy:check:make_linked_dirs (first_time)
** Execute deploy:check:make_linked_dirs
00:02 deploy:check:make_linked_dirs
01 mkdir -p /var/www/capistrano_sample_app_v1/shared/config
✔ 01 %user%@%hostname% 0.140s
** Invoke deploy:check:linked_files (first_time)
** Execute deploy:check:linked_files
** Invoke deploy:set_previous_revision (first_time)
** Execute deploy:set_previous_revision
** Invoke deploy:started (first_time)
** Execute deploy:started
** Invoke deploy:updating (first_time)
** Invoke deploy:new_release_path (first_time)
** Execute deploy:new_release_path
** Invoke git:create_release (first_time)
** Invoke git:update (first_time)
** Invoke git:clone (first_time)
** Invoke git:wrapper
** Execute git:clone
00:03 git:clone
The repository mirror is at /var/www/capistrano_sample_app_v1/repo
** Execute git:update
00:03 git:update
01 git remote set-url origin git@github.com:%user%/capistrano_sample_app_v1.git
✔ 01 %user%@%hostname% 0.142s
02 git remote update --prune
02 Fetching origin
02 remote: Enumerating objects: 12, done.
re…ote: Counting objects: 50% (6/12)
remote: Compressing objects: 100% (3/3), done.
02 remote: Total 7 (delta 4), reused 7 (delta 4), pack-reused 0
Unpacking objects… 100% (7/7) (1/7)
02 From github.com:%user%/capistrano_sample_app_v1
02 1b9edaa..78ee082 master -> master
✔ 02 %user%@%hostname% 2.175s
** Execute git:create_release
00:06 git:create_release
01 mkdir -p /var/www/capistrano_sample_app_v1/releases/*******
✔ 01 %user%@%hostname% 0.139s
02 git archive master | /usr/bin/env tar -x -f - -C /var/www/capistrano_sample_app_v1/releases/*******
✔ 02 %user%@%hostname% 0.154s
** Invoke slack:deploy:updating
** Execute deploy:updating
** Invoke deploy:set_current_revision (first_time)
** Invoke git:set_current_revision (first_time)
** Execute git:set_current_revision
** Execute deploy:set_current_revision
00:06 deploy:set_current_revision
01 echo "78ee082f5b26fcac1ad4aa25410dcc3d1b32d51e" > REVISION
✔ 01 %user%@%hostname% 0.140s
** Invoke deploy:symlink:shared (first_time)
** Execute deploy:symlink:shared
** Invoke deploy:symlink:linked_files (first_time)
** Execute deploy:symlink:linked_files
00:07 deploy:symlink:linked_files
01 mkdir -p /var/www/capistrano_sample_app_v1/releases/*******/config
✔ 01 %user%@%hostname% 0.141s
02 rm /var/www/capistrano_sample_app_v1/releases/*******/config/database.yml
✔ 02 %user%@%hostname% 0.138s
03 ln -s /var/www/capistrano_sample_app_v1/shared/config/database.yml /var/www/capistrano_sample_app_v1/releases/*******/config/database.yml
✔ 03 %user%@%hostname% 0.145s
** Invoke deploy:symlink:linked_dirs (first_time)
** Execute deploy:symlink:linked_dirs
00:07 deploy:symlink:linked_dirs
01 mkdir -p /var/www/capistrano_sample_app_v1/releases/******* /var/www/capistrano_sample_app_v1/releases/*******/tmp /var/www/capistrano_sample_app_v1/releases/*******/vendor /var/www/capistrano_sample_app_v1/releases/*******/public
✔ 01 %user%@%hostname% 0.142s
02 rm -rf /var/www/capistrano_sample_app_v1/releases/*******/log
✔ 02 %user%@%hostname% 0.138s
03 ln -s /var/www/capistrano_sample_app_v1/shared/log /var/www/capistrano_sample_app_v1/releases/*******/log
✔ 03 %user%@%hostname% 0.138s
04 ln -s /var/www/capistrano_sample_app_v1/shared/tmp/pids /var/www/capistrano_sample_app_v1/releases/*******/tmp/pids
✔ 04 %user%@%hostname% 0.143s
05 ln -s /var/www/capistrano_sample_app_v1/shared/tmp/cache /var/www/capistrano_sample_app_v1/releases/*******/tmp/cache
✔ 05 %user%@%hostname% 0.137s
06 ln -s /var/www/capistrano_sample_app_v1/shared/tmp/sockets /var/www/capistrano_sample_app_v1/releases/*******/tmp/sockets
✔ 06 %user%@%hostname% 0.136s
07 ln -s /var/www/capistrano_sample_app_v1/shared/vendor/bundle /var/www/capistrano_sample_app_v1/releases/*******/vendor/bundle
✔ 07 %user%@%hostname% 0.138s
08 ln -s /var/www/capistrano_sample_app_v1/shared/public/assets /var/www/capistrano_sample_app_v1/releases/*******/public/assets
✔ 08 %user%@%hostname% 0.138s
** Invoke deploy:updated (first_time)
** Invoke bundler:install (first_time)
** Execute bundler:install
00:11 bundler:install
01 RBENV_ROOT=/usr/local/rbenv RBENV_VERSION=2.6.5 /usr/local/rbenv/bin/rbenv exec bundle install --path /var/www/capistrano_sample_app_v1/shared/bundle --jobs 4 --without development test --deployment --quiet
✔ 01 %user%@%hostname% 0.701s
** Execute deploy:updated
** Invoke deploy:compile_assets (first_time)
** Invoke deploy:set_rails_env
** Execute deploy:compile_assets
** Invoke deploy:assets:precompile (first_time)
** Execute deploy:assets:precompile
** Invoke deploy:assets:backup_manifest (first_time)
** Execute deploy:assets:backup_manifest
** Invoke deploy:cleanup_assets (first_time)
** Invoke deploy:set_rails_env
** Execute deploy:cleanup_assets
** Invoke deploy:normalize_assets (first_time)
** Invoke deploy:set_rails_env
** Execute deploy:normalize_assets
** Invoke deploy:migrate (first_time)
** Invoke deploy:set_rails_env
** Execute deploy:migrate
** Invoke deploy:publishing (first_time)
** Execute deploy:publishing
** Invoke deploy:symlink:release (first_time)
** Execute deploy:symlink:release
00:11 deploy:symlink:release
01 ln -s /var/www/capistrano_sample_app_v1/releases/******* /var/www/capistrano_sample_app_v1/releases/current
✔ 01 %user%@%hostname% 0.142s
02 mv /var/www/capistrano_sample_app_v1/releases/current /var/www/capistrano_sample_app_v1
✔ 02 %user%@%hostname% 0.142s
** Invoke deploy:published (first_time)
** Execute deploy:published
** Invoke deploy:env_publising (first_time)
** Execute deploy:env_publising
00:12 deploy:env_publising
01 cp -a /var/www/capistrano_sample_app_v1/.env /var/www/capistrano_sample_app_v1/releases/*******/.env
✔ 01 %user%@%hostname% 0.137s
** Invoke deploy:restart (first_time)
** Execute deploy:restart
00:12 deploy:restart
01 touch /var/www/capistrano_sample_app_v1/releases/*******/tmp/restart.txt
✔ 01 %user%@%hostname% 0.137s
** Invoke deploy:finishing (first_time)
** Execute deploy:finishing
** Invoke deploy:cleanup (first_time)
** Execute deploy:cleanup
00:12 deploy:cleanup
Keeping 5 of 6 deployed releases on %hostname%
01 rm -rf /var/www/capistrano_sample_app_v1/releases/*******
✔ 01 %user%@%hostname% 0.149s
** Invoke slack:deploy:updated (first_time)
** Execute slack:deploy:updated
** Invoke deploy:finished (first_time)
** Execute deploy:finished
** Invoke deploy:log_revision (first_time)
** Execute deploy:log_revision
00:13 deploy:log_revision
01 echo "Branch master (at 78ee082f5b26fcac1ad4aa25410dcc3d1b32d51e) deployed as release ******* by %user%" >> /var/www/capistrano_sample_app_v1/revisions.log
✔ 01 %user%@%hostname% 0.138s
Rails 5.2以上で気をつけなければならないこと
require': cannot load such file -- bootsnap/setup (LoadError). が発生する場合
- 少なくともRails 5.2系では
bootsnap
はデフォルトでGemfile
に組み込まれている
group :development, :test do
・・・途中省略・・・
# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.1.0', require: false
end
この状態では staging環境の起動失敗する
$ bundle exec rails c -e staging
Traceback (most recent call last):
13: from bin/rails:4:in `<main>'
12: from bin/rails:4:in `require'
11: from /var/www/capistrano_sample_app_v1/shared/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/commands.rb:18:in `<top (required)>'
10: from /var/www/capistrano_sample_app_v1/shared/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/command.rb:46:in `invoke'
9: from /var/www/capistrano_sample_app_v1/shared/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/command/base.rb:65:in `perform'
8: from /var/www/capistrano_sample_app_v1/shared/bundle/ruby/2.6.0/gems/thor-0.20.3/lib/thor.rb:387:in `dispatch'
7: from /var/www/capistrano_sample_app_v1/shared/bundle/ruby/2.6.0/gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'
6: from /var/www/capistrano_sample_app_v1/shared/bundle/ruby/2.6.0/gems/thor-0.20.3/lib/thor/command.rb:27:in `run'
5: from /var/www/capistrano_sample_app_v1/shared/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/commands/console/console_command.rb:95:in `perform'
4: from /var/www/capistrano_sample_app_v1/shared/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/command/actions.rb:14:in `require_application_and_environment!'
3: from /var/www/capistrano_sample_app_v1/shared/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/command/actions.rb:22:in `require_application!'
2: from /var/www/capistrano_sample_app_v1/shared/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/command/actions.rb:22:in `require'
1: from /var/www/capistrano_sample_app_v1/releases/*******/config/application.rb:17:in `<top (required)>'
/var/www/capistrano_sample_app_v1/releases/*******/config/application.rb:17:in `require': cannot load such file -- bootsnap/setup (LoadError)
-
config/boot.rb
を書き換える
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
require 'bundler/setup' # Set up gems listed in the Gemfile.
begin
require 'bootsnap/setup'
env = ENV['RAILS_ENV'] || "development"
Bootsnap.setup(
cache_dir: 'tmp/cache', # キャッシュファイルを保存する path
development_mode: env == 'development', # 現在の作業環境、例えば RACK_ENV, RAILS_ENV など。
load_path_cache: true, # キャッシュで LOAD_PATH を最適化する。
autoload_paths_cache: true, # キャッシュで ActiveSupport による autoload を行う。
disable_trace: true, # (アルファ) `RubyVM::InstructionSequence.compile_option = { trace_instruction: false }`をセットする。
compile_cache_iseq: true, # ISeq キャッシュをコンパイルする
compile_cache_yaml: true # YAML キャッシュをコンパイルする
)
rescue LoadError => e;
end # Speed up boot time by caching expensive operations.
リポジトリ
- 本記事のリポジトリは「webmaster-patche/capistrano_sample_app_v1」にて公開しております