13

我致力于能够使用 capistrano 部署到生产环境。我面临几个问题,在解决其中大部分问题的同时,我们还有最后一个问题。

我们的预编译资产选项没有在生产环境中正确编译它们,因此,我们无法使用最后开发的功能,因为它们严重依赖 JS。

在不试图影响任何人如何分析这个问题的情况下,这是我试图让它发挥作用的一些方法:

  1. 本地预编译资产,推送到 github repo,从本地机器部署到 ec2。cap deploy 是本地的,推送到 ec2 的代码是 github 上的。
  2. 按照建议尝试使用 capistrano 任务。在 Capfile 中使用 load 'deploy'assets' 并让 cap deploy:setup 任务完成它的工作。
  3. 使用选项 cap deploy:assets:clean 然后 cap deploy:assets:precompile
  4. 尝试从公共中删除资产,然后在 deploy.rb 中使用 pipeline_precompile 任务
  5. 过期的资产,迫使 Rails 预编译所有改变 application.rb 中 assets.versions 的东西
  6. 在 environment/production.rb 中的 config.assets 上尝试了不同的组合
  7. 最后,尝试删除生产中的公共/资产并使用 RAILS_ENV=production bundle exec rake assets:precompile 进行预编译

该应用程序只是没有使用新的 JS 文件。如果您在 repo 或服务器本身中检查代码,我在 name.js.coffee 中引入了一个简单的注释(第 xxx 行的“# Shows and hides menus based on the data on DB”),这不在在生产中编译的 assets.js。这是一个快速测试,以确保正在使用最近的资产。

这里的整个问题是js和css文件,而不是rails。这就是为什么它如此难以测试或找到的原因。这也是最近 js 框架流行的原因之一。万一出现问题,您不必为了寻找问题所在而自杀。如果问题出现在 ruby​​ 或 rails 中,通常不会花费那么长时间来找出问题所在。一旦你获得了 js、css 和跨浏览器的兼容性,这就是手头的问题。

这是我的 deploy.rb 文件。运行轨道 3.2.12 ruby​​-1.9.3-p327:

# $:.unshift(File.expand_path('./lib', ENV['rvm_path']))

# Load rvm's capistrono plugins
require 'rvm/capistrano'

require 'bundler/capistrano'

set :rvm_type, :user

set :user, 'username'
set :domain, 'ip_address'
set :application, "app_pro"
set :keep_releases, 2 # It keeps on two old releases.

# git repo details
set :scm, :git # You can set :scm explicitly or Capistrano will make an intelligent guess based on known version control directory names
set :repository,  "git@github.com:user/app.git"
set :scm_username, 'user'
set :git_enable_submodules, 1
set :git_shallow_clone, 1
set :branch, 'master'

# Or: `accurev`, `bzr`, `cvs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none`


role :web, domain                          # Your HTTP server, Apache/etc
role :app, domain                          # This may be the same as your `Web` server
role :db,  domain, :primary => true# 'ec2-23-23-156-118.compute-1.amazonaws.com' This is where Rails migrations will run
# role :db,  "your slave db-server here"

# deply options
default_run_options[:pty] = true
set :ssh_options, {:forward_agent => true}
set :ssh_options, {:auth_methods => "publickey"}
set :ssh_options, {:keys => ["~/Downloads/key.pem"]}
set :deploy_to, "/home/user/appdir"
set :deploy_via, :remote_cache
set :use_sudo, false

# if you want to clean up old releases on each deploy uncomment this:
after "deploy:restart", "deploy:cleanup"

# if you're still using the script/reaper helper you will need
# these http://github.com/rails/irs_process_scripts

# If you are using Passenger mod_rails uncomment this:
namespace :deploy do
  task :start do
    # run COMMAND="/etc/init.d/nginx restart" invoke SUDO=1
    run "sudo /etc/init.d/nginx restart"
    # exit
  end
  after "deploy:start", "deploy:cleanup"

  task :stop do ; end
  task :restart, :roles => :app, :except => { :no_release => true } do
    run "touch #{File.join(current_path,'tmp','restart.txt')}"
  end

  task :setup_config, roles: :app do
    run "mkdir -p #{shared_path}/config"
    put File.read("config/database.example.yml"), "#{shared_path}/config/database.yml"
    puts 'now edit the config file database in #{shared_path}'
  end
  after 'deploy:setup', 'deploy:setup_config'

  desc "Symlink shared resources on each release - not used"
  task :symlink_config, :roles => :app do
    run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
  end

  after 'deploy:finalize_update', 'deploy:symlink_config'

  desc "It helps to seed database with values"
  task :seed do
    run "cd #{current_path}; bundle exec rake db:seed RAILS_ENV=#{rails_env}"
  end
  task :create_schema do
    run "cd #{current_path}; bundle exec rake db:create RAILS_ENV=#{rails_env} --trace"
  end
end

正在运行的新/替代 (deploy_new2.rb) 文件:

# On-working new/alternative deploy.rb file:

require 'rvm/capistrano'
require 'bundler/capistrano'

set :rvm_type, :user

set :application, "ip_address"
set :domain, 'ip_address'

# Roles
role :web, domain
role :app, domain
role :db,  domain, :primary => true

#deployment details
set :deploy_via, :remote_cache
set :user, "username"
set :copy_compression, :bz2
set :git_shallow_clone, 1
set :scm_verbose, true
set :use_sudo, false
set :deploy_to, "/home/user/dir"

default_run_options[:pty] = true
set :ssh_options, {:forward_agent => true}
set :ssh_options, {:auth_methods => "publickey"}
set :ssh_options, {:keys => ["~/Downloads/key.pem"]}

#repo details
set :scm, :git
set :repository,  "git@github.com:user/app.git"
set :scm_username, 'user'
set :keep_releases, 2
set :branch, "master"


namespace :deploy do
  # task :start, :roles => :app, :except => { :no_release => true } do
  #   # not need to restart nginx every time
  #   # run "service nginx start"
  #   run "cd #{release_path} && touch tmp/restart.txt"
  # end

  # after "deploy:start", "deploy:cleanup"
  # after 'deploy:cleanup', 'deploy:symlink_config'

  # You do not need reload nginx every time, eventhought if you use passenger or unicorn
  # task :stop, :roles => :app, :except => { :no_release => true } do
  #   run "service nginx stop"
  # end

  # task :graceful_stop, :roles => :app, :except => { :no_release => true } do
  #   run "service nginx stop"
  # end

  # task :reload, :roles => :app, :except => { :no_release => true } do
  #   run "cd #{release_path} && touch tmp/restart.txt"
  #   run "service nginx restart"
  # end

  task :restart, :roles => :app, :except => { :no_release => true } do
    run "cd #{release_path} && touch tmp/restart.txt"
  end

  # If you enable assets/deploy in Capfile, you do not need this
  # task :pipeline_precompile do
  #   # run "cd #{release_path}; RAILS_ENV=#{rails_env} bundle exec rake assets:precompile"
  #   # precompile assets before deploy and upload them to server 
  #   # run_locally("RAILS_ENV=#{rails_env} rake assets:clean && RAILS_ENV=#{rails_env} rake assets:precompile")
  #   # top.upload "public/assets", "#{release_path}/public/assets", :via =>:scp, :recursive => true
  # end
end

# you do not need to this, because you already add require 'bundler/capistrano'
# before "deploy:assets:precompile", "bundle:install"

和./Capfile:

load 'deploy'
# Uncomment if you are using Rails' asset pipeline
load 'deploy/assets'
load 'config/deploy' # remove this line to skip loading any of the default tasks

预先感谢您的任何帮助!如果您需要更多信息,请告诉我。

4

8 回答 8

15

您不需要自己的 :precompile_assets 任务。您通过在 Capfile 中包含加载“部署/资产”来使用 Capistrano。

从 deploy.rb 中删除 :precompile_assets 任务可能会解决问题。如果您查看 Capistrano 的源代码,您会发现它实现 :precompile_assets 的方式完全不同:https ://github.com/capistrano/capistrano/blob/legacy-v2/lib/capistrano/recipes/deploy/assets.rb

于 2013-03-23T01:22:15.653 回答
1

你可以试试这段代码

# On-working new/alternative deploy.rb file:

require 'rvm/capistrano'
require 'bundler/capistrano'

set :rvm_type, :user

set :application, "ip_address"
set :domain, 'ip_address'

# Roles
role :web, domain
role :app, domain
role :db,  domain, :primary => true

#deployment details
set :deploy_via, :remote_cache
set :user, "username"
set :copy_compression, :bz2
set :git_shallow_clone, 1
set :scm_verbose, true
set :use_sudo, false
set :deploy_to, "/home/user/dir"

default_run_options[:pty] = true
set :ssh_options, {:forward_agent => true}
set :ssh_options, {:auth_methods => "publickey"}
set :ssh_options, {:keys => ["~/Downloads/key.pem"]}

#repo details
set :scm, :git
set :repository,  "git@github.com:user/app.git"
set :scm_username, 'user'
set :keep_releases, 2
set :branch, "master"


namespace :deploy do
  # task :start, :roles => :app, :except => { :no_release => true } do
  #   # not need to restart nginx every time
  #   # run "service nginx start"
  #   run "cd #{release_path} && touch tmp/restart.txt"
  # end

  # after "deploy:start", "deploy:cleanup"
  # after 'deploy:cleanup', 'deploy:symlink_config'

  # You do not need reload nginx every time, eventhought if you use passenger or unicorn
  # task :stop, :roles => :app, :except => { :no_release => true } do
  #   run "service nginx stop"
  # end

  # task :graceful_stop, :roles => :app, :except => { :no_release => true } do
  #   run "service nginx stop"
  # end

  # task :reload, :roles => :app, :except => { :no_release => true } do
  #   run "cd #{release_path} && touch tmp/restart.txt"
  #   run "service nginx restart"
  # end

  task :restart, :roles => :app, :except => { :no_release => true } do
    run "cd #{release_path} && touch tmp/restart.txt"
  end

  # If you enable assets/deploy in Capfile, you do not need this
  # task :pipeline_precompile do
  #   # run "cd #{release_path}; RAILS_ENV=#{rails_env} bundle exec rake assets:precompile"
  #   # precompile assets before deploy and upload them to server 
  #   # run_locally("RAILS_ENV=#{rails_env} rake assets:clean && RAILS_ENV=#{rails_env} rake assets:precompile")
  #   # top.upload "public/assets", "#{release_path}/public/assets", :via =>:scp, :recursive => true
  # end
end

# you do not need to this, because you already add require 'bundler/capistrano'
# before "deploy:assets:precompile", "bundle:install"
于 2013-03-23T03:25:49.300 回答
1

解决方案:这是工作部署文件-

require 'rvm/capistrano'
require 'bundler/capistrano'

set :rvm_type, :user

set :application, "ip_address"
set :domain, 'ip_address'

# Roles
role :web, domain
role :app, domain
role :db,  domain, :primary => true

#deployment details
set :deploy_via, :remote_cache
set :user, "user"
set :copy_compression, :bz2
set :git_shallow_clone, 1
set :scm_verbose, true
set :use_sudo, false
set :deploy_to, "/home/user/app_dir"

default_run_options[:pty] = true
set :ssh_options, {:forward_agent => true}
set :ssh_options, {:auth_methods => "publickey"}
set :ssh_options, {:keys => ["~/sites/app/config/key.pem"]}

#repo details
set :scm, :git
set :repository,  "git@github.com:github_id/app.git"
set :scm_username, 'github_id'
set :keep_releases, 2
set :branch, "master"

after 'deploy:update_code', 'deploy:symlink_db'

namespace :deploy do
  # task :start, :roles => :app, :except => { :no_release => true } do
  #   # not need to restart nginx every time
  #   # run "service nginx start"
  #   run "cd #{release_path} && touch tmp/restart.txt"
  # end

  # after "deploy:start", "deploy:cleanup"
  # after 'deploy:cleanup', 'deploy:symlink_config'

  # You do not need reload nginx every time, eventhought if you use passenger or unicorn
  # task :stop, :roles => :app, :except => { :no_release => true } do
  #   run "service nginx stop"
  # end

  # task :graceful_stop, :roles => :app, :except => { :no_release => true } do
  #   run "service nginx stop"
  # end

  # task :reload, :roles => :app, :except => { :no_release => true } do
  #   run "cd #{release_path} && touch tmp/restart.txt"
  #   run "service nginx restart"
  # end

  task :restart, :roles => :app, :except => { :no_release => true } do
    run "cd #{release_path} && touch tmp/restart.txt"
  end

  desc "Symlinks the database.yml"
  task :symlink_db, :roles => :app do
    run "ln -nfs #{deploy_to}/shared/config/database.yml #{release_path}/config/database.yml"
  end

  # If you enable assets/deploy in Capfile, you do not need this
  # task :pipeline_precompile do
  #   # run "cd #{release_path}; RAILS_ENV=#{rails_env} bundle exec rake assets:precompile"
  #   # precompile assets before deploy and upload them to server 
  #   # run_locally("RAILS_ENV=#{rails_env} rake assets:clean && RAILS_ENV=#{rails_env} rake assets:precompile")
  #   # top.upload "public/assets", "#{release_path}/public/assets", :via =>:scp, :recursive => true
  # end
end

# you do not need to this, because you already add require 'bundler/capistrano'
# before "deploy:assets:precompile", "bundle:install"
于 2013-03-28T19:36:19.560 回答
1

我发现 capistrano 资产编译规则在捆绑器规则之前运行,所以没有任何效果,我编写了自己的:

  after "bundle:install" do
    run "cd #{release_path}; RAILS_ENV=production bundle exec rake assets:precompile"
  end

然后我发现我真的对在我的生产机器上安装 js 运行时不感兴趣。我回到只是将我的资产放入我的 git 树的部署分支中。我第一次这样做时,我忘了包含 manifest.yml 文件。

http://jimneath.org/2012/05/05/precompile-assets-using-a-git-hook.html

于 2013-06-21T19:53:21.393 回答
0

如果您在 Gemfile 中有 uglifier,它在资产编译期间运行,它可能已配置为仅删除您用来测试是否正在部署更改的 Javascript 资产的注释。

Uglifier 的自述文件这是可能的,并区分了几种评论。因此,您可能会被资产编译后仍然存在的另一条评论误导。

判断这种可能性的另一个线索是(正如你所说)这个问题是在解决其他问题的漫长(累人)过程之后出现的。通常,这会阻止人们产生这样的看法;长期的努力可以“锁定”他们的假设。

因此,请尝试在您的 Javascript 中添加变量声明而不是注释。

于 2013-03-24T19:51:46.903 回答
0

我遇到了与此类似的问题,但解决方案是删除 Gemfile 中的资产组,因为用于预编译的默认任务上限取决于资产似乎不在单独的组中。

于 2018-10-17T14:52:12.760 回答
0

我遇到了这个问题。原来我必须在我的服务器上安装 node 和 yarn 以获得 rake assets:precompile 才能工作

于 2020-10-28T11:44:32.670 回答
0

我最近也遇到了这个问题,使用 Capistrano 部署的资产预编译挂在 AWS 中。我通过在部署时临时从 t3.micro 实例切换到 t3.small 实例解决了这个问题。看起来微实例没有足够的资源用于预编译步骤。

于 2021-11-03T18:37:52.020 回答