Thom Nichols

Thom

Technology is evolution outside the gene pool

Deploying Octopress on Amazon S3

So a number of folks have described how to use Octopress with S3.  However most of them don't describe how to easily publish to S3, or require an external command-line tool to upload the generate files.  I solved this by using the aws/s3 gem and creating a new rake task. 

rake deploy_s3[blog]  # deploys all blog files

I also added a task to ping Google and Bing when the sitemap updates:

rake ping # tells Google & Bing to crawl updated sitemaps

You can see the full code here.

# Add this w/ your other imports:
begin
 require 'aws/s3'
 require 'yaml'
rescue
 puts "No S3 upload support!"
end

# and in your config section...
s3_config_file = "amazon_s3.yml" # location of file with S3 access key, private key, bucket name

# Use deploy_s3[.*html] to upload only HTML files since the timestamp matching 
# doesn't really work well. Most files get re-generated even if they haven't 
# changed.
desc "Deploy blog to Amazon S3"
task :deploy_s3, :file_match do |t, args|
 # follow these instructions to setup your bucket: 
 # http://docs.amazonwebservices.com/AmazonS3/latest/dev/WebsiteHosting.html 
 # Note that `s3_config_file` should be set at the top of yer rakefile
 args.with_defaults :file_match => '.*'

 begin
  config = YAML.load File.open( s3_config_file )
  AWS::S3::Base.establish_connection!(
   :access_key_id => config['access_key'],
   :secret_access_key => config['secret_key']
  )
 rescue
  puts "Please verify your AWS credentials in '#{s3_config_file}'"
  return
 end
 
 bucket_name = config['bucket_name']
 bucket = AWS::S3::Bucket.find bucket_name

 Dir.glob("#{public_dir}/**/*") do |f|

  next if File.directory? f
  f_name = f[public_dir.length+1..-1]
  next unless f_name.match( args.file_match ) != nil

  # compare atime for each file, only sync changes
  local_modified = Time.at( File.stat( f ).mtime ).to_datetime
  existing = bucket[f_name]

  unless existing and local_modified < DateTime.parse( existing.about['last-modified'] )
   puts "Pushing #{f_name} to #{bucket_name}..." 
   AWS::S3::S3Object.store f_name, File.new(f,'r'), bucket_name
  end
 end
end


desc 'Notify Google & Bing of the new sitemap'
task :ping do
 config = YAML.load File.open config_yaml
 sitemap_url = URI.escape "#{config['url']}#{config['root']}sitemap.xml"
 puts "* Pinging Google sitemap... #{sitemap_url}"
 resp = Net::HTTP.get_response 'www.google.com', "/webmasters/tools/ping?sitemap=#{sitemap_url}"
 puts "Error! #{resp.code} : #{resp.message}" if resp.code.to_i != 200
 puts '* Pinging Bing sitemap...'
 resp = Net::HTTP.get_response 'www.bing.com',  "/webmaster/ping.aspx?siteMap=#{sitemap_url}"
 puts "Error! #{resp.code} : #{resp.message}" if resp.code.to_i != 200
 puts '... Done.'
end

Category: AWS Ruby