How to fix ActionText image attachment link resulting in error 404 - ruby-on-rails

I am trying to run a very simple CMS of a page with Action Text on my own server.
In development it all works fine. The attachment is uploaded and I can see it after saving my page model.
When switching to production the upload still works and I can see the file on the local file system, but viewing the page shows a broken image tag.
The link for the image looks like
http://example.com/rails/active_storage/representations/SIGNED_ID/myimage.png
On my local production the link is:
http://localhost:3000/rails/active_storage/disk/gsid/myimage.png?content_type=image%2Fpng&disposition=inline%3B+filename%3D%22myimage.png%22%3B+filename%2A%3DUTF-8%27%27myimage.png
I have provided a secrete_key_base, white-listed my host and all the stuff to get the application running for production.
I am using:
Unicorn
Nginx
Ruby 2.6.5
Rails 6.0.2.1
My storage service is "Disk" and all files and folders inside, including the RAILS_ROOT are owned by the user running the application.
storage.yml:
local:
service: Disk
root: <%= Rails.root.join("storage") %>
routes.rb:
Rails.application.routes.draw do
resources :pages, param: :seo_url, path: 'seite'
get '/index', to: 'application#home', as: :home
root to: 'application#home'
end
production.rb:
# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :local
Does anyone have a clue why this does not work?

I was able to solve my problem. I misconfigured my Nginx. I pasted the wrong config snippet for static image delivery into the config.
I removed the lines from the Nginx config. Everything is working fine now.
This is actually so embarrassing!

Related

Accessing rails active storage no routes matches error

I am trying to host rails sever as a backend.
Nginx will redirect to localhost:3000 when the route start with /api.
In my case, 'etl.robust.best/api' will go to host's localhost:3000 where rails have been hosted.
The problem is I cannot access images from active storage.
Instead I get no routes matches error.
config/storage.yml
I can access images from active storage when testing on my computer.
How do I fix this.
This is my development.rb file.
The config of nginx
You should check what your Rails.root is. You could do that in rails console, launched inside your app. Then check config/storage.yml and see that the path defined there for local storage matches the actual path. For example this would point to /storage inside your app:
local:
service: Disk
root: <%= Rails.root.join("storage") %>
More info on Active Storage here.

Impossible to serve generated images without restarting app with Rails + Passenger?

I have images that are generated by users and written to public/designer/designer_output folder.
In config/environments/production.rb I have
config.serve_static_files = true
config.assets.compile = true
In config/initializers/assets.rb I have
Rails.application.config.assets.paths << Rails.root.join('public', 'designer', 'designer_output')
Yet I can't access the files either by requesting /assets/file_name nor /public/designer/designer_output/file_name
If I restart the server then the files become available only via the /assets/ path. But I need them to be available as soon as they are created without restarting.
If find it odd that I can't access them through the public folder at all.
This is on Rails 4.2.6 with Apache/Passenger
Also I have carrierwave as an upload gem, and it is storing files in public/uploads folder and that works fine.
The public folder is used as the web root for the rails server.
You need to drop public in the path or URL:
<!-- file is at /public/foo/bar.png --!>
<img src="/foo/bar.png" />

