如何使用Chef预编译资产?

OpsWorks不会在部署时预编译资产。 我在这个post中找到了这个食谱,但我认为它不完整,或者遗漏了一些东西,因为我收到了关于找不到release_path的错误。

precompile.rb:

 Chef::Log.info("Running deploy/before_migrate.rb...") Chef::Log.info("Symlinking #{release_path}/public/assets to #{new_resource.deploy_to}/shared/assets") link "#{release_path}/public/assets" do to "#{new_resource.deploy_to}/shared/assets" end rails_env = new_resource.environment["RAILS_ENV"] Chef::Log.info("Precompiling assets for RAILS_ENV=#{rails_env}...") execute "rake assets:precompile" do cwd release_path command "bundle exec rake assets:precompile" environment "RAILS_ENV" => rails_env end 

日志

 undefined local variable or method `release_path' for .... 

有任何想法吗? 我根本不认识厨师,我想在飞行中弄清楚这一点。

在OpsWorks开箱即用支持Asset Pipeline之前,您可以这样做。 使用rails应用程序中的以下内容创建文件deploy/before_symlink.rb

 run "cd #{release_path} && RAILS_ENV=production bundle exec rake assets:precompile" 

如果将Rails应用程序部署到其他环境,请更改RAILS_ENV。

如果使用NGINX / Unicorn堆栈,则必须修改/assets资源。 只需将以下内容复制到cookbook中名为unicorn/templates/default/nginx_unicorn_web_app.erb中即可。

 upstream unicorn_<%= @application[:domains].first %> { server unix:<%= @application[:deploy_to]%>/shared/sockets/unicorn.sock fail_timeout=0; } server { listen 80; server_name <%= @application[:domains].join(" ") %> <%= node[:hostname] %>; access_log <%= node[:nginx][:log_dir] %>/<%= @application[:domains].first %>.access.log; keepalive_timeout 5; root <%= @application[:absolute_document_root] %>; <% if @application[:nginx] && @application[:nginx][:client_max_body_size] %> client_max_body_size <%= @application[:nginx][:client_max_body_size] %>; <% end %> location / { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; # If you don't find the filename in the static files # Then request it from the unicorn server if (!-f $request_filename) { proxy_pass http://unicorn_<%= @application[:domains].first %>; break; } } location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all; } location ~ ^/assets/ { expires 1y; add_header Cache-Control public; add_header ETag ""; break; } error_page 500 502 503 504 /500.html; location = /500.html { root <%= @application[:absolute_document_root] %>; } } <% if @application[:ssl_support] %> server { listen 443; server_name <%= @application[:domains].join(" ") %> <%= node[:hostname] %>; access_log <%= node[:nginx][:log_dir] %>/<%= @application[:domains].first %>-ssl.access.log; ssl on; ssl_certificate /etc/nginx/ssl/<%= @application[:domains].first %>.crt; ssl_certificate_key /etc/nginx/ssl/<%= @application[:domains].first %>.key; <% if @application[:ssl_certificate_ca] -%> ssl_client_certificate /etc/nginx/ssl/<%= @application[:domains].first %>.ca; <% end -%> keepalive_timeout 5; root <%= @application[:absolute_document_root] %>; <% if @application[:nginx] && @application[:nginx][:client_max_body_size] %> client_max_body_size <%= @application[:nginx][:client_max_body_size] %>; <% end %> location / { proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; # If you don't find the filename in the static files # Then request it from the unicorn server if (!-f $request_filename) { proxy_pass http://unicorn_<%= @application[:domains].first %>; break; } } location ~ ^/assets/ { expires 1y; add_header Cache-Control public; add_header ETag ""; break; } error_page 500 502 503 504 /500.html; location = /500.html { root <%= @application[:absolute_document_root] %>; } } <% end %> 

如果使用Apache2 / Passenger堆栈,则必须修改/assets资源。 只需将以下内容复制到cookbook中名为passenger_apache2/templates/default/web_app.conf.erb中即可。

  ServerName <%= @params[:server_name] %> <% if @params[:server_aliases] && !@params[:server_aliases].empty? -%> ServerAlias <% @params[:server_aliases].each do |a| %><%= "#{a}" %> <% end %> <% end -%> <% if @params[:mounted_at] -%> DocumentRoot /var/www <%= @params[:deploy][:passenger_handler] -%>BaseURI <%= @params[:mounted_at] %> <% else -%> DocumentRoot <%= @params[:docroot] %> <%= @params[:deploy][:passenger_handler] -%>BaseURI / <% end -%> <%= @params[:deploy][:passenger_handler] -%>Env <%= @params[:rails_env] %> > Options FollowSymLinks AllowOverride None Order allow,deny Allow from all   Order allow,deny Deny from all   Order allow,deny Deny from all   Header unset ETag FileETag None # RFC says only cache for 1 year ExpiresActive On ExpiresDefault "access plus 1 year"  LogLevel info ErrorLog <%= node[:apache][:log_dir] %>/<%= @params[:name] %>-error.log CustomLog <%= node[:apache][:log_dir] %>/<%= @params[:name] %>-access.log combined CustomLog <%= node[:apache][:log_dir] %>/<%= @params[:name] %>-ganglia.log ganglia FileETag none RewriteEngine On Include <%= @params[:rewrite_config] %>* RewriteLog <%= node[:apache][:log_dir] %>/<%= @application_name %>-rewrite.log RewriteLogLevel 0 # Canonical host #RewriteCond %{HTTP_HOST} !^<%= @params[:server_name] %> [NC] #RewriteCond %{HTTP_HOST} !^$ #RewriteRule ^/(.*)$ http://<%= @params[:server_name] %>/$1 [L,R=301] RewriteCond %{REQUEST_URI} !\.(css|gif|jpg|jpeg|png)$ RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f RewriteCond %{SCRIPT_FILENAME} !maintenance.html RewriteRule ^.*$ /system/maintenance.html [L] Include <%= @params[:local_config] %>*  <% if node[:deploy][@application_name][:ssl_support] -%>  ServerName <%= @params[:server_name] %> <% if @params[:server_aliases] && !@params[:server_aliases].empty? -%> ServerAlias <% @params[:server_aliases].each do |a| %><%= "#{a}" %> <% end %> <% end -%> SSLEngine on SSLProxyEngine on SSLCertificateFile <%= node[:apache][:dir] %>/ssl/<%= @params[:server_name] %>.crt SSLCertificateKeyFile <%= node[:apache][:dir] %>/ssl/<%= @params[:server_name] %>.key <% if @params[:ssl_certificate_ca] -%> SSLCACertificateFile <%= node[:apache][:dir] %>/ssl/<%= @params[:server_name] %>.ca <% end -%> SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0 <% if @params[:mounted_at] -%> DocumentRoot /var/www <%= @params[:deploy][:passenger_handler] -%>BaseURI <%= @params[:mounted_at] %> <% else -%> DocumentRoot <%= @params[:docroot] %> <%= @params[:deploy][:passenger_handler] -%>BaseURI / <% end -%> <%= @params[:deploy][:passenger_handler] -%>Env <%= @params[:rails_env] %> > Options FollowSymLinks AllowOverride All Order allow,deny Allow from all   Order allow,deny Deny from all   Order allow,deny Deny from all   Header unset ETag FileETag None # RFC says only cache for 1 year ExpiresActive On ExpiresDefault "access plus 1 year"  LogLevel info ErrorLog <%= node[:apache][:log_dir] %>/<%= @params[:name] %>-ssl-error.log CustomLog <%= node[:apache][:log_dir] %>/<%= @params[:name] %>-ssl-access.log combined CustomLog <%= node[:apache][:log_dir] %>/<%= @params[:name] %>-ssl-ganglia.log ganglia FileETag none RewriteEngine On Include <%= @params[:rewrite_config] %>-ssl* RewriteLog <%= node[:apache][:log_dir] %>/<%= @application_name %>-ssl-rewrite.log RewriteLogLevel 0 # Canonical host #RewriteCond %{HTTP_HOST} !^<%= @params[:server_name] %> [NC] #RewriteCond %{HTTP_HOST} !^$ #RewriteRule ^/(.*)$ http://<%= @params[:server_name] %>/$1 [L,R=301] RewriteCond %{REQUEST_URI} !\.(css|gif|jpg|jpeg|png)$ RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f RewriteCond %{SCRIPT_FILENAME} !maintenance.html RewriteRule ^.*$ /system/maintenance.html [L] Include <%= @params[:local_config] %>-ssl*  <% end -%> 

如果您有任何问题,请随时提出。

丹尼尔

编辑:

或者你只是复制这本食谱https://github.com/neonlex/massive-octo-computing-machine我很快就开发了。 但是OpsWorks将来应该默认支持这一点。

我对OpsWorks和Chef知之甚少,但这就是我做的工作。

首先,我必须创建一个在setup事件期间运行的rails配方,以创建资产的符号链接目录。 这是OpsWorks可以访问的公共仓库。

食谱/导轨/食谱/ symlink_assets.rb:

 node[:deploy].each do |application, deploy| Chef::Log.info("Ensuring shared/assets directory for #{application} app...") directory "#{deploy[:deploy_to]}/shared/assets" do group deploy[:group] owner deploy[:user] mode 0775 action :create recursive true end end 

然后,在我的应用程序中,我必须创建deploy / before_migrate.rb:

 Chef::Log.info("Running deploy/before_migrate.rb...") Chef::Log.info("Symlinking #{release_path}/public/assets to #{new_resource.deploy_to}/shared/assets") link "#{release_path}/public/assets" do to "#{new_resource.deploy_to}/shared/assets" end rails_env = new_resource.environment["RAILS_ENV"] Chef::Log.info("Precompiling assets for RAILS_ENV=#{rails_env}...") execute "rake assets:precompile" do cwd release_path command "bundle exec rake assets:precompile" environment "RAILS_ENV" => rails_env end 

这在部署过程中被调用并编译资产。

请注意,如果您使用新的OpsWorksfunction将环境变量传递到Rails应用程序,则需要在rake调用中包含这些变量(因为它们不会永久地源自部署用户的环境)。

我在deploy/before_migrate.rb执行以下操作(基于本文和此配方 ):

 Chef::Log.info("Precompiling assets for RAILS_ENV=" \ "#{new_resource.environment['RAILS_ENV']}...") execute 'rake assets:precompile' do cwd release_path command 'bundle exec rake assets:precompile' environment new_resource.environment end 

在AWS Opsworks中,我使用以下配方:

 execute 'rake assets:precompile' do cwd "#{node[:deploy_to]}/current" user 'root' command 'bundle exec rake assets:precompile' environment 'RAILS_ENV' => node[:environment_variables][:RAILS_ENV] end 

我以root身份运行此命令,因为实例需要正确的权限才能写入release路径。 以deploy用户身份运行该命令会呈现权限被拒绝错误。