OpsWorks isn't precompiling assets on deploy. I found this recipe in this thread but I think it's not complete though, or missing something because I get an error about release_path
not being found.
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
logs:
undefined local variable or method `release_path' for ....
Any ideas? I do not know Chef at all and am trying to figure this out on the fly.
To compile your assets locally, run the assets:precompile task locally on your app. Make sure to use the production environment so that the production version of your assets are generated. A public/assets directory will be created. Inside this directory you'll find a manifest.
rails assets:precompile is the task that does the compilation (concatenation, minification, and preprocessing). When the task is run, Rails first looks at the files in the config.assets.precompile array. By default, this array includes application.js and application.css .
Before OpsWorks supports the Asset Pipeline out of the box, you could do this.
Create a file deploy/before_symlink.rb
with the following content in your rails application.
run "cd #{release_path} && RAILS_ENV=production bundle exec rake assets:precompile"
If you deploy your Rails application to a different environment, change the RAILS_ENV.
If you use a NGINX/Unicorn stack, you have to modify the /assets
resource.
Just copy the following content in a file named unicorn/templates/default/nginx_unicorn_web_app.erb
in your cookbooks.
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 %>
If you use a Apache2/Passenger stack, you have to modify the /assets
resource.
Just copy the following content in a file named
passenger_apache2/templates/default/web_app.conf.erb
in your cookbooks.
<VirtualHost *:80>
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] %>
<Directory <%= @params[:docroot] %>>
Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
<Directory ~ "\.svn">
Order allow,deny
Deny from all
</Directory>
<Directory ~ "\.git">
Order allow,deny
Deny from all
</Directory>
<LocationMatch "^/assets/.*$">
Header unset ETag
FileETag None
# RFC says only cache for 1 year
ExpiresActive On
ExpiresDefault "access plus 1 year"
</LocationMatch>
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] %>*
</VirtualHost>
<% if node[:deploy][@application_name][:ssl_support] -%>
<VirtualHost *:443>
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] %>
<Directory <%= @params[:docroot] %>>
Options FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
</Directory>
<Directory ~ "\.svn">
Order allow,deny
Deny from all
</Directory>
<Directory ~ "\.git">
Order allow,deny
Deny from all
</Directory>
<LocationMatch "^/assets/.*$">
Header unset ETag
FileETag None
# RFC says only cache for 1 year
ExpiresActive On
ExpiresDefault "access plus 1 year"
</LocationMatch>
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*
</VirtualHost>
<% end -%>
If you have questions feel free to ask.
Best Daniel
EDIT:
Or you just copy over this cookbooks https://github.com/neonlex/massive-octo-computing-machine I developed quickly. But OpsWorks should support this by default in the future.
Note that if you're passing environment variables to your Rails app using the new OpsWorks feature, you'll need to include these variables in your rake
invocation (as they don't get permanently sourced into the deploy user's environment).
I do the following (based on this article and this recipe) in 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With