Closed emk closed 8 years ago
I contacted heroku re: COMMIT_HASH and they said it is unsupported at the moment. I would be hesitant to merge these changes into the master at the moment. Another approach is to use RAILS_ASSET_ID env var, which you can set to whatever during the deployment. I implemented this in https://github.com/kmamykin/jammit-s3
That's too bad. Fortunately, nothing in this patch actually relies on Heroku, except for the documentation. Here's how I set up production.rb for use with Capistrano:
# Load our release-specific configuration from release.yml.
RELEASE_INFO =
YAML.load(File.read(File.join(Rails.root, 'config/release.yml')))
# Enable serving of images, stylesheets, and javascripts from an asset server
config.action_controller.asset_host = "dsz6mnjgj82i1.cloudfront.net"
config.action_controller.asset_path = lambda do |asset_path|
"/#{RELEASE_INFO['COMMIT_HASH']}#{asset_path}"
end
And in deploy.rb:
before 'deploy:update_code' do
system 'bundle exec jammit' or raise "Can't compile assets"
system 'bundle exec jammit-s3' or raise "Can't upload assets to S3"
end
after 'deploy:update_code' do
# Save our release ID in a configuration file.
run "echo COMMIT_HASH: #{COMMIT_HASH} > #{File.join(release_path, 'config/release.yml')}"
end
Right now, the master branch of jammit-s3 doesn't really work with CloudFront, because CloudFront invalidation is pretty complicated.
Any thoughts on how I should update this patch? Thank you for your feedback!
Cheers, Eric
Hi Eric, Thank you for submitting the patch. There are a few forks floating around that deal with CloudFront issue, I just need to find some time and merge it all together.
added support here. https://github.com/railsjedi/jammit-s3/commit/3dead946da96d94f33d05ed4e63e40785f8ab4a4 let me know if this approach works for you. thanks!
Thank you for adding more CloudFront support!
Unfortunately, there are a number of problems with relying on CloudFront invalidation:
1) It may reportedly take up to 15 minutes to invalidate all the CloudFront caches around the globe (and Google charges for more than a certain number of invalidations per month). 2) It's non-atomic from the perspective of the end-user: They may get an older version of the site with a newer version of the JavaScript and CSS, or vice versa. 3) It doesn't play nicely with aggressive HTTP caching. For example, once I serve a script or a stylesheet, I would like it to be cached indefinitely with no more round trips to see whether it is valid.
Given these constraints, there's still an important need for some kind of content-based hashing. Done right, this assures that all files can be cached indefinitely, and the user will always get matched HTML/JS/CSS files.
Thank you for your work on Jammit S3!
Cheers, Eric
ah, excellent point. reopened pull request. we should come up with a solid solution to this. i dont use cloudfront at the moment so i'm not intimately familiar with it. i'd be happy to merge in your changes if you think you have a solid solution
I think solution from emk excellent! But better use package_path config option of Jammit:
after 'deploy:update_code' do
run "echo package_path: assets/#{COMMIT_HASH} > #{File.join(release_path, 'config/assets.yml')}"
run 'bundle exec jammit'
run 'bundle exec jammit-s3'
end
On Mon, Apr 11, 2011 at 2:35 PM, railsjedi < reply@reply.github.com>wrote:
ah, excellent point. reopened pull request. we should come up with a solid solution to this. i dont use cloudfront at the moment so i'm not intimately familiar with it. i'd be happy to merge in your changes if you think you have a solid solution
Ideally, it would be nice to do something which Just Worked on Heroku, and other git-based deployment systems. We would need to find some piece of information which uniquely identified a specific version of the program, which could be embedded into a URL, and which we could easily and cheaply retrieve on both the development and the production machines.
The git commit ID is one obvious choice. The SHA1 sum of a given asset file would also work, though it's probably a lot more expensive to compute at runtime on the server, and it makes it harder to clean old junk out of CloudFront.
So I'd love to have some way to use either COMMIT_HASH, or (if that's not really what you want) something similar that I can compute using Ruby code and supply to Jammit S3 at runtime.
Many thanks for jammit-s3!
Cheers, Eric
I make it like this:
desc "Make new jammit assets path based on commit hash"
task :jammit do
run "echo \"package_path: 'assets/#{release_name}'\" >> #{current_path}/config/assets.yml"
run "cd #{current_path}; bundle exec jammit"
run "cd #{current_path}; bundle exec jammit-s3"
end
And run it before "deploy:restart". In release directories cleaning I can remove old asset releases on S3.
In this case I upload new assets and update if needed other static files. We not increase S3 storage data,but send invalidate request on updated files.
So I have an updated version here, which supports both asset invalidation and asset versioning. README updated with the info on how to configure, but basically comes down to one switch: use_cloudfront: invalidate or version. rake jammit:s3:heroku will Just Work (emk tm) on heroku. https://github.com/kmamykin/jammit-s3 I need someone to kick the tires and give a go/nogo for the merge to the jailsjedi repo.
@kmamykin I can't get your branch to work. I keep getting:
Error message:
uninitialized constant Rails::Railtie
Backtrace:
# File Line Location
0 /usr/local/rvm/gems/ruby-1.8.7-p302@rmsr/gems/activesupport-2.3.9/lib/active_support/dependencies.rb 466 in `load_missing_constant'
1 /usr/local/rvm/gems/ruby-1.8.7-p302@rmsr/gems/activesupport-2.3.9/lib/active_support/dependencies.rb 106 in `rake_original_const_missing'
2 /usr/local/rvm/gems/ruby-1.8.7-p302@rmsr/gems/rake-0.9.2.2/lib/rake/ext/module.rb 36 in `const_missing'
3 /usr/local/rvm/gems/ruby-1.8.7-p302@rmsr/bundler/gems/jammit-s3-2a7245027fa5/lib/jammit-s3.rb 12
Does your fork not support Rails 2.3?
I have not tested on rails 2.3, and apparently it does not work. Feel free to submit a separate pull request. I am not actively using jammit-s3 anymore, switched to assets pipeline.
@kmamykin cool thanks. Yeah same here, was just trying to retrofit this onto an old app I didn't feel like updating. I probably might as well upgrade it at this point.
OK, this PR is almost half a decade old, so I'm assuming it's obsolete. :-) Closing it.
Thank you for your excellent gem!
This patch makes it a lot easier to use CloudFront, which is terrible about expiring existing assets, and it does so in a way that should be compatible with Heroku.
Please let me know if you have any questions or if you would like any changes. Thank you!