Edited at

CapistranoのdeployタスクをVagrantマシンに適用するまで

More than 3 years have passed since last update.

Capistrano3を使って書いたdeployタスクをいきなり本番に適用するのは怖いので、Vagrantの仮想マシンにdeployして様子を見たい。cap deploy実行までやる。

このドキュメントではプロジェクトリポジトリを仮想マシンに撒くところまで扱うので、capistrano-rbenv等を使ってrubyを併せてまく所等は割愛する。


やりたいこと


  • Mac Book ProからVagrantで立てた仮想マシンへcap deploy

  • capのstaging名はdevelopmentとし、ユースケースとしては本番deploy前にvagrantへdeployして動くかカジュアルに確認する用途

  • 仮想マシン側にsshログインしなくて済む手順にする。vagrant upした直後にbundle exec cap development deployで通ればOK

  • アプリとしてRails製のOSSでグラフツールの yohoushiをdeployする

なお、vagrantに対してcap development deployが通るところまでやるが、rubyを入れるところや仮想マシン側でアプリをbundle installするところは省略する。


git repository

capistranoタスク保存するgit repository用意する。今回のはyohoushi-capにおいた。


Vagrantfile

こうなる。後のcapistranoに記述するsshのポート情報を揃える必要があるのと、guest_portの設定以外にforwarded_portの設定を上書く必要があった。vagrant upで仮想マシンを起動しておく。


Vagrantfile

# -*- mode: ruby -*-

# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

$script = <<SCRIPT
yum -y install git
SCRIPT
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.define :deploydst do |c|
c.vm.hostname = 'deploydst'
# Override default nat port for ssh
# c.f. https://github.com/mitchellh/vagrant/issues/3232
c.vm.network :forwarded_port, guest: 22, host: 12222, id: "ssh"
c.ssh.guest_port = 12222
c.vm.provision "shell", inline: $script
c.vm.provider :virtualbox do |provider, override|
override.vm.box = "chef/centos-6.5"
end
end
end



ssh-agent

deploy元(今回の場合はMac Book Pro)にてssh秘密鍵をssh-agentに予め登録しておく。こうしておくとvagrantの仮想マシン側に秘密鍵を置かずにgithub.comからpullできる。

$ ssh-add  ~/.ssh/id_rsa      # github.com登録済み公開鍵の対の秘密鍵


Gemfile

Gemfileを作ってbundle installする


Gemfile

# A sample Gemfile

source "https://rubygems.org"

gem 'capistrano', '~> 3.3.0'
gem 'capistrano-safe-deploy-to', '~> 1.1.1'


capistrano-safe-deploy-toについては後述します。


ひな形ファイルを生成する

cap installコマンドでひな形を作る

$ bundle exec cap install STAGES=development

今回はお試しなのでステージはdevelopmentのみでよいのでSTAGES=development指定で。

作成したファイルのうち、以下をとりあえず修正。ssh_optionsでvagrantの環境を指定してるところがポイント。


config/deploy.rb

set :application, 'yohoushi'

set :repo_url, 'git@github.com:yohoushi/yohoushi.git'
set :deploy_to, '/var/app/yohoushi'


config/deploy/development.rb

server 'localhost', user: 'vagrant', roles: %w{web app}, my_property: :my_value

set :ssh_options, {
port: 12222,
keys: %w(~/.vagrant.d/insecure_private_key),
forward_agent: true,
auth_methods: %w(publickey)
}



deploy

おもむろにcap development deployを実行すると以下のエラーのとおりmkdir -p に失敗する。

これは:deploy_toで指定した/var/app/yohoushiディレクトリが無いが、deployタスクの中で最初に呼ばれるタスクでmkdir -p #{deploy_to}/shared #{deploy_to/releases}するからであるが、解決策があって後述してる。

 $ bundle exec cap development deploy