rails 4: Errno::ENOENT (No such file or directory # rb_sysopen - /assets/

I've just deployed my app to heroku and I'm having a lot of trouble trying to read some assets.
I am trying to dynamically load some css from multiple files, then recompile them with some changes later. The line that keeps breaking is the first file load:
#css_asset_bootstrap = File.open(ActionController::Base.helpers.asset_path('bootstrap.css'), "r").read
which generates this error:
2015-04-07T23:30:50.098831+00:00 app[web.1]: Errno::ENOENT (No such file or directory # rb_sysopen - /assets/bootstrap-2d25733981c30e34bd9aa0fb75388f08.css):
I've tried a lot of things, including moving all my assets to aws cloudfront. Is there a way to get around this? Works perfectly in development environment.
Just to confirm a few things. I've successfully precompiled and uploaded the file. The file definately exists as I can see it in
heroku run bash
cd /public/assets/
I can also see it when I moved the assets to cloudfront.
Thanks.
edit 1:
Not sure if this is important information, but with the file on cloudfront, I can run heroku run bash to start a shell session on heroku. Then I can:
curl http://xxx.cloudfront.net/assets/bootstrap-2d25733981c30e34bd9aa0fb75388f08.css
And get the file ok. I was thinking maybe it was a permissions error but everything is set to public and it all seems to work from heroku to the aws server.
You're asking for the file from a relative path, which might not always work. Try absolute:
#css_asset_bootstrap = File.open(Rails.root + ActionController::Base.helpers.asset_path('bootstrap.css'), "r").read
Another possibly bigger problem is that Heroku has an ephemeral filesystem, and so any changes you write to it can be obliterated at any time when the dyno is culled.
In my case, using a virtual machine Rails.root give me this: '/home/vagrant/projects/.../my-nice-app' what is totally uncool.
I use instead request.url with give me: 'http://localhost:3000/' what it is exactly what I want.

How to handle uploads and logs in Rails when deployed as a .war file?

I am trying to deploy rails on jRuby using a .war file with the help of Warbler (Tomcat) and/or Torquebox 4 (Wildfly). The problem I face is that I don't know how to handle uploads with Carrierwave or Paperclip in this case.
Ideally uploads should be stored outside the war, as it may be replaced with a newer version of the app anytime.
I tried to create a symlink (uploads) in the public directory before I packaged the app as a war file to /home/username/uploads (permissions are set to 777) directory but that doesn't work (I get a 500 error).
Also how can I access the production.log after I deployed the war file? Or where should I place the logs?
UPDATE
I figured out how to config Carrierwave to store uploads outside the war file:
if Rails.env.development?
CarrierWave.configure do |config|
config.root = "/Users/Username/username_uploads/uploads"
end
elsif Rails.env.production?
CarrierWave.configure do |config|
config.root = "/home/username/username_uploads/uploads"
end
end
Now Carrierwave uploads the files without a problem, but I get a 404 error when I try to view them.
I tried to include a symlink inside the war file to the uploads folder but no success. I tried to create it before running warble war, and also after the app was deployed to Tomcat ( inside the app_name folder ).
Any idea how to solve this?
UPDATE 2
I found a working solution here:
Configure Symlinks for single directory in Tomcat
In short:
cd into the exploded war directory ( you can find this under tomcat/webapps ) that tomcat created ( if the name of the uploaded war file is yourapp.war then the directory name will be yourapp in Tomcat 8 ).
Create an uploads folder with sudo mkdir uploads
Create a mount point: sudo mount --bind /path/to/actual/upload/directory/uploads uploads
I haven't yet tested this with Wildfly, but I will later today or tomorrow. If I remember correctly it won't automatically explode war files by default.
I would still like to know additional, simpler, different solutions for the problem though, and also opinions about the solution I found.
Just food for thought on a different approach...
Using a "cloud based" storage service would make the upload and serving of the assets problem go away, it would also make it simpler to scale the app should you ever need a second node,
it would also reduce the need to scale the app because you would effectively delegate the large data operations which ruby traditionally handles badly to a different service
Amazon S3 is an obvious choice, but check out Riak too
I think the problem you are experiencing with this solution:
if Rails.env.development?
CarrierWave.configure do |config|
config.root = "/Users/Username/username_uploads/uploads"
end
elsif Rails.env.production?
CarrierWave.configure do |config|
config.root = "/home/username/username_uploads/uploads"
end
end
is that you are storing the images outside of the rails public folder, and therefore rails cannot serve them anymore. Carrierwave is uploading everything properly as you would expect it to do, and it creates links, relative to the storage dir.
If you would use the default #{Rails.root}/public storage, rails would serve your images, as any content from public is served (also static html or other assets). As Rails doesn't serve these anymore it's up to you to serve them.
Maybe you can just directly serve them through Tomcat (as I have no expertise in Tomcat configuration you have to figure this out yourself). This would maybe even be faster, as the request surpass the rails stack.
By default, Tomcat does not follow symbolic links (due security reasons). To enable this, you have to add the following inside the Host tag in your server.xml:
<!-- Tomcat 7: -->
<Context allowLinking="true" />
<!-- Tomcat 8: -->
<Context>
<Resources allowLinking="true" />
</Context>
See the docs and the latest migration guide.
If you could provide your logs it would be much easier to diagnose the problem (I take it this problem is only in production because you are asking about how to access that log?). Goto the rails app directory and look in log/production.log these log levels are often lower so you may have to configure them to be more informative config/enviroments/prouction.rb should have a config.log.level this is probably set to info set it to debug for more verbose logging.

Carrierwave leaves RackMultipart files in Rails root (development env)

So, whenever I upload a file in dev mode in Rails with Carrierwave, I get these temporary RackMultipart* files right in the Rails root. Even though in config/carrierwave.rb I have the following setting:
CarrierWave.configure do |config|
config.cache_dir = 'tmp/uploads'
end
And no, I didn't change cache dir in the uploader. Worst of all, it seems like for every new file upload, it creates 2 identical (in content, but not in name) RackMultipart* files. Any idea how to fix this?
This is a problem with the sticky bit.
You must do :
chmod o+t /tmp
Then in rails console check the path with :
Dir::tmpdir

Resources