LoginSignup
7
9

More than 5 years have passed since last update.

Capistrano3で `deploy_via :copy` 相当のデプロイをする(CakePHP3用サンプル付き)

Last updated at Posted at 2016-09-01

Capistrano3では、Capistrano2にあった deploy_via :copy が標準で導入されず、プライベートリポジトリからのソースコードのデプロイがしにくい状況でした。

当時、涙をのんでCapistrano2の継続利用を選択した人も多いと思います。

しかし、今はGitのリポジトリであれば、capistrano-scm-gitcopy.gem を使って簡単に deploy_via :copy 相当のデプロイが可能です。

というわけで、手順を追って環境を作ってみます。

Capistrano3の環境を構築する

適当なディレクトリを作ってGemfileを作成します。

$ bundle init

Gemfileには capistrano だけでなく、capistrano-scm-gitcopy も記載します。

source "https://rubygems.org"

gem "capistrano"
gem "capistrano-scm-gitcopy"

Capistrano3をインストールして初期設定をします。

$ bundle install
$ bundle exec cap install

Capistrano2の capistrano-ext-multistage 相当の環境切り替えは既にCapistrano3では標準搭載されているので、それを利用する形で実施します。

ディレクトリ構成

.
├── Capfile
├── Gemfile
├── Gemfile.lock
├── config
│   ├── deploy
│   │   ├── production.rb
│   │   └── staging.rb
│   ├── deploy.rb
│   ├── production
│   │   └── app_local.php
│   └── staging
│       └── app_local.php
├── lib
│   └── capistrano
│       └── tasks
└── log
    └── capistrano.log

Capistrano3では、app_local.php のようなファイルはリポジトリに含めずデプロイ先のsharedディレクトリ置くことを推奨していますが、今回はローカルファイルをアップロードをする方法を取ります。

deploy.rb

かなり雑ですが、CakePHP3の場合のサンプルはこんな感じでしょうか。

# config valid only for current version of Capistrano
lock '3.6.1'

set :application, 'my_app_name'
set :repo_url, 'git@github.com:k1LoW/my_app_name.git'

# Default branch is :master
# ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp

set :deploy_to, '/var/www/deploy/to'
set :scm, :gitcopy

set :pty, true

append :linked_dirs, 'tmp/cache/models', 'tmp/cache/persistent', 'tmp/cache/views', 'logs'

set :keep_releases, 5

namespace :deploy do
  desc 'Setup CakePHP app'
  task :setapp do
    on roles(:all) do
      within release_path do
        # @notice https://github.com/capistrano/capistrano/issues/719
        execute :sudo, :chmod, '-R', '777', 'tmp/'
        execute :rm, '-rf', 'tmp/cache/models/*'
        execute :rm, '-rf', 'tmp/cache/persistent/*'
        execute :rm, '-rf', 'tmp/cache/views/*'
        execute :curl, '-s', 'http://getcomposer.org/installer', '|', 'php'
        execute :php, 'composer.phar', 'install', '--no-dev'
      end
      upload!("#{File.dirname(__FILE__)}/#{fetch(:stage)}/app_local.php", "#{release_path}/config/app_local.php")
    end
  end

  desc 'Migrate database'
  task :migrate do
    on roles(:all) do
      within release_path do
        execute 'bin/cake', 'migrations', 'migrate'
      end
    end
  end
end

after 'deploy:symlink:linked_dirs', 'deploy:setapp'
after 'deploy:setapp', 'deploy:migrate'

ポイントは set :scm, :gitcopy ですね。これで deploy_via :copy と同じような動きをします。

あとは

$ bundle exec cap staging deploy

$ bundle exec cap production deploy

を実行したら、プライベートリポジトリからソースコードが一旦ローカルにcloneされて、tarでまとめてデプロイが開始されます。

これで、CakePHP3のBakerの皆さんも思う存分Capistrano3が使えますね!


以下、注意点

within *_path do が withinじゃなくなる問題

スペースが入っている文字列でコマンドを表すと発動します。これはバックエンドのSSHKitの仕様っぽいので、しっかり分割しましょう。

実行時にSkipping taskエラーがでる問題

Skipping task `gitcopy:set_current_revision'.
Capistrano tasks may only be invoked once. Since task `gitcopy:set_current_revision' was previously invoked, invoke("gitcopy:set_current_revision") at /Users/k1low/.anyenv/envs/rbenv/versions/2.3.1/lib/ru
by/gems/2.3.0/gems/capistrano-3.6.1/lib/capistrano/tasks/deploy.rake:228 will be skipped.
If you really meant to run this task again, first call Rake::Task["gitcopy:set_current_revision"].reenable
THIS BEHAVIOR MAY CHANGE IN A FUTURE VERSION OF CAPISTRANO. Please join the conversation here if this affects you.
https://github.com/capistrano/capistrano/issues/1686

これは、Rakeの #invoke は「1回実行すると、reenableを明示的に実行しないかぎり、同じタスクが2回目以降実行できなくなる」仕様らしいのですが、それがCapistranoでの利用想定と合っていないことによる問題のようです。
(Capistranoとしては、対応を議論中のようにみえます)。

実際は capistrano-scm-gitcopy.gem でエラーが出ているのですが、今のところ問題は発生していないので大丈夫だと思います。

7
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
9