a scalable rails app deployed in 60 seconds
DESCRIPTION
I gave this talk at Lone Star Ruby Conference in Austin on 8/28/2010.TRANSCRIPT
![Page 1: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/1.jpg)
A Scalable Rails app Deployed in 60
secondsA love affair with Rails & Heroku.
1
![Page 2: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/2.jpg)
Ben Scheirman
• Director of Development at ChaiONE
• Microsoft MVP, ASP Insider
• Certified ScrumMaster
• Former .NET Ninja, now Rails/iPhone aficionado
2
![Page 3: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/3.jpg)
Ben Scheirman
• ...not affiliated with Heroku
3
![Page 4: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/4.jpg)
So you have a fantastic app?
4
![Page 5: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/5.jpg)
Now deploy it...
5
![Page 6: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/6.jpg)
Shared HostingVirtual Dedicated
Dedicated6
![Page 7: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/7.jpg)
Shared Hosting
7
![Page 8: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/8.jpg)
Shared Hosting
7
![Page 9: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/9.jpg)
Shared Hosting
7
![Page 10: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/10.jpg)
Shared Hosting
7
![Page 11: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/11.jpg)
Shared Hosting
7
![Page 12: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/12.jpg)
Shared Hosting
7
![Page 13: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/13.jpg)
Virtual Dedicated
8
![Page 14: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/14.jpg)
Virtual Dedicated
8
![Page 15: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/15.jpg)
Dedicated
9
![Page 16: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/16.jpg)
Scale
10
![Page 17: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/17.jpg)
11
![Page 18: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/18.jpg)
x 1,000?11
![Page 19: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/19.jpg)
12
![Page 20: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/20.jpg)
x 10,000?12
![Page 21: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/21.jpg)
writes
reads
13
![Page 22: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/22.jpg)
x 1,000,000?
writes
reads
13
![Page 23: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/23.jpg)
14
![Page 24: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/24.jpg)
ScaleOn-Demand
15
![Page 25: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/25.jpg)
0
100
200
300
400
12 AM 3AM 6AM 9AM 12PM 3PM 6PM 9PM 12AM
# Users by time of day
16
![Page 26: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/26.jpg)
0
100
200
300
400
12 AM 3AM 6AM 9AM 12PM 3PM 6PM 9PM 12AM
# Users by time of day
16
![Page 27: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/27.jpg)
0
100
200
300
400
12 AM 3AM 6AM 9AM 12PM 3PM 6PM 9PM 12AM
# Users by time of day
Only need massive scale from 9am - 9pm
16
![Page 28: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/28.jpg)
0
225
450
675
900
Mar 1 Mar 15 Apr 1 Apr 15 May 1 May 15 Jun 1 Jun 2
Expected Users For PR Campaign
17
![Page 29: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/29.jpg)
0
225
450
675
900
Mar 1 Mar 15 Apr 1 Apr 15 May 1 May 15 Jun 1 Jun 2
Expected Users For PR Campaign
17
![Page 30: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/30.jpg)
Wouldn’t this be magical?
SCALE
18
![Page 31: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/31.jpg)
Forget about servers19
![Page 32: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/32.jpg)
Awesome Shredder Art by Dan Barret
20
![Page 33: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/33.jpg)
Awesome Shredder Art by Dan Barret
gem install heroku
20
![Page 34: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/34.jpg)
• Platform as a service for Rack-based apps
• Scale easily
•Great workflow
• Free to start / Friendly Pricing
• Complete command-line API
21
![Page 35: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/35.jpg)
git initgit add .git commit -m “My First Commit”heroku creategit push heroku master
Deploy a rails app in 5 steps
Creating morning-summer-18..... doneCreated http://morning-summer-18.heroku.com/ | [email protected]:morning-summer-18.git
22
![Page 36: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/36.jpg)
git initgit add .git commit -m “My First Commit”heroku creategit push heroku master
Deploy a rails app in 5 steps
LET THAT SOAK IN...
Creating morning-summer-18..... doneCreated http://morning-summer-18.heroku.com/ | [email protected]:morning-summer-18.git
22
![Page 37: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/37.jpg)
Using git for deployment is f***ing GENIUS
23
![Page 38: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/38.jpg)
• Amazon Web Services
• Caching w/ Varnish
• Debian Linux
• Erlang Routing Mesh
• Nginx
• PostgreSQL
Technology
24
![Page 39: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/39.jpg)
25
![Page 40: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/40.jpg)
How Heroku Scales
26
![Page 41: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/41.jpg)
How Heroku Scalesor WTF is a Dyno?
26
![Page 42: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/42.jpg)
How Heroku Scalesor WTF is a Dyno?
26
![Page 43: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/43.jpg)
How Heroku Scalesor WTF is a Dyno?
26
![Page 44: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/44.jpg)
How Heroku Scales
27
![Page 45: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/45.jpg)
How Heroku Scales
27
![Page 46: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/46.jpg)
How Heroku Scales
27
![Page 47: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/47.jpg)
• Increasing response times
• “Backlog Too Deep” Error
When to add dynos
28
![Page 48: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/48.jpg)
• New Relic RPM
• Apache Bench
Always Measure
29
![Page 49: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/49.jpg)
• Multiple Heroku apps for Test, Staging, Production
• Learn the awesome-ness of Taps
• Heroku logs
• Heroku Console
• Useful addons: New Relic, Exceptional
Heroku Tips
30
![Page 50: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/50.jpg)
Backups
31
![Page 51: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/51.jpg)
Coping with the Free Single Bundle task :backup do bundle_name = "my-backup" heroku_app = ENV['app'] def wait_for_response_text(text) heroku_app = ENV['app'] #lame, I know begin puts "." bundles = `heroku bundles --app #{heroku_app}` end while bundles.match(text).nil? end #check for existing bundle bundles = `heroku bundles --app #{heroku_app}` unless bundles.match /has no bundles/ `heroku bundles:destroy #{bundle_name} --app #{heroku_app}` wait_for_response_text 'has no bundles' end puts "Capture bundle #{bundle_name}..." `heroku bundles:capture #{bundle_name} --app #{heroku_app}` wait_for_response_text "complete" puts "Downloading bundle..." `heroku bundles:download #{bundle_name} --app #{heroku_app}` timestamp = `date -u '+%Y-%m-%d-%H-%M'`.chomp new_path = "backups/#{heroku_app}-#{timestamp}.tar.gz" mkdir "backups" unless File.exists? "backups" `mv #{heroku_app}.tar.gz #{new_path}` puts "Bundle saved to #{new_path}" end end
32
![Page 52: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/52.jpg)
Coping with the Free Single Bundle task :backup do bundle_name = "my-backup" heroku_app = ENV['app'] def wait_for_response_text(text) heroku_app = ENV['app'] #lame, I know begin puts "." bundles = `heroku bundles --app #{heroku_app}` end while bundles.match(text).nil? end #check for existing bundle bundles = `heroku bundles --app #{heroku_app}` unless bundles.match /has no bundles/ `heroku bundles:destroy #{bundle_name} --app #{heroku_app}` wait_for_response_text 'has no bundles' end puts "Capture bundle #{bundle_name}..." `heroku bundles:capture #{bundle_name} --app #{heroku_app}` wait_for_response_text "complete" puts "Downloading bundle..." `heroku bundles:download #{bundle_name} --app #{heroku_app}` timestamp = `date -u '+%Y-%m-%d-%H-%M'`.chomp new_path = "backups/#{heroku_app}-#{timestamp}.tar.gz" mkdir "backups" unless File.exists? "backups" `mv #{heroku_app}.tar.gz #{new_path}` puts "Bundle saved to #{new_path}" end end
33
![Page 53: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/53.jpg)
Coping with the Free Single Bundle task :backup do bundle_name = "my-backup" heroku_app = ENV['app'] def wait_for_response_text(text) heroku_app = ENV['app'] #lame, I know begin puts "." bundles = `heroku bundles --app #{heroku_app}` end while bundles.match(text).nil? end #check for existing bundle bundles = `heroku bundles --app #{heroku_app}` unless bundles.match /has no bundles/ `heroku bundles:destroy #{bundle_name} --app #{heroku_app}` wait_for_response_text 'has no bundles' end puts "Capture bundle #{bundle_name}..." `heroku bundles:capture #{bundle_name} --app #{heroku_app}` wait_for_response_text "complete" puts "Downloading bundle..." `heroku bundles:download #{bundle_name} --app #{heroku_app}` timestamp = `date -u '+%Y-%m-%d-%H-%M'`.chomp new_path = "backups/#{heroku_app}-#{timestamp}.tar.gz" mkdir "backups" unless File.exists? "backups" `mv #{heroku_app}.tar.gz #{new_path}` puts "Bundle saved to #{new_path}" end end
34
![Page 54: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/54.jpg)
Coping with the Free Single Bundle task :backup do bundle_name = "my-backup" heroku_app = ENV['app'] def wait_for_response_text(text) heroku_app = ENV['app'] #lame, I know begin puts "." bundles = `heroku bundles --app #{heroku_app}` end while bundles.match(text).nil? end #check for existing bundle bundles = `heroku bundles --app #{heroku_app}` unless bundles.match /has no bundles/ `heroku bundles:destroy #{bundle_name} --app #{heroku_app}` wait_for_response_text 'has no bundles' end puts "Capture bundle #{bundle_name}..." `heroku bundles:capture #{bundle_name} --app #{heroku_app}` wait_for_response_text "complete" puts "Downloading bundle..." `heroku bundles:download #{bundle_name} --app #{heroku_app}` timestamp = `date -u '+%Y-%m-%d-%H-%M'`.chomp new_path = "backups/#{heroku_app}-#{timestamp}.tar.gz" mkdir "backups" unless File.exists? "backups" `mv #{heroku_app}.tar.gz #{new_path}` puts "Bundle saved to #{new_path}" end end
35
![Page 55: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/55.jpg)
Coping with the Free Single Bundle task :backup do bundle_name = "my-backup" heroku_app = ENV['app'] def wait_for_response_text(text) heroku_app = ENV['app'] #lame, I know begin puts "." bundles = `heroku bundles --app #{heroku_app}` end while bundles.match(text).nil? end #check for existing bundle bundles = `heroku bundles --app #{heroku_app}` unless bundles.match /has no bundles/ `heroku bundles:destroy #{bundle_name} --app #{heroku_app}` wait_for_response_text 'has no bundles' end puts "Capture bundle #{bundle_name}..." `heroku bundles:capture #{bundle_name} --app #{heroku_app}` wait_for_response_text "complete" puts "Downloading bundle..." `heroku bundles:download #{bundle_name} --app #{heroku_app}` timestamp = `date -u '+%Y-%m-%d-%H-%M'`.chomp new_path = "backups/#{heroku_app}-#{timestamp}.tar.gz" mkdir "backups" unless File.exists? "backups" `mv #{heroku_app}.tar.gz #{new_path}` puts "Bundle saved to #{new_path}" end end
36
![Page 56: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/56.jpg)
Coping with the Free Single Bundle task :backup do bundle_name = "my-backup" heroku_app = ENV['app'] def wait_for_response_text(text) heroku_app = ENV['app'] #lame, I know begin puts "." bundles = `heroku bundles --app #{heroku_app}` end while bundles.match(text).nil? end #check for existing bundle bundles = `heroku bundles --app #{heroku_app}` unless bundles.match /has no bundles/ `heroku bundles:destroy #{bundle_name} --app #{heroku_app}` wait_for_response_text 'has no bundles' end puts "Capture bundle #{bundle_name}..." `heroku bundles:capture #{bundle_name} --app #{heroku_app}` wait_for_response_text "complete" puts "Downloading bundle..." `heroku bundles:download #{bundle_name} --app #{heroku_app}` timestamp = `date -u '+%Y-%m-%d-%H-%M'`.chomp new_path = "backups/#{heroku_app}-#{timestamp}.tar.gz" mkdir "backups" unless File.exists? "backups" `mv #{heroku_app}.tar.gz #{new_path}` puts "Bundle saved to #{new_path}" end end
37
![Page 57: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/57.jpg)
Coping with the Free Single Bundle task :backup do bundle_name = "my-backup" heroku_app = ENV['app'] def wait_for_response_text(text) heroku_app = ENV['app'] #lame, I know begin puts "." bundles = `heroku bundles --app #{heroku_app}` end while bundles.match(text).nil? end #check for existing bundle bundles = `heroku bundles --app #{heroku_app}` unless bundles.match /has no bundles/ `heroku bundles:destroy #{bundle_name} --app #{heroku_app}` wait_for_response_text 'has no bundles' end puts "Capture bundle #{bundle_name}..." `heroku bundles:capture #{bundle_name} --app #{heroku_app}` wait_for_response_text "complete" puts "Downloading bundle..." `heroku bundles:download #{bundle_name} --app #{heroku_app}` timestamp = `date -u '+%Y-%m-%d-%H-%M'`.chomp new_path = "backups/#{heroku_app}-#{timestamp}.tar.gz" mkdir "backups" unless File.exists? "backups" `mv #{heroku_app}.tar.gz #{new_path}` puts "Bundle saved to #{new_path}" end end
38
![Page 58: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/58.jpg)
Coping with the Free Single Bundle task :backup do bundle_name = "my-backup" heroku_app = ENV['app'] def wait_for_response_text(text) heroku_app = ENV['app'] #lame, I know begin puts "." bundles = `heroku bundles --app #{heroku_app}` end while bundles.match(text).nil? end #check for existing bundle bundles = `heroku bundles --app #{heroku_app}` unless bundles.match /has no bundles/ `heroku bundles:destroy #{bundle_name} --app #{heroku_app}` wait_for_response_text 'has no bundles' end puts "Capture bundle #{bundle_name}..." `heroku bundles:capture #{bundle_name} --app #{heroku_app}` wait_for_response_text "complete" puts "Downloading bundle..." `heroku bundles:download #{bundle_name} --app #{heroku_app}` timestamp = `date -u '+%Y-%m-%d-%H-%M'`.chomp new_path = "backups/#{heroku_app}-#{timestamp}.tar.gz" mkdir "backups" unless File.exists? "backups" `mv #{heroku_app}.tar.gz #{new_path}` puts "Bundle saved to #{new_path}" end end
39
![Page 59: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/59.jpg)
One-button Deployments task :deploy do heroku_app = ENV['app'] heroku_config = Hash.new Rake::Task["heroku:backup"].invoke puts "Turning maintenance on..." puts "** " + `heroku maintenance:on --app #{heroku_app}` sleep 15 #maintenance mode causes your slug to be recompiled puts "Pushing changes to heroku..." puts "** " + `git push #{git_remotes[heroku_app]} master` puts "Migrating heroku databases..." puts "** " + `heroku rake db:migrate --app #{heroku_app}` puts "Setting up config variables..." heroku_config.each_pair do |k, v| puts "** " + `heroku config:add #{k.to_s.upcase}=#{v}` end puts "Turning maintenance mode off" puts "** " + `heroku maintenance:off --app #{heroku_app}` puts "DEPLOYMENT DONE!" end
40
![Page 60: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/60.jpg)
Delayed Jobs
41
![Page 61: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/61.jpg)
Delayed Jobs
def send_bulk_emails
BulkEmailSender.send_a_tonflash[:notice] => "Ok we sent them"
end
41
![Page 62: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/62.jpg)
Delayed Jobs
def send_bulk_emails
BulkEmailSender.send_a_tonflash[:notice] => "Ok we sent them"
end
def send_bulk_emails
BulkEmailSender.send_later(:send_a_ton)flash[:notice] => "Ok we sent them"
end
41
![Page 63: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/63.jpg)
Delayed Jobs
42
![Page 64: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/64.jpg)
Delayed Jobs
> gem install delayed_job> rails g delayed_job > rake db:migrate
42
![Page 65: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/65.jpg)
Delayed Jobs
> gem install delayed_job> rails g delayed_job > rake db:migrate
> heroku workers 1 simple-snow-68 now running 1 worker
> heroku workers +1 simple-snow-68 now running 2 workers
42
![Page 66: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/66.jpg)
Delayed Jobs
43
![Page 67: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/67.jpg)
Delayed Jobs
$0.05 per hour / worker(even when it's not processing Jobs)
43
![Page 68: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/68.jpg)
Delayed Jobs
$0.05 per hour / worker(even when it's not processing Jobs)
http://github.com/pedro/delayed_job/commit/09d7657e1fc7d25072e6c5e73ede20d6e1185eac
http://bit.ly/9Qokff
43
![Page 69: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/69.jpg)
Delayed JobsPedro's Fork / auto-scale branch
44
![Page 70: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/70.jpg)
Delayed JobsPedro's Fork / auto-scale branch
//lib/delayed/job.rbdef after_createManager.scale_up if self.class.auto_scale && Manager.qty == 0
end
//lib/delayed/worker.rbManager.scale_down if count.zero? && Job.auto_scale && Job.count == 0
44
![Page 71: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/71.jpg)
• Read-only file system
• some gems don’t work
• File uploads?
• Temp Directory
• SSL, memcached, Full-text-search expensive
• Bound-by Amazon’s SLA
Gotchas
45
![Page 72: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/72.jpg)
contact = {
! :blog => http://flux88.com,!! :twitter => @subdigital,!! :email => [email protected]
}
46
![Page 73: A Scalable Rails App Deployed in 60 Seconds](https://reader034.vdocuments.mx/reader034/viewer/2022051323/54b54b604a7959cd6c8b463b/html5/thumbnails/73.jpg)
47