Carrierwave with S3 and Cloudfront not displaying images - ruby

Hello I am currently building a site using Rails and Heroku as well as GoDaddy for a custom domain name.
I am using Carrierwave with Fog, Amazon S3, and have set up a cloudfront with my Heroku domain name as the Origin Domain. Currently, the site loads up images very slow which is why I set up a cloudfront, but my carrierwave's config file doesn't seem to change the urls to the cloudfront counterparts. Here is my carrierwave config file. I would like users to be able to upload images through Carrierwave and then have those served back with my cloudfront.
CarrierWave.configure do |config|
config.fog_provider = 'fog/aws' # required
config.fog_credentials = {
provider: 'AWS', # required
aws_access_key_id: 'acesskey', # required
aws_secret_access_key: 'secretkey', # required
region: 'us-east-1', # optional, defaults to 'us-east-1'
}
config.fog_directory = 'directory' # required
# config.fog_public = false # optional, defaults to true
config.asset_host = 'randomjunk.cloudfront.net'
config.fog_public = false
config.fog_attributes = { 'Cache-Control' => "max-age=#{365.day.to_i}" } # optional, defaults to {}
end
It works as long as config.fog_public is false but when I change it to config.fog_public = true the urls are now correct but the images are not found. Is this something to do with my configuration settings or have I set up my cloudfront with Heroku incorrectly?

It depends on the settings that were used when you created the files initially. If they were created with config.fog_public = false they will be private files and access will be done with a special signed url to s3. I think the asset host is just used for files that are public (hence what you are seeing). If you upload files with fog_public = true then I don't think you would see the not found. You may also be able to just set it to true and re-save images to change that attribute (I'm less sure about specifics here, you certainly should be able to change them to public though).

Related

Amazon S3: how to set requests to use virtual host in ruby aws sdk

Currently, I am sending GET requests to S3 using aws-sdk ruby as follow:
#!/usr/bin/ruby
#
require 'aws-sdk'
s3 = Aws::S3::Resource.new(region: 'test', endpoint:'http://10.0.23.45:8081')
my_bucket = s3.bucket('test.bucket-name')
my_bucket.objects.limit(50).each do |obj|
puts " #{obj.key} => #{obj.etag}"
end
But the request is trying to hit this url endpoint(virtual hosting):
http://test.bucket-name.10.0.23.45:8081
I would like to use path style addressing instead. This is what I want the request url endpoint to look like:
http://10.0.23.45:8081/test.bucket-name/
Any idea how to set path style addressing instead of virtual hosting address? Thanks.
I found the answer for my own question after looking at the source code of ruby aws-sdk Source Code
Aws.config[:s3] = { force_path_style: true }
Adding the above line forced to use path style addressing.
You need to set option :virtual_host to true according to documentation.
So in your case something like this should work:
s3.bucket('10.0.23.45:8081').object('test.bucket-name').public_url(virtual_host: true)
#=> "http://10.0.23.45:8081/test.bucket-name/"

Rails 4 assets not being served in production on Windows

I'm currently having the exact same problem as described in this post: Rails not serving assets in production or staging environments.
I am running Rails 4.0.4 in production environment on Windows 7 (so that could easily be the problem, can't use Linux unfortunately). I have run rake assets:clobber to make sure everything is cleaned up and and then RAILS_ENV=production rake assets:precompile and it succeeds without errors or warnings. All the files appear in my public/assets folder and using Windows explorer I can view the text in application.js and application.css, and images display correctly. However when I try to visit localhost:3001/assets/application.js it is blank, same with application.css, and image files come up with an error. I have restarted the server each time after changing settings and precompiling.
When I look at the logs it says the page renders successfully, there are no "No route matches" errors like I have seen in other posts. So the assets are being found, but for some reason they aren't being properly served.
Here is my production.rb:
ABC::Application.configure do
config.cache_classes = true
config.eager_load = true
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
config.action_dispatch.x_sendfile_header = "X-Sendfile"
config.serve_static_assets = true
config.action_mailer.default_url_options = { :host => '' }
config.i18n.fallbacks = true
config.active_support.deprecation = :notify
config.assets.js_compressor = :uglifier
config.assets.css_compressor = :sass
config.assets.compile = false
config.assets.digest = true
end
Any help would be much appreciated, I've been stuck on this for nearly two days!
Just as I finished typing up this question, I finally came across another post which said the headers were being set but there was no body, which sounded like my problem. They were using nginx and fixed the problem by changing the following:
# Specifies the header that your server uses for sending files
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
And seeing as I'm not using either Apache or nginx, I commented out both lines and finally my assets were served. Seems obvious in hindsight but I thought I would post this anyway in case it helps anyone else having the same problem.

Fog not uploading entire file to S3

I'm using a ruby script to generate an html page that I'm uploading to s3. My amazon bucket is configured to work as a static website, and the html page my script is generating is the index page.
I've created a couple of models to build a connection to s3 using the fog gem, generate the html page, and then push it up to s3.
When I use the script to push the file up to s3, I don't get any errors, but only half the file gets uploaded. It happens regardless of file size. I inevitably wind up with about 15 rows missing from the html table I generated.
The relevant code from my FogManager model is this:
def connect
#connection = Fog::Storage.new({
provider: 'AWS',
aws_access_key_id: AWS_ACCESS_KEY,
aws_secret_access_key: AWS_SECRET_KEY,
persistent: true
})
end
def locate_directory
#directory = #connection.directories.get(DIRECTORY)
end
def upload_report_page(index_file)
file = #directory.files.get(index_file)
file.body = File.open(index_file)
file.acl = 'public-read'
file.save
end
My script looks something like:
filename = "index.html"
s3 = FogManager.new
s3.connect
s3.locate_directory
# code for generating the html page
s3.upload_report_page(filename)
All of the code works, but the whole html file isn't getting uploaded to s3.
I'm using the latest version of fog (1.15.0) with ruby 2.0.0p0
I've been able to manually go into irb and establish an s3 connection, locate the file, and upload the new one. I use these commands:
require 'fog'
connection = Fog:Storage({provider: 'AWS',
aws_access_key_id: 'xxx',
aws_secret_access_key: 'xxx',
persistent: true})
directory = connection.directories.get('my_directory')
file = directory.files.get('index.html')
file.body = File.open('index.html')
file.acl = 'public-read'
file.save
When I upload the file this way, it works properly, and the whole file gets uploaded, but it defeats the purpose of having the script.
Any insight would be greatly appreciated!

