asset_syncをcapistranoでのデプロイ時に実行するようにしました。
asset_syncの実行と実行したあとに出来るmanifestファイルのpushが何とかならないかと思い、capistranoのrun_locallyとuploadを使ってみました。
asset_syncで参考にしたサイト:
asset_sync を使ってデプロイを高速化しつつ転送料も節約する
環境
- Rails 4.1.8
- capistrano 3.2.1
- asset_sync 1.1.0
やりたいこと
- asset_sync(asset:precompile)をローカルで実行して、AWS S3にassetを置く
- ソースコードをデプロイする
- ローカルにできる public/assets/manifest〜.jsonをデプロイ先にアップロードする
deploy.rbの記述
# SSHKit.conifg
SSHKit.config.command_map[:rake] = 'bundle exec rake'
namespace :deploy do
desc 'Run asset_sync'
task :asset_sync do
run_locally do
with rails_env: fetch(:rails_env) do
execute :rake, 'assets:precompile'
end
end
end
desc 'Upload manifest'
task :upload_manifest do
on roles(:app) do |host|
if test "[ ! -d #{release_path}/public/assets ]"
execute "mkdir -p #{release_path}/public/assets"
end
file_path = Dir::glob('public/assets/manifest*').first
upload!(file_path, "#{release_path}/public/assets/")
end
end
before :starting, :asset_sync
after :publishing, :upload_manifest
タスクの内容
# SSHKit.conifg
SSHKit.config.command_map[:rake] = 'bundle exec rake'
rakeをbundleで実行したいので、command_mapでbundle exec rake
に設定しています。
file_path = Dir::glob('public/assets/manifest*').first
upload!(file_path, "#{release_path}/public/assets/")
manifestのアップロードですが、Rails4系の場合、manifestのファイル名にハッシュ値がつくので、Dir::glob
でファイル名を取得してuploadに渡すようにしました。アップロード先は、shared_pathではなく、release_pathにしています。shared_pathだと、以前のファイルを消していかないといけないので。
before :starting, :asset_sync
after :publishing, :upload_manifest
あとは、デプロイを開始するまえに、beforeでasset_sync
のタスクを実行して、ソースデプロイ後にafterでupload_manifest
をしてデプロイを完了させています。
capistranoについては、こちらがとても参考になりました。
Capistrano3のデプロイフレームワークの使い方