Capistrano 3 在 assets:precompile 上失败

Capistrano 3 fails on assets:precompile

我无法在 assets:precompile 上部署我的 Rails 4 应用程序并出现奇怪的错误。任务似乎无法使用已安装的宝石。 在本地机器上的开发和生产环境中,一切都完美无缺。部分部署日志:

INFO[286bfe45] Running ~/.rvm/bin/rvm 2.2.0@gemset do bundle install --binstubs /var/www/app/shared/bin --path /var/www/app/shared/bundle --without development test --deployment --quiet on app.com
DEBUG[286bfe45] Command: cd /var/www/app/releases/20150411140229 && ~/.rvm/bin/rvm 2.2.0@gemset do bundle install --binstubs /var/www/app/shared/bin --path /var/www/app/shared/bundle --without development test --deployment --quiet
INFO[286bfe45] Finished in 2.512 seconds with exit status 0 (successful).
DEBUG[6abacc25] Running /usr/bin/env if test ! -d /var/www/app/releases/20150411140229; then echo "Directory does not exist '/var/www/app/releases/20150411140229'" 1>&2; false; fi on app.com
DEBUG[6abacc25] Command: if test ! -d /var/www/app/releases/20150411140229; then echo "Directory does not exist '/var/www/app/releases/20150411140229'" 1>&2; false; fi
DEBUG[6abacc25] Finished in 0.252 seconds with exit status 0 (successful).
INFO[6a11bfd6] Finished in 1.650 seconds with exit status 0 (successful).
DEBUG[9a60b6ea] Running /usr/bin/env if test ! -d /var/www/app/releases/20150411140229; then echo "Directory does not exist '/var/www/app/releases/20150411140229'" 1>&2; false; fi on app.com
DEBUG[9a60b6ea] Command: if test ! -d /var/www/app/releases/20150411140229; then echo "Directory does not exist '/var/www/app/releases/20150411140229'" 1>&2; false; fi
DEBUG[9a60b6ea] Finished in 0.252 seconds with exit status 0 (successful).
INFO[926b14e1] Running ~/.rvm/bin/rvm 2.2.0@gemset do bundle exec rake assets:precompile on app.com
DEBUG[926b14e1] Command: cd /var/www/app/releases/20150411140229 && ( RAILS_ENV=production ~/.rvm/bin/rvm 2.2.0@gemset do bundle exec rake assets:precompile )
DEBUG[926b14e1]         I, [2015-04-11T14:02:51.203678 #18205]  INFO -- : Writing /var/www/app/releases/20150411140229/public/assets/apple-touch-icon-114x114-precomposed-305f00ea8c7d006b84bb4fae81f9560f.png
DEBUG[926b14e1]         I, [2015-04-11T14:02:51.230319 #18205]  INFO -- : Writing /var/www/app/releases/20150411140229/public/assets/projects/project-item-engine-rails-879f2b31347734136f7381f19bb9f6a3.png
DEBUG[926b14e1]         I, [2015-04-11T14:02:51.233698 #18205]  INFO -- : Writing /var/www/app/releases/20150411140229/public/assets/projects/projects-list-header-57d1dcc1cc60e2eb39438cb1845a9aa2.jpg
DEBUG[926b14e1]         I, [2015-04-11T14:02:51.236956 #18205]  INFO -- : Writing /var/www/app/releases/20150411140229/public/assets/rails-31b23f13156504238438fdd89afe6fd6.png
DEBUG[926b14e1]         I, [2015-04-11T14:02:51.237889 #18205]  INFO -- : Writing /var/www/app/releases/20150411140229/public/assets/sprites/blog-color-fd3e21aa29714c4881b34b34b4980ba9.png
DEBUG[926b14e1]         I, [2015-04-11T14:02:51.284081 #18205]  INFO -- : Writing /var/www/app/releases/20150411140229/public/assets/application-659c280b13b0f592813748b6abb50b74.js
DEBUG[926b14e1]         I, [2015-04-11T14:02:51.311349 #18205]  INFO -- : Writing /var/www/app/releases/20150411140229/public/assets/front-9b21c4b4182f885f99929c6f71639a44.js
DEBUG[926b14e1]         rake aborted!
DEBUG[926b14e1]         Sass::SyntaxError: Undefined mixin 'sprites-sprite'.
DEBUG[926b14e1]           (in /var/www/app/releases/20150411140229/app/assets/stylesheets/static.css.scss:96)
DEBUG[926b14e1]         /var/www/app/releases/20150411140229/app/assets/stylesheets/static.css.scss:96:in `sprites-sprite'
DEBUG[926b14e1]         /var/www/app/releases/20150411140229/app/assets/stylesheets/static.css.scss:96
DEBUG[926b14e1]         /var/www/app/shared/bundle/ruby/2.2.0/gems/sass-3.2.19/lib/sass/tree/visitors/perform.rb:253:in `visit_mixin'
DEBUG[926b14e1]         /var/www/app/shared/bundle/ruby/2.2.0/gems/sass-3.2.19/lib/sass/tree/visitors/base.rb:37:in `visit'

我认为问题在于放置宝石。日志的第一行告诉我 /var/www/app/shared/bundle 中的所有宝石,这是事实 — 它们确实存在。但是如果我 运行 rvm 2.2.0@gemset do gem list 作为部署用户,我在列表中看不到已安装的 gem:

deployer@server:/var/www/app/current$ rvm 2.2.0@gemset do gem list

*** LOCAL GEMS ***

bigdecimal (1.2.6)
bundler (1.8.4)
bundler-unload (1.0.2)
executable-hooks (1.3.2)
gem-wrappers (1.2.7)
io-console (0.4.3)
json (1.8.1)
minitest (5.4.3)
power_assert (0.2.2)
psych (2.0.8)
rake (10.4.2)
rdoc (4.2.0)
rubygems-bundler (1.4.4)
rvm (1.11.3.9)
test-unit (3.0.8)

当我从应用程序文件夹 运行 bundle 时,我可以看到已安装 gem 的完整列表:

deployer@server:/var/www/app/current$ bundle
Using rake 10.4.2
Using sass 3.2.19
Using bootstrap-sass 3.1.1.1
Using compass 0.12.7
Using breakpoint 2.0.7
Using compass-rails 2.0.0
Using sprockets 2.11.0
Using sprockets-rails 2.2.2
/* removed some lines to save space */
Using rails 4.1.8
Using sass-rails 4.0.3
Using uglifier 2.5.0
Using unicorn 4.8.3
Bundle complete! 39 Gemfile dependencies, 87 gems now installed.
Gems in the groups development and test were not installed.
Bundled gems are installed into /var/www/app/shared/bundle.

我在单用户模式下使用 rvm 进行开发和生产,我的一些文件在这里:

# deploy.rb
lock '3.2.1'

set :application, 'App'
set :repo_url, 'git@bitbucket.org:app/app.com.git'
set :deploy_to, '/var/www/app'

set :rvm_ruby_version, '2.2.0@gemset'
set :unicorn_env, 'production'
set :rails_env, :production
set :linked_files, %w{config/database.yml config/secrets.yml config/scp.yml}

set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
namespace :deploy do

    desc 'Restart application'
    task :restart do
        invoke 'unicorn:restart'
    end

    after :restart, :clear_cache do
        on roles(:web), in: :groups, limit: 3, wait: 10 do
        end
    end

after :publishing, :restart
end

Capfile

# Capfile
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano3/unicorn'
require 'whenever/capistrano'
require 'capistrano/rvm'
require 'capistrano/bundler'
require 'capistrano/rails'

Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

Front.css.scss 在 application.rb

中设置为预编译
# front.css.scss
@import "compass";
@import "compass/utilities/sprites";
@import "sprites/*.png";
@include all-sprites-sprites;
@import "breakpoint";
$breakpoint-tiny : 0 660px;

@import "static";

例如static.css.scss:

/* static.css.scss */
.blog {
    @include sprites-sprite(blog-gray);
    &:hover {
        @include sprites-sprite(blog-color);
    }
}

如果我从 static.css.scss 中删除所有混入,部署将成功完成。

我解决了这个问题,它与 capistrano 甚至 rvm 无关。 我为我的应用程序使用了两种布局:front.html.slim 和 admin.html.slim,每个布局都有一个专用样式表:front.cssadmin.css.

front.css.scss 中,我使用了以下 (sass) 语法:

@import "compass";
@import "compass/utilities/sprites";

虽然 admin.css.scss 使用了 Sprocket 的语法:

/*
 *= require base
 *= require posts
 *= require projects

在我将 admin.css.scss 更改为实际的 sass 语法后,assets:precompile 任务成功完成:

 @import "base";
 @import "posts";
 @import "projects";

感谢@RAJ 的建议。