Assets of LocomotiveCMS App

I have hosted a LocomotiveCMS app on Heroku. I've thereafter been working directly on the Heroku MongoHQ database, and have completed the wesbite.
I've then set the development database on my local machine to connect to the MongoHQ database used by the HerokuApp, so the local machine uses the actual data that's on the web. But the assets (CSS and JS files ) donot get accessed properly. Even though I've set up AWS Credentials.
So, when I access the CSSS+JS files on my local machine, I get the files, but with no content, i.e. blank file. I also dont get the AWS links for the assets, as I was seeing on the Heroku server.
Is it something to do with asset precompilation. I have set up the Heroku exactly as described here: http://doc.locomotivecms.com/guides/hosting/heroku-hosting
The production.rb file is as follows:
Testapp::Application.configure do
# Settings specified here will take precedence over those in config/application.rb
# Code is not reloaded between requests
config.cache_classes = true
# Full error reports are disabled and caching is turned on
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Disable Rails's static asset server (Apache or nginx will already do this)
config.serve_static_assets = false
# Compress JavaScripts and CSS
config.assets.compress = true
# Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = false
# Generate digests for assets URLs
config.assets.digest = true
# Defaults to nil and saved in location specified by config.assets.prefix
# config.assets.manifest = YOUR_PATH
# Specifies the header that your server uses for sending files
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
# See everything in the log (default is :info)
# config.log_level = :debug
# Prepend all log lines with the following tags
# config.log_tags = [ :subdomain, :uuid ]
# Use a different logger for distributed setups
# config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
# Use a different cache store in production
# config.cache_store = :mem_cache_store
# Enable serving of images, stylesheets, and JavaScripts from an asset server
# config.action_controller.asset_host = "http://assets.example.com"
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
# config.assets.precompile += %w( search.js )
# Disable delivery errors, bad email addresses will be ignored
# config.action_mailer.raise_delivery_errors = false
# Enable threaded mode
# config.threadsafe!
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation can not be found)
config.i18n.fallbacks = true
# Send deprecation notices to registered listeners
config.active_support.deprecation = :notify
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => 'smtp.sendgrid.net',
:port => 25,
:authentication => :plain,
:user_name => ENV['SENDGRID_USERNAME'],
:password => ENV['SENDGRID_PASSWORD'],
:domain => ENV['SENDGRID_DOMAIN']
}
end
Run this in your console
bundle exec rake assets:precompile
then push to git, then to heroku
I understand why you have set the following to config.assets.initialize_on_precompile = false this makes your application run faster. However the ruby on rails guides states the following:
If you set config.assets.initialize_on_precompile to false, be sure to test rake assets:precompile locally before deploying. It may expose bugs where your assets reference application objects or methods, since those are still in scope in development mode regardless of the value of this flag.
So potentially this could be the route of your problem. Also if you want to include additional css and js you can add the following into the precompile array like so:
config.assets.precompile += ['admin.js', 'admin.css']
See following link for additional reading:
Precompiling assets
Hope this helps

no route matches for assets/images in Rails

Working on rails, images are not visible and giving error.
Started GET "/assets/home.png" for 127.0.0.1 at 2012-06-19 12:23:24 +0530
Served asset /home.png - 404 Not Found (24ms)
ActionController::RoutingError (No route matches [GET] "/assets/home.png"):
I have used command
rake assets:precompile
production.rb
config.assets.compress = true
config.assets.compile = false
application.rb
config.assets.enabled = true
config.assets.version = '1.0'
Thanks for any help!
Actually you cannot reference your image with /assets/home.png path.
It will work in development mode, but in production all of your assets have a fingerprint in their filename (read this http://guides.rubyonrails.org/asset_pipeline.html#what-is-fingerprinting-and-why-should-i-care-questionmark)
That's why, in assets-pipeline enabled applications you need to reference all of your assets using helper methods. Read this doc to learn about the different helpers available in Ruby, JS and Sass files: http://guides.rubyonrails.org/asset_pipeline.html#coding-links-to-assets
The lack of a fingerprint in the file request suggests that you are running this in development. I am also going to guess that this is an app upgraded from an older version of Rails.
Any images need to be in the folder /assets/images for the pipeline to work.
Also, you do not need to precompile when in development mode.
Delete the public/assets folder, delete the folder tmp/cache/assets, and restart your server.
If this images are in the correct location, it should work.

Resources