为什么 Capistrano 部署在 assets:precompile 失败且没有错误?
Why does Capistrano deployment fail at assets:precompile without error?
我已经尝试了所有我能想到的方法,但我无法让部署工作。
该应用程序需要部署到由 Alwaysdata 和 运行 ruby 2.6.2 托管的 VPS,使用 Capistrano 进行部署。
这是一个 Rails 6.0.2.2 应用程序,对 JS 使用 webpack,对遗留脚本、所有图像和 CSS 使用 sprockets。
# On local machine (MacOS)
$ bundle exec cap production deploy
00:00 git:wrapper
00:01 git:check
00:03 deploy:check:directories
00:03 deploy:check:linked_dirs
00:03 deploy:check:make_linked_dirs
00:05 git:clone
00:06 git:update
00:08 git:create_release
00:10 deploy:set_current_revision
00:10 deploy:symlink:linked_files
00:12 deploy:symlink:linked_dirs
00:18 deploy:config:bundler
00:20 bundler:install
00:20 deploy:assets:precompile
#<Thread:0x00007fb35ba959f0@/Users/Goulven/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/sshkit-1.21.0/lib/sshkit/runners/parallel.rb:10 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
/Users/Goulven/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/sshkit-1.21.0/lib/sshkit/command.rb:97:in `exit_status=': rake exit status: 1 (SSHKit::Command::Failed)
rake stdout: Nothing written
rake stderr: Nothing written
INFO [3def24f1] Running bundle exec rake assets:precompile as vtcontrol@ssh-vtcontrol.alwaysdata.net
DEBUG [3def24f1] Command: cd /home/www/app/releases/20200409174918 && ( export NODE_ENVIRONMENT="production" RAILS_ENV="production" RAILS_GROUPS="" ; bundle exec rake assets:precompile )
运行本地或服务器上的最后一个命令不会产生任何错误,只会产生警告:
# On production server:
$ cd /home/www/app/releases/20200409174918 && ( export NODE_ENVIRONMENT="production" RAILS_ENV="production" RAILS_GROUPS="" ; bundle exec rake assets:precompile )
yarn install v1.22.4
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@1.2.12: The platform "linux" is incompatible with this module.
info "fsevents@1.2.12" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
warning " > webpack-dev-server@3.10.3" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
warning "webpack-dev-server > webpack-dev-middleware@3.7.2" has unmet peer dependency "webpack@^4.0.0".
success Already up-to-date.
Done in 0.62s.
我想到的假设:
- 运行 内存不足。主要发生在 Digital Ocean 上,提供者排除了这种可能性,无论如何它在 sshing 到服务器时不会编译。
node
与 nodejs
的问题。这曾经困扰我,但现在不再发生了,起初是因为我只使用链轮并添加了 mini_racer
gem,它为 ExecJS 打包了节点,然后因为我使用 webpacker 包含了 Bootstrap链轮,从而消除了对 autoprefixer-rails
和 errors out when an old version of nodejs is present alongside node 的依赖。
- Capistrano 错误地解释了 yarn/webpacker 失败警告。我把Bootstrap提取到它自己的app/javascripts/bootstrap.js中,因为webpacker抱怨生成的JS太大,所以这个可以排除。 Yarn 抱怨未满足的对等依赖性,但这些是开发依赖性,我认为这无关紧要。 这可能是问题所在,但我该如何测试呢?
- 还有什么我应该尝试的吗?例如,使用 webpack 和 sprockets 会导致生产冲突吗?它在开发中运行良好,生成的资产不应相互覆盖。
以下是我的 Gemfile 的相关部分:
# Gemfile
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 4.0'
group :production do
# Used to load env vars from an .env file during deploy
gem 'dotenv-rails'
end
group :development do
gem 'capistrano', '~> 3.13.0', require: false
gem 'capistrano-rails', '~> 1.4', require: false
gem 'capistrano-bundler', '~> 1.6', require: false
gem 'capistrano-rails-console', require: false
end
最后是我的 Capfile
和 deploy.rb
的相关部分:
# Capfile
require 'capistrano/bundler'
require 'capistrano/rails'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano/rails/console'
require 'dotenv'
Dotenv.load
# config/deploy.rb
# Setup bundler
# Unset capistrano/bundler default flags because Bundler has deprecated them
set :bundle_flags, '--quiet'
set :bundle_path, nil
set :bundle_without, nil
before 'bundler:install', 'deploy:config:bundler'
# Remove gems no longer used to reduce disk space used
# This command requires loading capistrano/bundler in Capfile
after 'deploy:published', 'bundler:clean'
# Skip migration if files in db/migrate were not modified
# This command requires loading capistrano/rails in Capfile
set :conditionally_migrate, true
# Rails app server manages the database
set :migration_role, :app
# Defaults to nil (no asset cleanup is performed)
# If you use Rails 4+ and you'd like to clean up old assets after each deploy,
# set this to the number of versions to keep
set :keep_assets, 2
感谢您的帮助!
好吧,在尝试了几天我能想到的一切之后,我尝试了一些我已经测试过的东西,但我想这次使用了正确的语法,因为它现在可以工作了。
这是我需要添加到 Capistrano 的配置文件以确保部署时 Yarn 可用的内容:
# In deploy.rb
# Add or adjust default_env to append .npm-packages to $PATH:
set :default_env, {
PATH: '$HOME/.npm-packages/bin/:$PATH',
NODE_ENVIRONMENT: 'production'
}
说明:VPS 用户可以安装像 Yarn "globally" 这样的二进制文件(使用 npm install --global yarn
)。在后台,二进制文件安装在 $HOME/.npm-packages/bin
中,并且此文件夹被添加到 $PATH
以用于 interactive/login shell 会话。由于 Capistrano 尽最大努力不接受这个,我们必须在 deploy.rb
.
中强制提供更新的 $PATH
感谢您为我指明了正确的方向。我有同样的错误,结果证明是内存问题。对于有相同问题的任何人,请在编译期间检查 运行 是否内存不足 free -m
。如果你 运行 出来你会看到类似 -bash: fork: Cannot allocate memory
.
的东西
我正在使用 Digitalocean,我的解决方案是添加交换 space:https://www.digitalocean.com/community/tutorials/how-to-add-swap-space-on-ubuntu-18-04
我已经尝试了所有我能想到的方法,但我无法让部署工作。
该应用程序需要部署到由 Alwaysdata 和 运行 ruby 2.6.2 托管的 VPS,使用 Capistrano 进行部署。 这是一个 Rails 6.0.2.2 应用程序,对 JS 使用 webpack,对遗留脚本、所有图像和 CSS 使用 sprockets。
# On local machine (MacOS)
$ bundle exec cap production deploy
00:00 git:wrapper
00:01 git:check
00:03 deploy:check:directories
00:03 deploy:check:linked_dirs
00:03 deploy:check:make_linked_dirs
00:05 git:clone
00:06 git:update
00:08 git:create_release
00:10 deploy:set_current_revision
00:10 deploy:symlink:linked_files
00:12 deploy:symlink:linked_dirs
00:18 deploy:config:bundler
00:20 bundler:install
00:20 deploy:assets:precompile
#<Thread:0x00007fb35ba959f0@/Users/Goulven/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/sshkit-1.21.0/lib/sshkit/runners/parallel.rb:10 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
/Users/Goulven/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/sshkit-1.21.0/lib/sshkit/command.rb:97:in `exit_status=': rake exit status: 1 (SSHKit::Command::Failed)
rake stdout: Nothing written
rake stderr: Nothing written
INFO [3def24f1] Running bundle exec rake assets:precompile as vtcontrol@ssh-vtcontrol.alwaysdata.net
DEBUG [3def24f1] Command: cd /home/www/app/releases/20200409174918 && ( export NODE_ENVIRONMENT="production" RAILS_ENV="production" RAILS_GROUPS="" ; bundle exec rake assets:precompile )
运行本地或服务器上的最后一个命令不会产生任何错误,只会产生警告:
# On production server:
$ cd /home/www/app/releases/20200409174918 && ( export NODE_ENVIRONMENT="production" RAILS_ENV="production" RAILS_GROUPS="" ; bundle exec rake assets:precompile )
yarn install v1.22.4
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@1.2.12: The platform "linux" is incompatible with this module.
info "fsevents@1.2.12" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
warning " > webpack-dev-server@3.10.3" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
warning "webpack-dev-server > webpack-dev-middleware@3.7.2" has unmet peer dependency "webpack@^4.0.0".
success Already up-to-date.
Done in 0.62s.
我想到的假设:
- 运行 内存不足。主要发生在 Digital Ocean 上,提供者排除了这种可能性,无论如何它在 sshing 到服务器时不会编译。
node
与nodejs
的问题。这曾经困扰我,但现在不再发生了,起初是因为我只使用链轮并添加了mini_racer
gem,它为 ExecJS 打包了节点,然后因为我使用 webpacker 包含了 Bootstrap链轮,从而消除了对autoprefixer-rails
和 errors out when an old version of nodejs is present alongside node 的依赖。- Capistrano 错误地解释了 yarn/webpacker 失败警告。我把Bootstrap提取到它自己的app/javascripts/bootstrap.js中,因为webpacker抱怨生成的JS太大,所以这个可以排除。 Yarn 抱怨未满足的对等依赖性,但这些是开发依赖性,我认为这无关紧要。 这可能是问题所在,但我该如何测试呢?
- 还有什么我应该尝试的吗?例如,使用 webpack 和 sprockets 会导致生产冲突吗?它在开发中运行良好,生成的资产不应相互覆盖。
以下是我的 Gemfile 的相关部分:
# Gemfile
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 4.0'
group :production do
# Used to load env vars from an .env file during deploy
gem 'dotenv-rails'
end
group :development do
gem 'capistrano', '~> 3.13.0', require: false
gem 'capistrano-rails', '~> 1.4', require: false
gem 'capistrano-bundler', '~> 1.6', require: false
gem 'capistrano-rails-console', require: false
end
最后是我的 Capfile
和 deploy.rb
的相关部分:
# Capfile
require 'capistrano/bundler'
require 'capistrano/rails'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano/rails/console'
require 'dotenv'
Dotenv.load
# config/deploy.rb
# Setup bundler
# Unset capistrano/bundler default flags because Bundler has deprecated them
set :bundle_flags, '--quiet'
set :bundle_path, nil
set :bundle_without, nil
before 'bundler:install', 'deploy:config:bundler'
# Remove gems no longer used to reduce disk space used
# This command requires loading capistrano/bundler in Capfile
after 'deploy:published', 'bundler:clean'
# Skip migration if files in db/migrate were not modified
# This command requires loading capistrano/rails in Capfile
set :conditionally_migrate, true
# Rails app server manages the database
set :migration_role, :app
# Defaults to nil (no asset cleanup is performed)
# If you use Rails 4+ and you'd like to clean up old assets after each deploy,
# set this to the number of versions to keep
set :keep_assets, 2
感谢您的帮助!
好吧,在尝试了几天我能想到的一切之后,我尝试了一些我已经测试过的东西,但我想这次使用了正确的语法,因为它现在可以工作了。
这是我需要添加到 Capistrano 的配置文件以确保部署时 Yarn 可用的内容:
# In deploy.rb
# Add or adjust default_env to append .npm-packages to $PATH:
set :default_env, {
PATH: '$HOME/.npm-packages/bin/:$PATH',
NODE_ENVIRONMENT: 'production'
}
说明:VPS 用户可以安装像 Yarn "globally" 这样的二进制文件(使用 npm install --global yarn
)。在后台,二进制文件安装在 $HOME/.npm-packages/bin
中,并且此文件夹被添加到 $PATH
以用于 interactive/login shell 会话。由于 Capistrano 尽最大努力不接受这个,我们必须在 deploy.rb
.
$PATH
感谢您为我指明了正确的方向。我有同样的错误,结果证明是内存问题。对于有相同问题的任何人,请在编译期间检查 运行 是否内存不足 free -m
。如果你 运行 出来你会看到类似 -bash: fork: Cannot allocate memory
.
我正在使用 Digitalocean,我的解决方案是添加交换 space:https://www.digitalocean.com/community/tutorials/how-to-add-swap-space-on-ubuntu-18-04