web-dev-qa-db-ja.com

capistranoを使用してAmazon EC2の本番環境にデプロイすると、アセットがプリコンパイルされません

Capistranoを使用して本番環境にデプロイできるように取り組みました。私はいくつかの問題に直面し、それらのほとんどを修正している間に、私たちはまだ最後の問題を抱えています。

アセットのプリコンパイルオプションは、本番環境で適切にコンパイルされません。そのため、JSに大きく依存しているため、最後に開発された機能を使用できません。

誰もがこの問題を分析する方法に影響を与えようとすることなく、これは私がそれを機能させるために私がやったことの一部です:

  1. ローカルでプリコンパイルされたアセット、githubリポジトリにプッシュ、ローカルマシンからec2にデプロイされたキャップ。 capデプロイはローカルで、ec2にプッシュされるコードはgithubにあるコードです。
  2. 提案されているようにカピストラーノタスクを使用してみました。 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. 最後に、本番環境でpublic/assetsを削除し、Rails_ENV = production bundle exec rake assets:precompileを使用してそこでプリコンパイルしてみました

アプリは新しいJSファイルを使用していません。リポジトリまたはサーバー自体のいずれかでコードを確認する場合、name.js.coffeeに簡単なコメントを導入しました( "#は、DBのデータに応じてメニューを表示および非表示にする" xxx行にあります)。本番環境でコンパイルされたassets.jsこれは、最近のアセットが使用されていることを確認する簡単なテストです。

ここでの問題全体は、jsファイルとcssファイルであり、Railsではありません。これが、テストや検索が非常に難しい理由です。このように、最近のjsフレームワークの人気の理由の1つです。問題が発生した場合、問題が発生している場所を探すために自分を殺す必要はありません。確率がRubyまたはRailsにある場合、通常、見つけるのにそれほど時間はかかりません。 js、css、およびブラウザー間の互換性に到達したら、これが問題ですIS。

これが私のdeploy.rbファイルです。 Rails 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,  "[email protected]: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,  "[email protected]: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

助けてくれてありがとう!さらに情報が必要な場合はお知らせください。

12
TKVR

解決策:これが動作するデプロイファイルです。

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,  "[email protected]: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"
1
TKVR

独自の:precompile_assetsタスクは必要ありません。 Capfileにload 'deploy/assets'を含めることにより、Capistranoを使用しています。

:precompile_assetsタスクをdeploy.rbから削除すると、問題が解決する場合があります。 Capistranoのソースコードを見ると、:precompile_assetsの実装がまったく異なることがわかります。 https://github.com/capistrano/capistrano/blob/legacy-v2/lib/capistrano/recipes/deploy /assets.rb

13
Chris Aitchison

このコードを試すことができます

# 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,  "[email protected]: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"
1
Hendra Gunawan

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

1
mcr

アセットのコンパイル中に実行されるuglifierがGemfileにある場合、変更されたJavascriptアセットがデプロイされているかどうかのテストとして使用している種類のコメントのみを削除するように構成されている可能性があります。

UglifierのReadme says これは可能であり、いくつかの種類のコメントを区別します。そのため、アセットのコンパイル後にまだ別のコメントが残っているのを見て、誤解された可能性があります。

この可能性を判断する別の手がかりは、(あなたが言うように)この問題が他の問題を修正する長い(疲れる)プロセスの後に生じたということです。多くの場合、これはこのような認識から人々をブロックする可能性があります。長い努力は仮定に「それらを固定する」ことができます。

したがって、JavaScriptでコメントの代わりに変数宣言を追加してみてください。

0
MarkDBlackwell

これと同様の問題がありましたが、解決策はGemfileのアセットグループを削除することでした。プリコンパイルに使用されるデフォルトのタスクキャップは、アセットが別のグループに含まれていないように見えるためです。

0
KevEllis