Skip to content

Instantly share code, notes, and snippets.

@albrow
Last active March 20, 2025 09:04
Show Gist options
  • Save albrow/4385707 to your computer and use it in GitHub Desktop.
Save albrow/4385707 to your computer and use it in GitHub Desktop.
An excerpt from the Rakefile I use to deploy my blog. http://blog.alexbrowne.info
desc "Deploy website to s3/cloudfront via aws-sdk"
task :s3_cloudfront => [:generate, :minify, :gzip, :compress_images] do
puts "=================================================="
puts " Deploying to Amazon S3 & CloudFront"
puts "=================================================="
# setup the aws_deploy_tools object
config = YAML::load( File.open("_config.yml"))
aws_deploy = AWSDeployTools.new(config)
# get all files in the public directory
all_files = Dir.glob("#{$public_dir}/**/*.*")
# we want the gzipped version of the files, not the regular (non-gzipped) version
# excluded files contains all the regular versions, which will not be deployed
excluded_files = []
$gzip_exts.collect do |ext|
excluded_files += Dir.glob("#{$public_dir}/**/*.#{ext}")
end
# we do gzipped files seperately since they have different metadata (:content_encoding => gzip)
puts "--> syncing gzipped files...".yellow
gzipped_files = Dir.glob("#{$public_dir}/**/*.gz")
gzipped_keys = gzipped_files.collect {|f| (f.split("#{$public_dir}/")[1]).sub(".gz", "")}
aws_deploy.sync(gzipped_keys, gzipped_files,
:reduced_redundancy => true,
:cache_control => "max_age=86400", #24 hours
:content_encoding => 'gzip',
:acl => config['acl']
)
puts "--> syncing all other files...".yellow
non_gzipped_files = all_files - gzipped_files - excluded_files
non_gzipped_keys = non_gzipped_files.collect {|f| f.split("#{$public_dir}/")[1]}
aws_deploy.sync(non_gzipped_keys, non_gzipped_files,
:reduced_redundancy => true,
:cache_control => "max_age=86400", #24 hours
:acl => config['acl']
)
# invalidate all the files we just pushed
aws_deploy.invalidate_dirty_keys
puts "DONE."
end
desc "Compress all applicable content in public/ using gzip"
task :gzip do
unless which('gzip')
puts "WARNING: gzip is not installed on your system. Skipping gzip..."
return
end
@compressor ||= RedDragonfly.new
$gzip_exts.each do |ext|
puts "--> gzipping all #{ext}...".yellow
files = Dir.glob("#{$gzip_dir}/**/*.#{ext}")
files.each do |f|
@compressor.gzip(f)
end
end
puts "DONE."
end
desc "Minify all applicable files in public/ using jitify"
task :minify do
unless which('jitify')
puts "WARNING: jitify is not installed on your system. Skipping minification..."
return
end
@compressor ||= RedDragonfly.new
$minify_exts.each do |ext|
puts "--> minifying all #{ext}...".yellow
files = Dir.glob("#{$minify_dir}/**/*.#{ext}")
files.each do |f|
@compressor.minify(f)
end
end
puts "DONE."
end
desc "Compress all images in public/ using ImageMagick"
task :compress_images do
unless which('convert')
puts "WARNING: ImageMagick is not installed on your system. Skipping image compression..."
return
end
@compressor ||= RedDragonfly.new
$compress_img_exts.each do |ext|
puts "--> compressing all #{ext}...".yellow
files = Dir.glob("#{$compress_img_dir}/**/*.#{ext}")
files.each do |f|
@compressor.compress_img(f)
end
end
puts "DONE."
end
@monfresh
Copy link

monfresh commented Jan 8, 2013

Thanks for this, but I wanted to point out an issue I came across:

If you don't specify a :content_type option in aws_deploy.sync, then you could end up with a Content-Type of "image/jpeg" for html files. This means that the sync method needs to have logic that detects what kind of file is being uploaded and add the appropriate Content-Type.

@albrow
Copy link
Author

albrow commented Jan 29, 2013

Good catch. Turns out S3 is setting the content-type for everything to be "image/jpeg." It doesn't seem to break anything, but I'll probably still fix it at some point for the sanity's sake.

@albrow
Copy link
Author

albrow commented Feb 23, 2013

Turns out the content type problem was causing problems on certain versions of IE, plus I can imagine that specifying an incorrect content type might have a performance penalty. I added a few lines to aws_deploy_tools.rb to automatically detect the content type based on the file extension. It uses part of Actionpack, which means you have to add rails to your gemfile.

I've also fixed a problem with cloudfront invalidations. It turns out that they work with paths instead of files. So, e.g., it's necessary to post invalidation requests for both "/index.html" and "/"

@albrow
Copy link
Author

albrow commented Feb 23, 2013

By the way– Anyone interested in seeing some of this converted to a gem?

@nitrogenlogic
Copy link

This would make a useful gem.

I'll note that I had to replace "$public_dir" in the Rakefile excerpt with "public_dir"; otherwise the Dir.glob line tried to scan my entire hard drive since $public_dir is unset.

@dkamioka
Copy link

dkamioka commented Sep 8, 2013

I would really like this into a gem! :)

@macsilber
Copy link

I think there could be an issue with
def compress_img (files = [])
in that $img_options[:output_ext] is being forced to jpg by
$img_options = {
:output_ext => "jpg",
:max_width => "600",
:max_height => "1200",
:quality => "65",
:compress_type => "JPEG"
}

This means png files are being converted to jpg and deleted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment