Search code examples
serverproduction-environmentpre-compilation

Why is my newly pushed Fly.io Rails7.0.8 app not finding my image & js assets?


I've launched and deployed my (very simple toy) app to Fly.io and it runs but as per console is getting a 404 response trying to load an image asset (there's only one!) and my Stimulus JS controller. Error messages:

GET https://top-odin-flight-booker.fly.dev/assets/controllers/flight_search_form_controller net::ERR_ABORTED 404 (Not Found) application-e7fafc70c0600c189e4ed9edd25c3fea7803e8ac98a17cafc91fe146f8f9fc85.css:1  
        
GET https://top-odin-flight-booker.fly.dev/assets/mountains.jpg 404 (Not Found)

I've run; RAILS_ENV=production rails assets:precompile locally and re-deployed, as well as run this precompile command via a flyctl ssh console session in case that would have helped. Through a console session I can see that the files are definitely present on the 'production' app on Fly.IO.

I have this setting in config/environments/production.rb; config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? and I've set; flyctl secrets set RAILS_SERVE_STATIC_FILES=true according to some info suggesting that I should.

I can see that the public/assets/.sprockets-manifest-....json file has a fingerprinted file name for the image which matches the actual image name in; public/assets/....

I still can't get the production app to see these two assets. Can anyone advise what I must be doing wrong/have forgotten/have incorrectly configured? (RoR 7.0.8 (ImportMaps), Ruby 3.1.2, TailwindCSS, Stimulus, Turbo, no docker, fly launch and deploy worked fine)


Solution

  • The problem with the image asset 404 was this line in a css file:

    background-image: url('/assets/mountains.jpg')
    

    which did not handle referencing the correct fingerprinted file in the ./public/assets/ directory. The solution that I found was changing this file to a css.erb file and using rails' asset_path helper method, like so:

    background-image: url(<%= asset_path('mountains.jpg') %>);
    

    The problem with my Stimulus js controller not being found was this line:

    app/javascript/controllers/application.js:

    import FlightSearchFormController from "./flight_search_form_controller"
    

    which caused no issue locally, but in production on the Fly server it resulted in a request being made to this url;

    https://my-app.fly.dev/assets/controllers/flight_search_form_controller
    

    which of course is not present, so changing the app/javascript/controllers/application.js line to:

    import FlightSearchFormController from "controllers/flight_search_form_controller"
    

    solved the issue with the request then being made to the correct location. 😅 Phew, hope this post can help someone else in future.