2013-06-11 17 views
13

OpsWorks non sta precompilando le risorse sulla distribuzione. Ho trovato questa ricetta nel this thread ma penso che non sia completa però, o manchi qualcosa perché ho un errore su release_path non trovato.Come precompilare le risorse con Chef?

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 

tronchi:

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

Tutte le idee? Non conosco lo Chef e sto cercando di capirlo al volo.

+0

Sembra che è necessario fornire il release_path, il percorso in cui l'applicazione Rails dovrebbe risiedere sull'host deisgnation. – cmur2

+0

Cambia ogni volta che si distribuisce l'app. È dinamico quindi non riesco a codificarlo. – manafire

risposta

10

Prima che OpsWorks supporti la pipeline di asset, è possibile farlo. Creare un file deploy/before_symlink.rb con il seguente contenuto nell'applicazione rotaie.

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

Se si distribuisce l'applicazione Rails in un altro ambiente, modificare RAILS_ENV.

Se si utilizza uno stack NGINX/Unicorn, è necessario modificare la risorsa /assets. Basta copiare il seguente contenuto in un file chiamato unicorn/templates/default/nginx_unicorn_web_app.erb nei tuoi ricettari.

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 %> 

Se si utilizza uno stack Apache2/passeggero, è necessario modificare la risorsa /assets. Basta copiare il seguente contenuto in un file chiamato passenger_apache2/templates/default/web_app.conf.erb nei tuoi libri di cucina.

<VirtualHost *:80> 
    ServerName <%= @params[:server_name] %> 
    <% if @params[:server_aliases] && [email protected][: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] && [email protected][: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 -%> 

Se avete domande non esitate a chiedere.

Miglior Daniel

EDIT:

O semplicemente copiare questo libri di cucina https://github.com/neonlex/massive-octo-computing-machine ho sviluppato rapidamente. Ma OpsWorks dovrebbe supportarlo per impostazione predefinita in futuro.

+0

Grazie gentilmente, Daniel. Sono riuscito a capire qualcosa che alla fine ha funzionato per me (risposta postata qui sotto) e ora che funziona ha paura mortale di provare il tuo libro di cucina per paura di romperlo. Sono curioso di sapere qual è il passo dell'unicorno nella tua risposta e ogni pensiero che hai su ciò che ho inventato. Grazie! – manafire

+0

@neonlex Ho usato il repository aggiornato con il quale funziona bene. Ho provato a sostituire il comando ruby ​​shell con execute recipe dsl in https://github.com/neonlex/massive-octo-computing-machine/blob/master/rails/libraries/rails_configuration.rb, dà errore undefined metodo 'execute'. qualsiasi idea perché non ha funzionato! – goutham

+0

Non ho bisogno di modificare/beni o libri di cucina. Avere semplicemente before_symlink.rb ha funzionato per me. Sono su nginx e unicorno, usando le ricette Opsworks predefinite. – Kirk

5

So molto poco di OpsWorks e Chef, ma ecco cosa ho fatto per farlo funzionare.

In primo luogo, ho dovuto creare una ricetta di binari che viene eseguita durante l'evento setup per creare la directory di collegamento simbolico per le risorse. Questo si trova in un repository pubblico a cui OpsWorks può accedere.

libri di cucina/rails/Ricette/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 

Poi, nella mia app, ho dovuto creare 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 

Questa ottenere chiamato durante il processo di distribuzione e compila le risorse.

+0

Per qualche motivo questo continua a ricostruire alcuni dei miei script, anche se ho per la directory delle risorse condivise. –

3

In AWS Opsworks Io uso la seguente ricetta:

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 

ho eseguito questo comando come root perché l'istanza ha bisogno del permesso di diritto di scrivere al percorso release. Eseguendo il comando mentre l'utente deploy esegue il rendering di un errore di autorizzazione negato.

+0

Sono stato confuso dall'errore di autorizzazione negato, dal momento che OpsWorks sembra impostare l'utente di distribuzione come proprietario di tutto in/shared. Si scopre che questo utente crea ancora i suoi file con il proprietario root (tramite la sua impostazione maschera file), quindi crea un file di registro e quindi non può modificarlo. – zrisher

5

Si noti che se si passano variabili di ambiente all'app Rails utilizzando new OpsWorks feature, è necessario includere queste variabili nell'invocazione rake (poiché non vengono acquisite in modo permanente nell'ambiente dell'utente di distribuzione).

faccio la seguente (in base a this article e 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 
Problemi correlati