INFO [d02dfa4c] Running /usr/bin/env mkdir -p /tmp/yohoushi/ as vagrant@localhost
DEBUG [d02dfa4c] Command: /usr/bin/env mkdir -p /tmp/yohoushi/
DEBUG Uploading /tmp/yohoushi/git-ssh.sh 0.0%
INFO Uploading /tmp/yohoushi/git-ssh.sh 100.0%
INFO [c31495af] Running /usr/bin/env chmod +x /tmp/yohoushi/git-ssh.sh as vagrant@localhost
DEBUG [c31495af] Command: /usr/bin/env chmod +x /tmp/yohoushi/git-ssh.sh
INFO [cf2b4766] Running /usr/bin/env git ls-remote --heads git@github.com:yohoushi/yohoushi.git as vagrant@localhost
DEBUG [cf2b4766] Command: ( GIT_ASKPASS=/bin/echo GIT_SSH=/tmp/yohoushi/git-ssh.sh /usr/bin/env git ls-remote --heads git@github.com:yohoushi/yohoushi.git )
DEBUG [cf2b4766] Warning: Permanently added the RSA host key for IP address '192.30.252.130' to the list of known hosts.
DEBUG [cf2b4766] e79da3d727a6e1122c9170fe69d48a1ca536662b refs/heads/delete-tagged-graphs-fix-button
DEBUG [cf2b4766] 18e7dec95011f77a82e907e1e4b4541ca08cd92e refs/heads/footer
DEBUG [cf2b4766] 2cf4f53873e0cb24790d3885151ed82dc3fc9b62 refs/heads/gh-pages
DEBUG [cf2b4766] 17e868a591875dccd0d21b1486d8aa6b42a5e7c4 refs/heads/master
INFO [9cd2ea40] Running /usr/bin/env mkdir -p /var/app/yohoushi/shared /var/app/yohoushi/releases as vagrant@localhost
DEBUG [9cd2ea40] Command: /usr/bin/env mkdir -p /var/app/yohoushi/shared /var/app/yohoushi/releases
DEBUG [9cd2ea40] mkdir:
DEBUG [9cd2ea40] cannot create directory `/var/app'
DEBUG [9cd2ea40] : Permission denied
DEBUG [9cd2ea40]
DEBUG [9cd2ea40] mkdir:
DEBUG [9cd2ea40] cannot create directory `/var/app'
DEBUG [9cd2ea40] : Permission denied
DEBUG [9cd2ea40]
(Backtrace restricted to imported tasks)
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as vagrant@localhost: mkdir exit status: 1
mkdir stdout: Nothing written
mkdir stderr: mkdir: cannot create directory `/var/app': Permission denied
mkdir: cannot create directory `/var/app': Permission denied

SSHKit::Command::Failed: mkdir exit status: 1
mkdir stdout: Nothing written
mkdir stderr: mkdir: cannot create directory `/var/app': Permission denied
mkdir: cannot create directory `/var/app': Permission denied

Tasks: TOP => deploy:check:directories
(See full trace by running task with --trace)
The deploy has failed with an error: Exception while executing as vagrant@localhost: mkdir exit status: 1
mkdir stdout: Nothing written
mkdir stderr: mkdir: cannot create directory `/var/app': Permission denied
mkdir: cannot create directory `/var/app': Permission denied

deploy_toで指定したディレクトリ以下はリモート実行ユーザで書き込める状態にないと最初に失敗してしまう。ここでつまづく人が多いみたい。自前でmkdir -pしてchownしようかとおもったが capistrano-safe-deploy-to を使うと最初にディレクトリを作ってくれるみたいなので以下のようにする。


Gemfile

# A sample Gemfile

source "https://rubygems.org"

gem 'capistrano', '~> 3.3.0'
gem 'capistrano-safe-deploy-to', '~> 1.1.1' # 追加



Capfile

# Include default deployment tasks

require 'capistrano/deploy'

# https://github.com/capistrano-plugins/capistrano-safe-deploy-to
require 'capistrano/safe_deploy_to' # 追加

(以下略)
...


これでbundle exec cap development deployが通った。

というわけでうまくいった。

この後はVagrant側にrubyが無いのでhttps://github.com/capistrano/rbenv などを使っていく。