Ruby activestorage Heroku AWS S3 - heroku

I have a web app working on heroku right now, I configure my app to stored in assets the fav-icon and company logo that I and use only in the login.
The problem is that Im trying to use activestorage and aws s3 to start uploading images of my employees in heroku.
I follow all documentation to use activestorage and all docs about how to configure Heroku and AWS S3.
runing my app local works with activestorage and s3 I can upload images to my S3 bucket and all looks great, the problem is when I try to deploy this version to heroku the upload (when i use "git push heroku master") don't mark any error but when i try to access my app my app these do not work.
My heroku logs show me
2020-03-27T16:38:47.835694+00:00 app[web.1]: from bin/rails:9:in `<main>'
2020-03-27T16:38:47.889395+00:00 app[web.1]: => Booting Puma
2020-03-27T16:38:47.889418+00:00 app[web.1]: => Rails 5.2.4.1 application starting in production
2020-03-27T16:38:47.889419+00:00 app[web.1]: => Run `rails server -h` for more startup options
2020-03-27T16:38:47.889419+00:00 app[web.1]: Exiting
2020-03-27T16:38:57.236728+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/admin/client" host=admin.ttpn.com.mx request_id=6568febe-d894-4751-bf2c-c6d8d1539146 fwd="189.237.90.141" dyno= connect= service= status=503 bytes= protocol=https
My employee model have the fields to use with railsandmin and the code to use activestorage :
class Employee < ApplicationRecord
has_one_attached :avatar
attr_accessor :remove_avatar
after_save { avatar.purge if remove_avatar == '1' }
The rails_admin configuration to use images is:
rails_admin do
create do
field :avatar, :active_storage
field ...
end
edit do
field :avatar, :active_storage do
delete_method :remove_avatar
end
field ...
end
end
end
My storege.yml code is:
local:
service: S3
access_key_id: <%= Rails.application.credentials.amazon[:access_key_id] %>
secret_access_key: <%= Rails.application.credentials.amazon[:secret_access_key] %>
region: <%= Rails.application.credentials.test[:region] %>
bucket: <%= Rails.application.credentials.test[:bucket] %>
amazon:
service: S3
access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
region: us-east-2
bucket: <%= ENV['BUCKET_NAME'] %>
All ENV[] variable are configured right now in Heroku.
Some one can help me to found a solution why my app dont work in heroku
Tks

#antonio-castellanos-loya considering you stated that the application works fine in your local environment, is uploading images to s3 in development, AND is deploying without failing, I'm going to make the assumption that this is an issue with your heroku instance.
did you try running the migrations on the heroku instance?
heroku run rails db:migrate
This is the first thing I'd check, especially since your app is exiting immediately upon booting as per your logs.

Related

Why do the pictures attached to my seeded items not display on Heroku (ERROR 500)?

First-time poster, I tried to follow the rules but please tell me if anything is missing and/or needs to be edited in this question.
TL;DR : using ActiveStorage, pictures associated to items display fine on localhost but not on Heroku
Initial setup
In an educational context, my team and I are building a simple Ruby On Rails application. We have to use Ruby 2.5.1 and Rails 5.2.4 with a postgresql 9.5 database in development, and we have to use Heroku for production.
The source code is hosted on a GitLab instance name Framagit. We are using the GitLab pipeline to deploy the code to Heroku everytime a merge is completed in the staging branch.
Procfile is as follows :
realease: rails db:migrate && rails db:seed
web: rails server
On this app, the main model is Compost. Each instance has one picture. These pictures are stored under :
app/assets/images/compost_pictures/compost_{001-007}.jpg
ActiveStorage setup
ActiveStorage has been installed by running $ rails active_storage:install followed by $ rails db:migrate which created the active_storage_attachments and active_storage_blobs tables in db/schema.rb.
app/models/compost.rb was updated with :
# Active Storage picture association
has_one_attached :picture
app/views/composts/show.html.erb now includes :
<div class="col-8">
<% if #compost.picture.attached? %>
<%= image_tag #compost.picture, style:"height: auto; max-width:100%" %>
<% else %>
<h3> Hey, why don't you provide a nice compost picture ?</h3>
<% end %>
</div>
(also tried with image_tag url_for(#compost.picture) with no success on Heroku, although it works on localhost)
(#compost is set in the controller and works fine for other composts attributes display)
and db/seeds.rb was updated with :
def compost_seed(user)
new_compost = user.owned_composts.create!( all the attributes...)
picture_file_name = 'compost_' + (format '%03d', rand(1..7)) + '.jpg'
picture_path = Rails.root.join("app", "assets", "images", "compost_pictures", picture_file_name)
new_compost.picture.attach(
io: File.open(picture_path),
filename: picture_file_name,
content_type: "image/jpg"
)
end
Running the server
Locally
On localhost with the Rails server set to development, everything works fine, pictures are displayed.
I've set up a simulated production environment like this :
$ RAILS_ENV=production rails db:create db:migrate
# completed with no error
$ RAILS_ENV=production rails assets:precompile
# completed with no error
$ RAILS_ENV=production rails db:seed
# completed with no error
$ RAILS_ENV=production SERVE_STATIC_ASSETS=true rails server
# server runs smoothly
Everything works fine, pictures are displayed.
On Heroku
none of the pictures is displayed : they are replaced by a broken image symbol
when in Heroku rails console, > Compost.all.sample.picture.attached? returns true
in the browser, the URL of the image is https://ok-compost-staging.herokuapp.com/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWRaV2huZW1SRGVESkRTRE5sWWxoSGJYSlJSakpTVG5OVUJqb0dSVlE2RUdScGMzQnZjMmwwYVc5dVNTSkphVzVzYVc1bE95Qm1hV3hsYm1GdFpUMGlZMjl0Y0c5emRGOHdNRFl1YW5Cbklqc2dabWxzWlc1aGJXVXFQVlZVUmkwNEp5ZGpiMjF3YjNOMFh6QXdOaTVxY0djR093WlVPaEZqYjI1MFpXNTBYM1I1Y0dWSklnOXBiV0ZuWlM5cWNHVm5CanNHVkE9PSIsImV4cCI6IjIwMTktMTItMDdUMDA6NDM6NTUuNTYzWiIsInB1ciI6ImJsb2Jfa2V5In19--ee616a99d031d361f2b63aeb869ca5d787ef44a8/compost_006.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22compost_006.jpg%22%3B+filename%2A%3DUTF-8%27%27compost_006.jpg and trying to visit it ends up with a 'We're sorry, but something went wrong'.
The logs are :
2019-12-07T00:44:44.433822+00:00 heroku[router]: at=info method=GET path="/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWRVMVI1ZERoQ1ZXUlFibUpTTVZGNFRWbEVUamhaVldsMkJqb0dSVlE2RUdScGMzQnZjMmwwYVc5dVNTSkphVzVzYVc1bE95Qm1hV3hsYm1GdFpUMGlZMjl0Y0c5emRGOHdNREV1YW5Cbklqc2dabWxzWlc1aGJXVXFQVlZVUmkwNEp5ZGpiMjF3YjNOMFh6QXdNUzVxY0djR093WlVPaEZqYjI1MFpXNTBYM1I1Y0dWSklnOXBiV0ZuWlM5cWNHVm5CanNHVkE9PSIsImV4cCI6IjIwMTktMTItMDdUMDA6NDk6MzcuMzI2WiIsInB1ciI6ImJsb2Jfa2V5In19--cae4ff5349cfa4a394c081da5827f0c35ce96c08/compost_001.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22compost_001.jpg%22%3B+filename%2A%3DUTF-8%27%27compost_001.jpg" host=ok-compost-staging.herokuapp.com request_id=e8ca9a03-07c4-459d-ab20-4e096da30e87 fwd="78.201.127.110" dyno=web.1 connect=0ms service=4ms status=500 bytes=1827 protocol=https
2019-12-07T00:44:47.277080+00:00 app[web.1]: I, [2019-12-07T00:44:47.276974 #4] INFO -- : [f8400596-5b61-4569-ad22-b514afe4b32a] Started GET "/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWRVMVI1ZERoQ1ZXUlFibUpTTVZGNFRWbEVUamhaVldsMkJqb0dSVlE2RUdScGMzQnZjMmwwYVc5dVNTSkphVzVzYVc1bE95Qm1hV3hsYm1GdFpUMGlZMjl0Y0c5emRGOHdNREV1YW5Cbklqc2dabWxzWlc1aGJXVXFQVlZVUmkwNEp5ZGpiMjF3YjNOMFh6QXdNUzVxY0djR093WlVPaEZqYjI1MFpXNTBYM1I1Y0dWSklnOXBiV0ZuWlM5cWNHVm5CanNHVkE9PSIsImV4cCI6IjIwMTktMTItMDdUMDA6NDk6MzcuMzI2WiIsInB1ciI6ImJsb2Jfa2V5In19--cae4ff5349cfa4a394c081da5827f0c35ce96c08/compost_001.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22compost_001.jpg%22%3B+filename%2A%3DUTF-8%27%27compost_001.jpg" for 78.201.127.110 at 2019-12-07 00:44:47 +0000
2019-12-07T00:44:47.277980+00:00 app[web.1]: I, [2019-12-07T00:44:47.277897 #4] INFO -- : [f8400596-5b61-4569-ad22-b514afe4b32a] Processing by ActiveStorage::DiskController#show as JPEG
2019-12-07T00:44:47.278103+00:00 app[web.1]: I, [2019-12-07T00:44:47.278010 #4] INFO -- : [f8400596-5b61-4569-ad22-b514afe4b32a] Parameters: {"content_type"=>"image/jpeg", "disposition"=>"inline; filename=\"compost_001.jpg\"; filename*=UTF-8''compost_001.jpg", "encoded_key"=>"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWRVMVI1ZERoQ1ZXUlFibUpTTVZGNFRWbEVUamhaVldsMkJqb0dSVlE2RUdScGMzQnZjMmwwYVc5dVNTSkphVzVzYVc1bE95Qm1hV3hsYm1GdFpUMGlZMjl0Y0c5emRGOHdNREV1YW5Cbklqc2dabWxzWlc1aGJXVXFQVlZVUmkwNEp5ZGpiMjF3YjNOMFh6QXdNUzVxY0djR093WlVPaEZqYjI1MFpXNTBYM1I1Y0dWSklnOXBiV0ZuWlM5cWNHVm5CanNHVkE9PSIsImV4cCI6IjIwMTktMTItMDdUMDA6NDk6MzcuMzI2WiIsInB1ciI6ImJsb2Jfa2V5In19--cae4ff5349cfa4a394c081da5827f0c35ce96c08", "filename"=>"compost_001"}
2019-12-07T00:44:47.279105+00:00 app[web.1]: I, [2019-12-07T00:44:47.279040 #4] INFO -- : [f8400596-5b61-4569-ad22-b514afe4b32a] Completed 500 Internal Server Error in 1ms (ActiveRecord: 0.0ms)
2019-12-07T00:44:47.279772+00:00 app[web.1]: F, [2019-12-07T00:44:47.279702 #4] FATAL -- : [f8400596-5b61-4569-ad22-b514afe4b32a]
2019-12-07T00:44:47.279842+00:00 app[web.1]: F, [2019-12-07T00:44:47.279773 #4] FATAL -- : [f8400596-5b61-4569-ad22-b514afe4b32a] Errno::ENOENT (No such file or directory # rb_file_s_mtime - /app/storage/ST/yt/STyt8BUdPnbR1QxMYDN8YUiv)
The images were properly displayed when we fetched them via their URL in the assets pipeline.
So, what now ?
According to the logs, we guess this is a path issue. What are we missing ? At what point are we mistaken ?
We'll update the post with any required code snippet or test result, this is an educational project and nothing about it is private or sensitive.
Any insight or pointer appreciated :)
Workaround : use cloud storage instead of local disk in production
Since all the other images (background, logos, etc.) were displayed properly, the problem had to lie with our Active Storage use.
According to Heroku doc on Active Storage they use Ephemeral Disks for Active Storage and files are not persisted neither across dyno nor over time. So our guess was that our attachments were not stored on the dyno that served our application.
Connecting the production storage to a free-tier AWS bucket as suggested in Heroku doc worked for us and images are displayed properly.

Sinatra app 404's when deployed to Heroku

I am working with an app and am looking to deploy to heroku. Full source here.
The primary error that I am seeing is
heroku[router]: at=info method=GET path="/" host=cheesyparts.herokuapp.com request_id=25d2dbb5-e13a-4146-bb3a-9386f997c44c fwd="54.234.191.55" dyno=web.1 connect=2 service=3 status=404 bytes=417
Locally when I attempt to lauch via foreman the same issue occurs. However, I am able to launch the server and run it if I use the ruby parts_server_control.rb run. Any tip is appreciated.
The config.ru looks like this
require './parts_server'
run Sinatra::Application
and the control script parts_server_control.rb looks like:
require "bundler/setup"
require "daemons"
require "pathological"
require "thin"
Daemons.run_proc("parts_server", :monitor => true) do
require "parts_server"
Thin::Server.start("0.0.0.0", PORT, CheesyParts::Server)
end
The control script is running the app class CheesyParts::Server, but your but your config.ru (used by foreman and Heroku) assumes the app written in the classic style and is using the class Sinatra::Application. See the Sinatra docs on modular and classic application styles. Since nothing is added to Sinatra::Application it is an “empty” app and so you will get 404 errors for any route.
The fix is to change the line
run Sinatra::Application
in your config.ru to
run CheesyParts::Server
so that that class will be used as the main app.

How to get content to display on Heroku from a Ruby app built with Nesta CMS?

I added the demo files and ran the app just fine locally
But I ran into problems when i deployed to heroku, the content was not showing
I read through the documentation on the official site for nesta at
http://nestacms.com/docs/deployment/heroku
But they pretty much just make a comment rather than offering instruction
Make sure that you fill in config/config.yml properly (the most important thing is to ensure that caching is off, as we can’t write to Heroku’s file system).
Well I followed their documentation elsewhere
http://nestacms.com/docs/config
And then made changes to my config.yml file. Most relevant changes below
title: "Practice Nesta Site"
subtitle: "Nesta is pretty cool"
author:
name: Juan Gallardo
uri: nestademo1.herokuapp.com
email: jgallardo720#gmail.com
# cache
# Set it to true if you'd like Nesta to cache your pages in ./public.
# Useful if you're deploying Nesta with a proxy server such as Nginx,
# but not in the least bit helpful if your pages are dynamic, or you're
# deploying Nesta to Heroku.
#
cache: false
# content
# The root directory where nesta will look for your article files.
# Should contain "pages" and "attachments" subdirectories that contain
# your actual content and the (optional) menu.txt file that links to your
# main category pages.
#
content: content
# Overriding "cache" and "content" in production is recommended if you're
# deploying Nesta to your own server (but see the deployment documentation
# on the Nesta site). Setting google_analytics_code in production is
# recommended regardless of how you're deploying (if you have a GA account!).
#
# Don't forget to uncomment the "production:" line too...
production:
cache: false
content: /var/apps/nesta/shared/content
# google_analytics_code: "UA-???????-?"
read_more: See full page
Full file at this gist
https://gist.github.com/JGallardo/6195651
I ran heroku logs
jgallardo:demo-site juan.gallardo$ heroku logs
2013-08-09T17:22:21+00:00 heroku[slug-compiler]: Slug compilation started
2013-08-09T17:23:35.001505+00:00 heroku[api]: Scale to web=1 by jgallardo720#gmail.com
2013-08-09T17:23:35.026933+00:00 heroku[api]: Deploy 953af2e by jgallardo720#gmail.com
2013-08-09T17:23:35.046866+00:00 heroku[api]: Release v3 created by jgallardo720#gmail.com
2013-08-09T17:23:35.085708+00:00 heroku[api]: Deploy 953af2e by jgallardo720#gmail.com
2013-08-09T17:23:35+00:00 heroku[slug-compiler]: Slug compilation finished
2013-08-09T17:23:39.139164+00:00 heroku[web.1]: Starting process with commandbundle exec rackup config.ru -p 4751
2013-08-09T17:23:42.686255+00:00 app[web.1]: [2013-08-09 17:23:42] INFO WEBrick 1.3.1
2013-08-09T17:23:42.686255+00:00 app[web.1]: [2013-08-09 17:23:42] INFO ruby 2.0.0 (2013-06-27) [x86_64-linux]
2013-08-09T17:23:42.686477+00:00 app[web.1]: [2013-08-09 17:23:42] INFO WEBrick::HTTPServer#start: pid=2 port=4751
2013-08-09T17:23:43.030091+00:00 heroku[web.1]: State changed from starting to up
2013-08-09T17:36:17.229501+00:00 heroku[router]: at=info method=GET path=/ host=nestademo1.herokuapp.com fwd="98.173.1.66" dyno=web.1 connect=4ms service=51ms status=404 bytes=1570
2013-08-09T17:36:17.658553+00:00 heroku[router]: at=info method=GET path=/css/master.css host=nestademo1.herokuapp.com fwd="98.173.1.66" dyno=web.1 connect=4ms service=129ms status=200 bytes=5548
This line is the problem:
content: /var/apps/nesta/shared/content
Change it to this:
content: content
And make sure that your content is checked into the code repo. You've probably found this page already, right? http://nestacms.com/docs/deployment/heroku

How do I deploy Sinatra + mustache onto Heroku?

I have a really basic Sinatra site working locally. I am using the "rackup" thing, where you define a config.ru like this:
require './web'
use Rack::ShowExceptions
run App.new
And then in the terminal you can run 'rackup' and a web server is fired up and all is well.
However, when I deploy this to heroku I don't get any error messages, but, when I visit the site, it says the standard "Sinatra does not know this ditty" error.
Here is a snippet of my web.rb in case it helps:
require 'sinatra'
require 'maruku'
require 'mustache/sinatra'
require 'nokogiri'
class App < Sinatra::Base
register Mustache::Sinatra
require './views/layout'
set :mustache, {
:views => './views/',
:templates => './templates/'
}
get '/' do
"FUUUUUUUUUUUUU"
end
Edit
Looking at the heroku logs, it appears like sinatra starts and then stops; it doesn't keep running. Then when someone makes a request obviously the server returns a 404
2012-01-20T12:39:23+00:00 app[web.1]: == Sinatra/1.1.0 has taken the stage on 16662 for development with backup from Thin
2012-01-20T12:39:23+00:00 app[web.1]: >> Thin web server (v1.2.7 codename No Hup)
2012-01-20T12:39:23+00:00 app[web.1]: >> Maximum connections set to 1024
2012-01-20T12:39:23+00:00 app[web.1]: >> Listening on 0.0.0.0:16662, CTRL+C to stop
2012-01-20T12:39:23+00:00 app[web.1]: == Sinatra has ended his set (crowd applauds)
2012-01-20T12:39:23+00:00 app[web.1]:
2012-01-20T12:39:23+00:00 app[web.1]: >> Stopping ...
2012-01-20T12:39:23+00:00 heroku[web.1]: Process exited
2012-01-20T12:39:24+00:00 heroku[router]: GET young-river-2245.herokuapp.com/ dyno=web.1 queue=0 wait=0ms service=48ms status=404 bytes=409
Whenever you inherit from Sinatra::Base you must require 'sinatra/base' rather than require 'sinatra' at the top of your web.rb file.
I just ran a simple test using your snippets and was able to replicate and then fix the error by doing this.

Downloading: Paperclip, S3, Heroku, and x_sendfile

I have what i imagine is a fairly common setup.
My rails 3 app is hosted on Heroku, and i use Paperclip to manage file uploading, of videos and images, with all files saved on Amazon S3. The model that the files are attached to is Entry, and the attachments themselves are called 'media'. So, I have paperclip set up like this:
class Entry < ActiveRecord::Base
has_attached_file :media, {:storage=>:s3,
:bucket=>"mybucketname",
:s3_credentials=> <credentials hash>}
This is all working fine. But, I now want to add download links to the files, so the user can download the videos for editing for example. I've done this as follows:
Download link on the page:
<p><%= link_to "Download", download_entry_path(entry) %></p>
This just calls a download action in EntriesController which looks like this:
def download
#entry = Entry.find(params[:id])
if #entry.media.file?
send_file #entry.media.to_file, :type => #entry.media_content_type,
:disposition => 'attachment',
:filename => #entry.media_file_name,
:x_sendfile => true
else
flash[:notice] = "Sorry, there was a problem downloading this file"
redirect_to report_path(#entry.report) and return
end
end
Since some of the downloads will be very large, i'd like to hive the download off to the server to avoid tying up a dyno. That's why i'm using the x_sendfile option. However, i don't think it's set up properly: in the heroku log i can see this:
2011-06-30T11:57:33+00:00 app[web.1]: X-Accel-Mapping header missing
2011-06-30T11:57:33+00:00 app[web.1]:
2011-06-30T11:57:33+00:00 app[web.1]: Started GET "/entries/7/download" for 77.89.149.137 at 2011-06-30 04:57:33 -0700
2011-06-30T11:57:33+00:00 app[web.1]: ### params = {"action"=>"download", "controller"=>"entries", "id"=>"7"}
2011-06-30T11:57:33+00:00 heroku[router]: GET <my-app>/entries/7/download dyno=web.1 queue=0 wait=0ms service=438ms status=200 bytes=94741
The "X-Accel-Mapping header missing" message suggests that something's not right, but i don't know what. Basically i don't know if heroku's nginx server takes on file downloading automatically, and if not then how to tell it to, and i can't find anything in heroku's documentation about it (i might be looking for the wrong thing).
Can anyone set me straight? Grateful for any advice - max
I'm not sure why you're sending files via the server. If they're stored on S3, why not just link right to them?
<%= link_to "Download", entry.media.url %>
That way the downloads bypass your Heroku server altogether.

Resources