Capistrano部署进行预编译

Capistrano部署进行预编译

本文介绍了加速资产:使用Rails 3.1/3.2 Capistrano部署进行预编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的部署速度很慢,至少需要3分钟.部署期间缓慢的Capistrano任务是资产:预编译.这大概花费了总部署时间的99%.我怎样才能加快速度?我应该在我的本地计算机上预编译我的资产并将其添加到我的git repo中吗?

My deployments are slow, they take at least 3 minutes. The slow Capistrano task during deploy is assets:precompile. This takes probably 99% of the total deploy time. How can I speed this up? Should I precompile my assets on my local machine and add them to my git repo?

config.assets.initialize_on_precompile = false添加到我的application.rb文件中会使预编译时间缩短了半分钟,但仍然很慢.

Adding config.assets.initialize_on_precompile = false to my application.rb file dropped the precompile time with half a minute, but it is still slow.

推荐答案

想法是,如果您不更改资产,则无需每次都重新编译它们:

The idea is that if you don't change your assets you don't need to recompile them each time:

这是Ben Curtis提出的解决方案用于git部署:

This is the solution that Ben Curtis propose for a deployment with git:

 namespace :deploy do
      namespace :assets do
        task :precompile, :roles => :web, :except => { :no_release => true } do
          from = source.next_revision(current_revision)
          if releases.length <= 1 || capture("cd #{latest_release} && #{source.local.log(from)} vendor/assets/ app/assets/ | wc -l").to_i > 0
            run %Q{cd #{latest_release} && #{rake} RAILS_ENV=#{rails_env} #{asset_env} assets:precompile}
          else
            logger.info "Skipping asset pre-compilation because there were no asset changes"
          end
      end
    end
  end

这是另一种基于资产寿命的方法( https://gist.github.com/2784462 ):

Here is another approach based on asset age (https://gist.github.com/2784462) :

set :max_asset_age, 2 ## Set asset age in minutes to test modified date against.

after "deploy:finalize_update", "deploy:assets:determine_modified_assets", "deploy:assets:conditionally_precompile"

namespace :deploy do
  namespace :assets do

    desc "Figure out modified assets."
    task :determine_modified_assets, :roles => assets_role, :except => { :no_release => true } do
      set :updated_assets, capture("find #{latest_release}/app/assets -type d -name .git -prune -o -mmin -#{max_asset_age} -type f -print", :except => { :no_release => true }).split
    end

    desc "Remove callback for asset precompiling unless assets were updated in most recent git commit."
    task :conditionally_precompile, :roles => assets_role, :except => { :no_release => true } do
      if(updated_assets.empty?)
        callback = callbacks[:after].find{|c| c.source == "deploy:assets:precompile" }
        callbacks[:after].delete(callback)
        logger.info("Skipping asset precompiling, no updated assets.")
      else
        logger.info("#{updated_assets.length} updated assets. Will precompile.")
      end
    end

  end
end

如果您希望在本地预编译资产,则可以使用以下任务:

If you prefer to precompile your assets locally you can use this task:

namespace :deploy do
  namespace :assets do
    desc 'Run the precompile task locally and rsync with shared'
    task :precompile, :roles => :web, :except => { :no_release => true } do
      from = source.next_revision(current_revision)
      if releases.length <= 1 || capture("cd #{latest_release} && #{source.local.log(from)} vendor/assets/ app/assets/ | wc -l").to_i > 0
        %x{bundle exec rake assets:precompile}
        %x{rsync --recursive --times --rsh=ssh --compress --human-readable --progress public/assets #{user}@#{host}:#{shared_path}}
        %x{bundle exec rake assets:clean}
      else
        logger.info 'Skipping asset pre-compilation because there were no asset changes'
      end
    end
  end
end

另一种有趣的方法可能是使用 git hook .例如,您可以将此代码添加到.git/hooks/pre-commit中,以检查资产文件中是否存在任何差异,并最终对其进行预编译并将其添加到当前提交中.

Another interesting approach can be that of using a git hook.For example you can add this code to .git/hooks/pre-commit which checks if there are any differences in the assets files and eventually precompiles them and add them to the current commit.

#!/bin/bash

# source rvm and .rvmrc if present
[ -s "$HOME/.rvm/scripts/rvm" ] && . "$HOME/.rvm/scripts/rvm"
[ -s "$PWD/.rvmrc" ] && . "$PWD/.rvmrc"

# precompile assets if any have been updated
if git diff-index --name-only HEAD | egrep '^app/assets' >/dev/null ; then
  echo 'Precompiling assets...'
  rake assets:precompile:all RAILS_ENV=production RAILS_GROUPS=assets
  git add public/assets/*
fi

如果您决定使用此方法,则可能需要更改config/environments/development.rb添加:

If you decide to use this approach you would probably need to change your config/environments/development.rb adding:

config.assets.prefix = '/assets_dev'

因此,在开发过程中,您将不会使用预编译的资产.

So that while in development you won't serve the precompiled assets.

这篇关于加速资产:使用Rails 3.1/3.2 Capistrano部署进行预编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 12:16