0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

railsアプリをcapsitranoでdeployする時に自動でseedを実行する。けど必要な時だけする。

Posted at

本記事のサマリ

capistranoでrailsアプリをdeployする際に、自動的にseedを流すようにすると、deployの運用的には楽になるが、seedの実行時間が待たされるので、seedファイルが描き変わった時だけ動くように工夫するといいかもという話です。

対象読者

  • capistranoをつかって、railsアプリをデプロイしており、seedの実行は手動でやっているような方
  • seedの実行をcapに任せているが、毎回時間かかっているような方

動作確認バージョン

Capistrano Version: 3.11.2 (Rake Version: 10.3.2)
Rails 5.1.6
ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-darwin18]

経緯

capistranoでデプロイする際に、seedの実行は変更があったときに、手で実行するのは、面倒です。
なので、そういったものは、自動的にやるようにしたいというのが、怠惰なプログラマな正常な欲求です。
でも、自動的にやってみたのはいいものの、毎回実行していると、seedの肥大化に伴って、実行時間の待ち時間がもったいない。
ならば、seedの変更が会った時だけ実行するようにしようというのが敬意です。

方針

やり方はいろいろあると思いますが、seedファイルの変更を検知するために、seedファイルのmd5のハッシュ値をとっておいて、それが切り替わったら実行するというやり方で実現してみました。

実物

以下のように、独自で定義したcapistranoのタスクを、deploy:migrateの後で実行するようにします。

deploy.rb
# 〜中略〜
# deploy用のスクリプトで、migrateの後にdeploy:seedタスクを実行させる
after 'deploy:migrate', 'deploy:seed'
# 〜中略〜

実際に、seedを実行するタスクは以下のようにして、seedファイルのmd5を保持しておき、それを比較して違っていたらseedを実行するような形で実現します。

deploy.cap
# 〜中略〜
  # seedの実行タスクは以下の通り
  # 前提となる情報
  #  release_path: deployされたアプリのパス
  #  shared_path: 別のリリース時でも共有できる共有ディレクトリのパス
  #  seedファイルは、実行されるたびに、トランザクションを貼って洗い替え(delete & insert)することで、冪等性を担保している。
  desc 'Load seed data into database'
  task :seed do
    on roles(:db) do
      within release_path do
        with rails_env: fetch(:rails_env) do
          command = 'db:seed'
          # rakeのコマンドを元に、seedファイルの相対パスを組み立て
          seed_filepath = 'db/seed.rb'
          new_digest_filepath = shared_path.join("new_#{seed_filepath.gsub('/', '_')}.md5")
          digest_filepath     = shared_path.join("#{seed_filepath.gsub('/', '_')}.md5")
          # digestがなかった時にエラーにしないために、事前にtouch
          execute :touch, digest_filepath
          execute :md5sum, "#{seed_filepath} > #{new_digest_filepath}"
          # md5が違っていたらseedを反映するコマンドを実行する
          execute "if [ \"`cat #{new_digest_filepath}`\" != \"`cat #{digest_filepath}`\" ]; then cd #{release_path}; RAILS_ENV=#{ fetch(:rails_env) } bundle exec rake #{command}; mv #{new_digest_filepath} #{digest_filepath}; fi"
          end
        end
      end
    end
  end
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?