I'm trying to put my app into production and image and css asset paths aren't working.
Here's what I'm currently doing:
Image assets live in /app/assets/images/image.jpg
Stylesheets live in /app/assets/stylesheets/style.css
In my layout, I reference the css file like this: <%= stylesheet_link_tag "styles", media: "all", "data-turbolinks-track" => true %>
Before restarting unicorn, I run RAILS_ENV=production bundle exec rake assets:precompile and it succeeds and I see the fingerprinted files in the public/assets directory.
When I browse to my site, I get a 404 not found error for mysite.com/stylesheets/styles.css.
What am I doing wrong?
Update:
In my layout, it looks like this:
<%= stylesheet_link_tag "bootstrap.min", media: "all", "data-turbolinks-track" => true %>
<%= stylesheet_link_tag "styles", media: "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
The generate source is this:
<link data-turbolinks-track="true" href="/stylesheets/bootstrap.min.css" media="all" rel="stylesheet" />
<link data-turbolinks-track="true" href="/stylesheets/styles.css" media="all" rel="stylesheet" />
<script data-turbolinks-track="true" src="/assets/application-0c647c942c6eff10ad92f1f2b0c64efe.js"></script>
Looks like Rails is not properly looking for the compiled css files. But it's very confusing why it's working correctly for javascripts (notice the /assets/****.js path).
In rails 4 you need to make the changes below:
config.assets.compile = true
config.assets.precompile = ['*.js', '*.css', '*.css.erb']
This works with me. use following command to pre-compile assets
RAILS_ENV=production bundle exec rake assets:precompile
Best of luck!
I just had the same problem and found this setting in config/environments/production.rb:
# Rails 4:
config.serve_static_assets = false
# Or for Rails 5:
config.public_file_server.enabled = false
Changing it to true got it working. It seems by default Rails expects you to have configured your front-end webserver to handle requests for files out of the public folder instead of proxying them to the Rails app. Perhaps you've done this for your javascript files but not your CSS stylesheets?
(See Rails 5 documentation). As noted in comments, with Rails 5 you may just set the RAILS_SERVE_STATIC_FILES environment variable, since the default setting is config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?.
In /config/environments/production.rb I had to add this:
Rails.application.config.assets.precompile += %w( *.js ^[^_]*.css *.css.erb )
The .js was getting precompiled already, but I added it anyway. The .css and .css.erb apparently don't happen automatically. The ^[^_] excludes partials from being compiled -- it's a regexp.
It's a little frustrating that the docs clearly state that asset pipeline IS enabled by default but doesn't clarify the fact that only applies to javascripts.
I was able to solve this problem by changing:
config.assets.compile = false to
config.assets.compile = true in /config/environments/production.rb
Update (June 24, 2018): This method creates a security vulnerability if the version of Sprockets you're using is less than 2.12.5, 3.7.2, or 4.0.0.beta8
For Rails 5, you should enable the follow config code:
config.public_file_server.enabled = true
By default, Rails 5 ships with this line of config:
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
Hence, you will need to set the environment variable RAILS_SERVE_STATIC_FILES to true.
There are 2 things you must accomplish to serve the assets in production:
Precompile the assets.
Serve the assets on the server to browser.
1) In order to precompile the assets, you have several choices.
You can run rake assets:precompile on your local machine, commit it to source code control (git), then run the deployment program, for example capistrano. This is not a good way to commit precompiled assets to SCM.
You can write a rake task that run RAILS_ENV=production rake assets:precompile on the target servers each time you deploy your Rails app to production, before you restart the server.
Code in a task for capistrano will look similar to this:
on roles(:app) do
if DEPLOY_ENV == 'production'
execute("cd #{DEPLOY_TO_DIR}/current && RAILS_ENV=production rvm #{ruby_string} do rake assets:precompile")
end
end
2) Now, you have the assets on production servers, you need to serve them to browser.
Again, you have several choices.
Turn on Rails static file serving in config/environments/production.rb
config.serve_static_assets = true # old
or
config.serve_static_files = true # new
Using Rails to serve static files will kill your Rails app performance.
Configure nginx (or Apache) to serve static files.
For example, my nginx that was configured to work with Puma looks like this:
location ~ ^/(assets|images|fonts)/(.*)$ {
alias /var/www/foster_care/current/public/$1/$2;
gzip on;
expires max;
add_header Cache-Control public;
}
Rails 4 no longer generates the non fingerprinted version of the asset: stylesheets/style.css will not be generated for you.
If you use stylesheet_link_tag then the correct link to your stylesheet will be generated
In addition styles.css should be in config.assets.precompile which is the list of things that are precompiled
change your Production.rb file line
config.assets.compile = false
into
config.assets.compile = true
and also add
config.assets.precompile = ['*.js', '*.css', '*.css.erb']
What you SHOULD NOT do:
Some of my colleagues above have recommended you to do this:
config.serve_static_assets = true ## DON”T DO THIS!!
config.public_file_server.enabled = true ## DON”T DO THIS!!
The rails asset pipeline says of the above approach:
This mode uses more memory, performs more poorly than the default and is not recommended. See here: (http://edgeguides.rubyonrails.org/asset_pipeline.html#live-compilation)
What you SHOULD do:
Precompile your assets.
RAILS_ENV=production rake assets:precompile
You can probably do that with a rake task.
I'm running Ubuntu Server 14.04, Ruby 2.2.1 and Rails 4.2.4 I have followed a deploy turorial from DigitalOcean and everything went well but when I go to the browser and enter the IP address of my VPS my app is loaded but without styles and javascript.
The app is running with Unicorn and Nginx. To fix this problem I entered my server using SSH with my user 'deployer' and go to my app path which is '/home/deployer/apps/blog' and run the following command:
RAILS_ENV=production bin/rake assets:precompile
Then I just restart the VPS and that's it!
It works for me!
Hope it could be useful for somebody else!
If precompile is set you DO NOT need
config.assets.compile = true
as this is to serve assets live.
Our problem was we only had development secret key base set in config/secrets.yml
development:
secret_key_base: '83d141eeb181032f4070ae7b1b27d9ff'
Need entry for production environment
The default matcher for compiling files includes application.js, application.css and all non-JS/CSS files (this will include all image assets automatically) from app/assets folders including your gems:
If you have other manifests or individual stylesheets and JavaScript files to include, you can add them to the precompile array in config/initializers/assets.rb:
Rails.application.config.assets.precompile += ['admin.js', 'admin.css', 'swfObject.js']
http://guides.rubyonrails.org/asset_pipeline.html#precompiling-assets
First of all check your assets, it might be possible there is some error in pre-compiling of assets.
To pre-compile assets in production ENV run this command:
RAILS_ENV=production rake assets:precompile
If it shows error, remove that first,
In case of "undefined variable" error, load that variable file before using it in another file.
example:
#import "variables";
#import "style";
in application.rb file set sequence of pre-compiliation of assets
example:
config.assets.precompile += [ 'application.js', 'admin.js', 'admin/events.js', 'admin/gallery.js', 'frontendgallery.js']
config.assets.precompile += [ 'application.css', 'admin.css','admin/events.css', 'admin/gallery.css', 'frontendgallery.css']
Found this:
The configuration option config.serve_static_assets has been renamed to config.serve_static_files to clarify its role.
in config/environments/production.rb:
# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present?
So set env RAILS_SERVE_STATIC_FILES or using Nginx to serving static files.
Add config.serve_static_assets = true will still work, but removed in future.
it is not recommended to let capistrano do assets precompile, because it may take ages and often time out. try to do local assets precompile.
1st, set in config/application.rb
config.assets.initialize_on_precompile = false
then do local
RAILS_ENV=production bin/rake assets:precompile
and add those public/assets to git.
and config/environments/development.rb, change your asset path to avoid using precompiled assets:
config.assets.prefix = '/dev-assets'
If you have db connection issue, means u have initializer that uses db. one way around it is to set a new environment by duplicate production.rb as maybe production2.rb, and in database.yml, add production2 environment with development db setting. then do
RAILS_ENV=production2 bin/rake assets:precompile
if you are still facing some issue with assets, for example ckeditor,
add the js file into config/initializers/assets.rb
Rails.application.config.assets.precompile += %w( ckeditor.js )
I may be wrong but those who recommend changing
config.assets.compile = true
The comment on this line reads: #Do not fallback to assets pipeline if a precompiled asset is missed.
This suggests that by setting this to true you are not fixing the problem but rather bypassing it and running the pipeline every time. This must surely kill your performance and defeat the purpose of the pipeline?
I had this same error and it was due to the application running in a sub folder that rails didn't know about.
So my css file where in home/subfolder/app/public/.... but rails was looking in home/app/public/...
try either moving your app out of the subfolder or telling rails that it is in a subfolder.
location ~ ^/assets/ {
expires 1y;
add_header Cache-Control public;
add_header ETag "";
}
This fixed the problem for me in production. Put it into the nginx config.
Even we faced the same problem where RAILS_ENV=production bundle exec rake assets:precompile succeeded but things did not work as expected.
We found that unicorn was the main culprit here.
Same as your case, even we used to restart unicorn after compiling the assets. It was noticed that when unicorn is restarted, only its worker processes are restarted and not the master process.
This is the main reason the correct assets are not served.
Later, after compiling assets, we stopped and started unicorn so that the unicorn master process is also restarted and the correct assets were getting served.
Stopping and starting unicorn brings around 10 secs on downtime when compared to restarting the unicorn. This is the workaround that can be used where as long term solution is move to puma from unicorn.
Related
I have a project that works in the local development environment but breaks when it is uploaded to Heroku. When visiting my project on Heroku, I notice that I get 404 responses from the server saying that it could not find my css and js files. I have done some searching and found out that Heroku is not precompiling my assets. The project will work fine until Heroku puts my project to sleep. Upon waking the project in Heroku, the css and js are broken.
The project is using Rails 4.2.4, I have made sure to to include config.serve_static_assets = true in my config/application.rb and gem 'rails_12factor', group: :production in my Gemfile.
The css and js only breaks when Heroku puts the project to sleep due to inactivity. Does anyone know how to have Heroku automatically precompile assets when it is awaken from sleep?
I had similar issues before, my best bet was to precompile in local and then push to heroku. Configure your production.rb as follows:
config.serve_static_files = false
config.assets.compile = false
then in your console precompile as follows:
rake assets:precompile RAILS_ENV=production
This will precompile everything in public/assets commit your changes and push to heroku.
Also reset your assets cache for avoid any inconsistence:
rake assets:precompile RAILS_ENV=production
The above will force all your public/assets directory to rebuild when you run precompile command.
If your issue is with assets recompilation my answer should solve it, if you still have issues then you are doing something wrong or the issue does not have anything to do with assets precompilation.
We set the configuration values of above to false because now you are sending the precompiled files to the repo, so we do not serve static files nor fallback assets pipeline if something is missing, we are going everything in local.
Gemfile
gem 'rails_12factor', group: :production
application.rb
By default Rails 4 will not serve your assets. To enable this functionality you need to go into config/application.rb and add this line:
config.serve_static_assets = true
production.rb
config.serve_static_files = true
config.assets.compile = true
Command Line
bundle install
bundle exec rake assets:precompile RAILS_ENV=production
Make sure the images are in the /public folder.
Reference here
In production the generated html for the image_tag helper returns a 404 error.
Asset pipeline is enabled
In the haml file
=image_tag "how_it_works_1.jpg"
how_it_works_1.jpg file is located at app/assets/images/how_it_works_1.jpg
When I deploy in production with mina I can find this asset under current/public/assets/how_it_works_1-5e40b2326fc14e879ae476a3fd6aef97.jpg
however the generated html doesn't point to this asset but to /images/how_it_works_1.jpg which returns a 404
<img src="/images/how_it_works_1.jpg"/>
it's working under the development env
<img src="/assets/how_it_works_1.jpg"/>
edit:
I am using apache2.4 together with passenger
here is an extract of my production.rb:
config.serve_static_assets = false
config.assets.js_compressor = :uglifier
config.assets.css_compressor = :sass
config.assets.compile = true
config.assets.paths << Rails.root.join('app', 'assets', 'fonts')
config.assets.digest = true
config.assets.version = '1.0'
You have to run this first. I've had this issue myself before.
rake assets:precompile RAILS_ENV=production
and then reload the server.
It seems like your assets are precompiling successfully. However, Rails defaults to refusing to serve static assets in production. This Rails guide has a bit more information. (Ctrl-F for config.serve_static_assets)
To answer your question, you will need to configure your web server (is it Apache, nginx, or something else?) to serve the static assets from your deploy's public/assets/ directory.
If you edit your question to include your web server, I can give you a link to more specific instructions. Cheers!
It seems like config.assets.digest is not true in config/environments/production.rb (by default it should be true).
I am deploying a RoR 3.2 app to a shared server.
When I run rake assets:precompile RAILS_ENV=production I can see at ~/public_html/my_app/assets/ that all my images are precompiled.
But when I go to mywebsite.com ActionView throws an error. The production log gives me:
ActionView::Template::Error (200/adrap21.png isn't precompiled).
Funny thing is that at ~/public_html/my_app/assets/200 I can see a precompiled image: adrap21-a5f042dd2b89a3d87eba25969495d678.png
I have run several times one of the following:
1) rake assets:precompile RAILS_ENV=production
2) RAILS_ENV=production rake assets:precompile
at my_app/config/environments/production.rb I have the following:
# Disable Rails's static asset server (Apache or nginx will already do this)
config.serve_static_assets = false
# Compress JavaScripts and CSS
config.assets.compress = true
# Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = true
I have changed config.assets.compile from false to true and does not help.
I have read related answers but other people solutions are not working for me.
This one was suposed to be foolproof. Another one, more specific about not compiling images, this other prevents using config.assets.compile = true.
I have even tried the advice of using config.assets.precompile += %w[*.png *.jpg *.jpeg *.gif] , but it is not yet working. Might there be something wrong with images call? Is it a RoR 3.2 bug?
FOUND WHAT THE PROBLEM WAS.
Phusion Passenger needs to be restarted for the compiled assets to work. That is why, using Capistrano, you need to restart the server for all the compiled to work together.
Thanks again, Paritosh. I know too how slow is learning curve at beginning when you learn to program by yourself.
It very clearly says in its documentation that it would do this if I don't precompile them locally.
And truthfully, I have no interest in precompiling these locally.
What I've had in production.rb, I've duplicated in application.rb
In my production.rb :
config.serve_static_assets = false
config.assets.compile = false
config.assets.precompile << 'application.js'
config.assets.precompile << 'application.css'
config.assets.precompile << 'screen.css'
Then I deploy, and that returns :
-----> Compiled slug size: 52.4MB
-----> Launching... done, v28
http://myapp.herokuapp.com deployed to Heroku
So it "compiled" something, right? Except no go, I go to the site and the .css and .js files are blank.
In order to precompile this locally, I am required to comment out in bootstraps_and_overrides.css the line :
#import "screen.css.scss";
Then it precompiles locally, and my local machine will not load the css correctly, but remotely it will actually work correctly.
So my method of deployment now is comment out that line of code,
bundle exec rake assets:precompile
git add .
git commit -m "Adding public/assets"
git push heroku development:master
Then ( unfortunately! ) :
bundle exec rake assets:clean
And then uncomment that line of code in my .css.
Some things to check
You're on Cedar, right? Heroku only supports this behavior on Cedar.
You're on Rails 3, right? Heroku doesn't support precompiling assets on Rails 4.
You have asset pipeline turned on, right? in config/application.rb you need the line config.assets.enabled = true
You have to not have a public/assets folder. On deployment Heroku decides whether or not to precompile based on whether this folder is present (even if it's empty).
If the pipeline is on and you don't have an assets folder, then pre-compilation must be failing.
Try changing to this. I hope this will help you.
In config/environments/production.rb
config.assets.compile = true
config.assets.digest = true
You might be on the wrong Heroku stack. Make sure you specify stack Cedar when you create apps that use the asset pipeline.
heroku create -stack cedar
The reason it would not deploy was because of Google fonts. Moving the file to your application.css such as :
*= require_self
*= require_tree .
*/
#import url(http://fonts.googleapis.com/css?family=Special+Elite);
Will allow the app to deploy, and for the fonts to work.
I have a Rails 3.2.11 running on the Heroku Cedar stack. I don't compile assets locally, they are compiled automatically during slug compilation, as described here. I have just created a new CSS manifest file app/assets/stylesheets/new_manifest.css.scss in addition to the default application.css.scss. When I push to Heroku, this manifest file is not getting compiled like application.css.scss is. The new manifest file works fine in development. Why would that be happening?
application.rb
config.assets.enabled = true
config.assets.version = '1.0'
config.assets.initialize_on_precompile = false
production.rb
config.assets.compile = false
config.serve_static_assets = false
config.assets.compress = true
config.assets.digest = true
Console output from Heroku push
-----> Preparing app for Rails asset pipeline
Running: rake assets:precompile
Asset precompilation completed (83.62s)
Sample page
<%= stylesheet_link_tag "new_manifest", media: "all" %>
The solution was to add config.assets.precompile += %w( new_manifest.css ) to production.rb, as described here. This isn't required in development, but is required in production, which caused my confusion.
If you say your new_manifest is a manifest file , it should be included in the main manifest for the application : application.css . In case you are including it by stylesheet_link_tag it is not under asset-pipeline control (it is treated like a pure CSS file , not as a manifest one). It is about to be precompiled also , but inclusions are about to be ignored . There is a more proper way to include additional manifest files into the main application.css : index files(look for 2.1.2 ) .