Precompiled CSS File not found with rails 4 asset pipeline - ruby-on-rails

I'm starting in rails and I've got an application that is working in dev (webrick).
The problem is: the precompiled CSS file is not found in production.
Now I host it on heroku and deploy it. I have a message saying that assets are precompiled (so it's not a compilation error) and everything is by-default for settings.
I've ls the /public/assets folder and everything is in there. I can even cat the application-*.css file and I get the full content I should have.
Now when I try to access the CSS file it gives me an error 404 (even tho it's an auto-generated css link usingĀ <%= stylesheet_link_tag "application", :media => "all" %>). So definetly it's not a problem that I did hardcode the CSS link.
I'm not exactly sure on what would be the next check to perform.
If you're curious on the output, it is currently publicly accessible here.

Try changing the configuration option config.serve_static_assets = false to config.serve_static_assets = true in your config/environments/production.rb if you haven't already done that.

The only thing that fixed it for me in Rails 4 was
config.assets.compile = true
in config/environments/production.rb
This would fall back to the assets pipeline if a precompiled asset is missed, according to the documentation.

Related

Rails 7 css assets are not working in production, need help understanding how the asset pipeline works without webpacker

Trying out rails 7, with tailwind and postcss.
I have a few stylesheets in assets/stylesheets, which I import through a file called imports.css in the same folder.
//imports.css
#import stylesheet1.css;
#import stylesheet2.css;
I then import that file in application.html.erb with the following:
//application.html.erb
<%= stylesheet_link_tag "application", "imports", "data-turbo-track": "reload" %>
On development everything works fine as intended, meshes well with tailwind. Importing works fine due to postcss. However on production (nginx, puma) it tries to pull in those files and fails. For every stylesheet I have, i see in the browser console:
GET https://mywebsite.com/assets/style/stylesheet1.css net::ERR_ABORTED 404 (Not Found)
I am trying to shift my brain over from webpacker in rails 6, not sure what I need to do here... some thoughts:
Do i need to set it up so that the stylesheets get copied over to the public/assets folder or something? Is there a setting to do that in production.rb? (I feel like rails by default should be already doing this)
Do I need to be manually precompiling these assets on deployment?
Help would be appreciated. Thanks!
#stellenberger was right and deserves the credit. In my case their solution of enabling the public file server for static assets fixed this issue for me and immediately started serving the css assets from public. I was already precompiling, they just weren't being served. I am using Rails docker containers on an EC2 in AWS behind an ALB, and there is no local NGINX so the default assumed is not correct for my scenario and needed to be changed.
The config/environments/production.rb file already provides an environment variable that will turn on the public server if present, called RAILS_SERVE_STATIC_FILES so all you need to do is set that environment variable in your build or deploy process. Since it is a presence check, any value will be truthy as the var existence is all that is checked.
Alternatively, you could also set
# config/environments/production.rb
config.public_file_server.enabled = true
in the file instead of using the ENV var, but generally the ENV vars are better than hard-coded configs.
In my case, I changed the default to
# config/environments/production.rb
config.public_file_server.enabled = ENV.fetch("RAILS_SERVE_STATIC_FILES") { true }
that way my default is true and enabled without setting the var, but I can still use the var to disable it if desired.
Do I need to be manually precompiling these assets on deployment?
Yes. Since you're not using a Node workflow now, instead relying on Sprockets and assets directly, you need the precompile step in Production.
Setting the environment variables RAILS_ENV=production and RAILS_SERVE_STATIC_FILES=true did the job for me (with Rails 7.0.4).

Rails 4 app with precompiled assets on Elastic Beanstalk with Puma and Nginx serving page with old asset links

I have to precompile assets locally in order for one of my JS plugins to work correctly.
Whenever I make a change to any asset and precompile, I get a new version in public/assets, and the old one is there, too. When I run locally in production mode, I am served a page with the new assets.
When I deploy to EB, the pages always contain links to the old assets.
Of course, application.html.erb uses the dynamic css link tag: <%= stylesheet_link_tag "application", media: "all" %>
production.rb contains:
config.action_controller.perform_caching = true
config.assets.compile = true
I think this must have something to do with Nginx or some sort of caching in EC2 on the html files because puma runs locally.
I have tried:
Different browser, PC, cleared cache, disable cache. It is not the browser.
Setting send file off in nginx.conf.
Setting cache expiration to -1 for html and confirmed with curl that I receive Cache-Control: no-cache
Renamed entire app/current folder. I still receive a page, but it is missing the CSS. Where are the files that are actually used after a server is started?
rake tmp:clear on the server.
Looking all over the server for any nginx or puma cache. I found nothing.
Researching for hours on end over the past 2 years.
The only thing that ever works is to rake assets:clobber, create a new EB environment, and deploy a few times. Sometimes, even that doesn't work.
Please help!
After additional countless hours of failing to solve this, I noticed a variable in the Elastic Beanstalk configuration settings that I had been changing from the default value. RAILS_SKIP_ASSET_COMPILATION - I was setting it to true since I was trying to manage the asset compilation myself. Flipping this back to false fixed my issue and significantly increased my deployment time. My third-party javascripts and gems all work correctly as well.
I still think this is a workaround because I should be able to precompile manually. However, it is good enough for me at this time.
I had a similar issue with caching assets on staging or production server. When I checked Last-Modified attribute of an asset file, for example with curl -I http://url-to-the-asset-file server returned old (cached) file.
What solve the issue was updating assets version in production.rb file. It will force assets to recompile with new MD5 hash fingerprint.
# config/environments/production.rb
# Version of your assets, change this if you want to expire all your assets.
config.assets.version = '1.1'
Hopefully this will help you or at least give some guidance.

Heroku can't find some of my rails assets

I'm new to web development, and I've been working on a simple app for learning purposes. I've been able to deploy to Heroku from my local machine, but for some reason, the custom classes that I use for some vector images aren't rendering on Heroku.
This is my page, and as you can see, there are just squares where there should be different images. Looking in the inspector, you see the following errors:
Failed to load resource: the server responded with a status of 404 (Not Found) - https://enigmatic-hollows-2702.herokuapp.com/assets/flaticon.woff
Failed to load resource: the server responded with a status of 404 (Not Found) https://enigmatic-hollows-2702.herokuapp.com/assets/flaticon.ttf
I have tried recompiling assets, recommitting, and pushing to Heroku, but this error persists. What's weird is that if I use Heroku Bash and view the Heroku file directory, it looks like the files are there:
But they are still throwing up that error in the inspector. I've also got the following set in my production.rb file:
config.cache_classes = true
config.eager_load = true
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
config.serve_static_assets = true
config.assets.compile = true
config.assets.js_compressor = :uglifier
Any idea what could be causing this asset issue? I'm using Rails 4.2.0.
I was able to answer my own question after reading through this link. Essentially, I moved the font files out of my CSS directory and into their own fonts directory under the app/assets directory, and then in production.rb added the following line to the Application class:
config.assets.paths << Rails.root.join("app", "assets", "fonts")
and presto! It worked. I didn't mess around with #font-face in CSS, since the assets I'm using from flat-icons are built through custom classes used in span or div blocks.

dynamic asset loading heroku

I'm implementing a site tour feature for the website https://looky.co, and I want to only send the site_tour.js file when a show_site_tour is set to true. (show_site_tour is a database column).
I have it set up in my application.html.haml (layout file). The problem is with the way heroku runs the asset pipeline.
Directory structure
\ app
\ assets
\ javascripts
\ guiders
site_tour.js
Basically the problem is that when I try to include that folder only on the condition that the database column is equal to true, heroku gives an "asset not precompiled" error.
In my application.html.haml
%head
= javascript_include_tag 'application'
- if current_user.show_site_tour == true
= javascript_include_tag 'guiders/site_tour'
So how can I make this work with the heroku pipeline?
Basically the main question is, how can I have more than one javascript file on heroku?
This answer should help.
Basically, you need to tell the asset pipeline to keep the site_tour file separate.
config.assets.precompile += %w( guiders/site_tour )
You should end up with two JavaScript files after this setting takes affect, application.js and site_tour.js.
You can test this locally by precompiling the assets using rake.
bundle exec rake assets:precompile
This will show you how the output will end up on Heroku.
It's probably also worth noting that Heroku requires that you have the following setting set to false.
config.assets.initialize_on_precompile = false

Asset Pipeline Rails 3.2 not working in production

How to make Apache+Passenger and Rails Asset Pipeline work together nice?
When I deploy my locally working project, I get a 500 error
In ActionView::Template::Error occurred in pages#start: jquery-ui-1.8.21.custom.min isn't precompiled
If I grep my_project/current/assets_manifest.yml for jquery-ui-1.8, it gives me
jquery-ui-1.8.21.custom.min.js: jquery-ui-1.8.21.custom.minc50ea0bef9c2fae04ab3b50ead60fc1f.js
and this file also exists in my_project/shared/assets (along with jquery-ui-1.8.21.custom.min-c50ea0bef9c2fae04ab3b50ead60fc1f.js.gz, jquery-ui-1.8.21.custom.min.js, jquery-ui-1.8.21.custom.min.js.gz).
When I open
http://mytestserver/assets/jquery-ui-1.8.21.custom.min-c50ea0bef9c2fae04ab3b50ead60fc1f.js
in browser it gives me the correct js file.
The 500 error is raised from
app/views/layouts/application.haml:25
line 24-26 of that file are:
= javascript_include_tag "application"
= javascript_include_tag "jquery-ui-1.8.21.custom.min"
= csrf_meta_tag
So what could have gone wrong? Why is it not working?
If the file isn't being loaded by application.js then you need to add a line to application.rb so the app knows about it:
config.assets.precompile += ['jquery-ui-1.8.21.custom.min.js']
shared/assets is not a place that the asset pipeline typically looks for files.
Typically the asset pipeline looks in app/assets, it may look in lib/assets and I'm pretty sure it looks in vendor/assets also. But it's possible that the vendor/assets is not included by default, which I talk about below.
Per Rails convention I suggest you put that dependency in vendor/assets/javascripts
If you want to add search directories to the asset pipeline it's just a simple modification to config.application.rb
in the YourProject::Application declaration, add:
config.assets.paths << Rails.root.join("vendor/assets/javascripts")
Or whatever other path you want.
I think I solved it.. I think this were the steps:
renaming the rake-namespace of capistrano deployment (possible duplication of namespace and var damage) which was also doing the precompilation
add each js file that I include via javascript_include_tag to config.assets.precompile for production environment like #Simon suggested
in config.assets.precompile they seem to be mentioned without .js-extension, whereas in the javascript_include_tag directives they should be included with .js-extension

Resources