I have been handed a Ruby Project that creates a document and serves it to the user, when I try to access the file on a local environment it it is delivered correctly, (this is the code that does so).
filepath = Rails.root.join("public",@records.document.url)
send_file (filepath)
So I know the file is constructed correctly and sending it to the user using send_file works at least in a local environment.
But when it's deployed on the production server (running Amazon EC2, ubuntu, deployed with dokku) I get a 500 Internal server error:
ActionController::MissingFile (Cannot read file *path of the file*)
Few things I'm noticing: doing a find / -iname "*filename*"
tells me the file is stored in var/lib/docker/overlay2/*container_name*/merged/app/public/filename
and var/lib/docker/overlay2/*container_name*/diff/app/public/filename
but the result of joining Rails.root
with the filename is app/public/filename
, do I need to pass send_file
the whole filepath?
I googled for a couple hours and it seems nginx has no access to the public folder because it's running in the host machine while the app is inside a container? How would I know if that is the case and if so, how should I serve the file?
The person who originally wrote the code told me to use OpenURI.open_uri() but googling it doesn't seem to turn up anything applicable to the situation.
Nothing you're doing here actually makes sense - its sounds like you're just following a bunch of misinformation down a bunch of rabbit holes.
The way this is supposed to work is that the files in
/public
- not/app/public
are served directly by the HTTP server (NGinX or Apache) in production and your Rails application in development (so you don't have to configure a local HTTP server). The/app
directory is for your application code and uncompiled assets. Do not serve files from there - ever.The
/public
directory is used for your compiled assets and stuff likerobots.txt
, the default error pages and various icons. Serving the files directly by your HTTP server is far more efficient then serving them through your Rails application. You can do a litmus test to see if serving static assets are working by sendingcurl -v YOUR_URL/robots.txt
.If this isn't working in production you need to check your NGinX configuration. There is no shortage of guides on how to serve static files with NGinX and Docker.
Serving files with a Rails controller and
send_data
/send_file
should only be done when its actually needed: