This repository has been archived by the owner on May 1, 2020. It is now read-only.
/
heroku.html
256 lines (189 loc) · 17.1 KB
/
heroku.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
<!DOCTYPE html>
<html lang="en">
<head>
<title>pydanny - heroku</title>
<meta charset="utf-8" />
<link rel="stylesheet" href=".././theme/css/main.css" type="text/css" />
<link href=".././feeds/all.atom.xml" type="application/atom+xml" rel="alternate" title="pydanny ATOM Feed" />
<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
<!--[if lte IE 7]>
<link rel="stylesheet" type="text/css" media="all" href=".././css/ie.css"/>
<script src=".././js/IE8.js" type="text/javascript"></script><![endif]-->
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" media="all" href=".././css/ie6.css"/><![endif]-->
</head>
<body id="index" class="home">
<a href="https://github.com/pydanny/pydanny.github.com">
<img style="position: absolute; top: 0; right: 0; border: 0;" src="http://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png" alt="Fork me on GitHub" />
</a>
<header id="banner" class="body">
<h1><a href="../.">pydanny </a></h1>
<nav><ul>
<li><a href=".././pages/about.html">About</a></li>
<li><a href=".././pages/tools.html">Tools</a></li>
<li><a href=".././pages/upcoming.html">Upcoming</a></li>
<li ><a href=".././category/audrey.html">audrey</a></li>
<li ><a href=".././category/blog.html">blog</a></li>
<li ><a href=".././category/django.html">django</a></li>
<li ><a href=".././category/python.html">python</a></li>
</ul></nav>
</header><!-- /#banner -->
<aside id="featured" class="body">
<article>
<h1 class="entry-title"><a href=".././you-should-heroku.html">You should Heroku</a></h1>
<footer class="post-info">
<abbr class="published" title="2012-02-28T12:45:00">
Tue 28 February 2012
</abbr>
<address class="vcard author">
By <a class="url fn" href="#">Daniel Greenfeld</a>
</address>
<p>In <a href=".././category/python.html">python</a>. </p>
<p>tags: <a href=".././tag/python.html">python</a><a href=".././tag/django.html">django</a><a href=".././tag/heroku.html">heroku</a><a href=".././tag/consumernotebook.html">consumernotebook</a><a href=".././tag/mongodb.html">mongodb</a></p>
</footer><!-- /.post-info --><p>In mid-November me and my fiancee, <a class="reference external" href="http://audreymroy.com">Audrey Roy</a> began our startup. We had been frustrated with trying to do on-line product research and came up with an idea to take the lessons learned from <a class="reference external" href="http://djangopackages.com">Django Packages</a> / <a class="reference external" href="http://opencomparison.org">Open Comparison</a> and apply them to a commercial effort. The result has been <a class="reference external" href="http://consumernotebook.com">Consumer Notebook</a>, and it's been a steadily growing success.</p>
<p>We've been bootstrapping the project. That means supporting it with consulting and grinding away on it during our free time. That means 12-16 hour days of Python, Django, and Javascript coding, marketing, system administration, graphic design, communicating with users and vendors, and a thousand other tasks. Since we've had to explore new techniques for making things work on the backend and front end, that means we've needed to have a robust system that is trivial to deploy and certain to never go down. Which, of course, requires serious sys admin skills.</p>
<div class="section" id="the-big-problem">
<h2>The Big Problem</h2>
<blockquote class="pull-quote">
<strong>I hate system administration work.</strong></blockquote>
<p>Sys admin is boring. I find it tedious and dull. Devops doesn't make it easier/faster, it just makes it possible to do it at a large scale.</p>
<p>Fortunately for me, my fiancee likes the sys admin side of things. However, she's got serious programming skills in Python/Javascript, understands CSS, is an excellent illustrator, and has good business skills to boot. Which means <strong>I needed Audrey not to be doing sys admin</strong>.</p>
</div>
<div class="section" id="solution-platform-as-a-service">
<h2>Solution: Platform as a Service</h2>
<p>Platform as a Service, or <a class="reference external" href="http://en.wikipedia.org/wiki/PaaS">PaaS</a>, is where someone else does the majority of work involved in system administration. There are now <a class="reference external" href="http://www.quora.com/What-is-the-Heroku-equivalent-for-Django-applications-Edit-Question-not-relevant-anymore-as-Heroku-now-supports-Django">dozens of companies edging into the Python capable PaaS space</a>. We've been leery of using any of them but finally settled on <a class="reference external" href="http://heroku.com">Heroku</a> after a long period of evaluation.</p>
</div>
<div class="section" id="why-heroku">
<h2>Why Heroku?</h2>
<p>We choose Heroku for a number of reasons:</p>
<ol class="arabic simple">
<li>We competed in a Los Angeles area Hacking contest with <a class="reference external" href="http://rdegges.com/">Randall Degges</a>. He was responsible for the sys admin and went with Heroku. He got it up and it was out of the way for the competition. He spent his time coding, adding features, and fixing templates instead of tweaking knobs on something in the cloud. We saw other people not deliver products at the contest because of this issue.</li>
<li>Heroku doesn't lock you in. If I wanted to, I could take all the pieces out in about 10 minutes, then go old school and host it myself on my own closet server.</li>
<li>Heroku has very good <a class="reference external" href="http://devcenter.heroku.com/categories/heroku-postgres">PostgreSQL</a> support. Our web framework is <a class="reference external" href="http://djangoproject.com">Django</a>, which has an ORM that works best with PostgreSQL.</li>
<li>Heroku has staff. At least seventy of them. Odds are they would have people around 24/7 to deal with issues.</li>
<li>The add-on system means they've got many other people adding great new features. Want <a class="reference external" href="https://addons.heroku.com/mongolab">MongoDB</a>? No problem! How about something to <a class="reference external" href="https://addons.heroku.com/pandastream">handle video</a>? You got it!</li>
<li>Heroku scales up trivially. If we get an upswell of users, I just type <tt class="docutils literal">heroku ps:scale web=50</tt> and I've got 50 web server things handling the load.</li>
<li>When I think of Heroku I think of Puffer Fish. Which is awesome because Puffer Fish are awesome.</li>
</ol>
<a class="reference external image-reference" href="http://www.flickr.com/photos/saspotato/5776592544/"><img alt="http://farm6.staticflickr.com/5303/5776592544_fb15a2902a_m.jpg" class="align-center" id="puffer-fish" src="http://farm6.staticflickr.com/5303/5776592544_fb15a2902a_m.jpg" /></a>
<p>Creative Commons: Some rights reserved by <a class="reference external" href="http://www.flickr.com/photos/saspotato/5776592544/">Saspotato</a></p>
<div class="section" id="things-that-we-really-liked-about-using-heroku">
<h3>Things that we really liked about using Heroku</h3>
<p>As we progressed down the journey of building our site, we discovered even more nice features about Heroku. Here are some of the things that really make me smile:</p>
<ol class="arabic simple">
<li><a class="reference external" href="http://devcenter.heroku.com/articles/releases">Releases</a> and especially <a class="reference external" href="http://devcenter.heroku.com/articles/releases#rollback">rollbacks</a> means we deploy with a lot more confidence.</li>
<li><a class="reference external" href="http://devcenter.heroku.com/articles/logging">Logging</a> and other diagnostic add-ons like <a class="reference external" href="https://addons.heroku.com/sentry">Sentry</a> and <a class="reference external" href="https://addons.heroku.com/newrelic">New Relic</a> means we know what's going on.</li>
<li>During one huge data migration effort I scaled up the workers so a 6 hour task became a 5 minute task. Cost was less then 10 cents for workers instead of me losing hours of labor.</li>
<li>In case we go viral, we don't have to worry about load balancers and all that high performance stuff.</li>
</ol>
</div>
</div>
<div class="section" id="what-does-that-mean">
<h2>What does that mean?</h2>
<p>It means I'm doing the deployments. I'm the sys admin. And I'm happy with my role because it takes minutes out of my day. Me and Audrey team up on everything else and the results so far have been great. If you've ever worked with me, the fact that <a class="reference external" href="http://consumernotebook.com">Consumer Notebook</a> is administered and deployed by me is going to be a shock.</p>
<p>We've been able to really focus on development of the project. And when I mean development, I mean a lot of things. I mean:</p>
<ul class="simple">
<li>Python</li>
<li>Django</li>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
<li>Data Modeling</li>
<li><a class="reference external" href="http://api.consumernotebook.com/">Documenting the API</a></li>
<li>Marketing: <a class="reference external" href="http://insidertips.consumernotebook.com/">blogging on Consumer Notebook</a>, <a class="reference external" href="https://twitter.com/consumernotebk">Tweeting</a>, and working with other groups</li>
<li>Trying out <a class="reference external" href="https://github.com/consumernotebook/tickets/issues">public tickets</a></li>
<li>Iterating through the user experience by communicating to users</li>
<li>All the boring legal and business stuff</li>
</ul>
<p>What you don't see is anything about sys admin issues. That's because what could have been a huge sink in time and resources is pretty much gone. We deploy staging servers with a bit of code I copy/pasted from a bash history into a Fabric script:</p>
<div class="highlight"><pre><span class="kn">from</span> <span class="nn">fabric.api</span> <span class="kn">import</span> <span class="n">local</span>
<span class="n">commands</span> <span class="o">=</span> <span class="s">"""</span>
<span class="s">heroku create --stack cedar</span>
<span class="s">heroku addons:add memcache</span>
<span class="s">heroku config:add S3_KEY=HAHAHAHAHAHA S3_SECRET=NOTGIVINGITOUT</span>
<span class="s">heroku addons:add redistogo</span>
<span class="s">heroku addons:add sendgrid:starter</span>
<span class="s">heroku addons:add mongolab:starter</span>
<span class="s">heroku addons:add sentry:test</span>
<span class="s">heroku addons:add pgbackups</span>
<span class="s">heroku addons:add custom_domains:basic</span>
<span class="s">heroku addons:add zerigo_dns:basic</span>
<span class="s">heroku domains:add staging.consumernotebook.com</span>
<span class="s">heroku addons:add ssl:piggyback</span>
<span class="s">git push heroku master</span>
<span class="s">heroku scale web=1</span>
<span class="s">heroku addons:add heroku-PostgreSQL:ronin</span>
<span class="s">heroku pg:wait</span>
<span class="s">"""</span>
<span class="k">def</span> <span class="nf">build_staging</span><span class="p">():</span>
<span class="k">for</span> <span class="n">command</span> <span class="ow">in</span> <span class="n">commands</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">'</span><span class="se">\n</span><span class="s">'</span><span class="p">):</span>
<span class="n">local</span><span class="p">(</span><span class="n">command</span><span class="p">)</span>
</pre></div>
<p>How awesome is that?</p>
</div>
<div class="section" id="how-much-does-heroku-really-cost">
<h2>How much does Heroku really cost?</h2>
<p>You can do Heroku for free. A lot of people do. More power to them.</p>
<p>But let's face it, beyond a certain point, every PaaS, including Heroku, is going to be more expensive then getting your own EC2, Rackspace, Dreamhost, or Linode hosted server. For a fraction of the cost, you can provision a server, install all the bits, configure the database, http server, load balancers, and even write Chef/Puppet/Fabric scripts so you can do it repeatedly at scale. Cheap!</p>
<p>So why pay more for Heroku? Why not just do it ourselves? For example, right now we're on dedicated PostgreSQL hosting which Heroku charges us $200/month. That's a lot, right?</p>
<blockquote class="pull-quote">
<strong>Wrong.</strong></blockquote>
<p>Right now we're seeing a 50% increase in visits every day. So if we ran our own servers, Chef/Puppet/Fabric or not, odds are we would be spending at least 10 hours a month doing server work. And I can assure you that when we consult that we make more than $20/hour.</p>
<blockquote class="pull-quote">
<strong>$200 < 10 hours of us doing consulting work to bootstrap the project.</strong></blockquote>
<p>Until you hit a certain point, these days the real cost of servers is labor. If you're a developer or small effort, and you think going with a cheap hosting provider is the way to go, think again. Think about the hours you're losing monkeying around with servers and databases instead of getting code done.</p>
<p>Heroku saves us money.</p>
</div>
<div class="section" id="the-takeaway">
<h2>The Takeaway</h2>
<p>One of the problems Django and other Python web frameworks has had is the difficulty of deployment. I can't tell you how many projects I didn't do because of the thought of handling the sys admin side of things. Let's face it, one of the great ongoing successes for PHP is that deploying the majority of sites is trivial.</p>
<p>With the rise of devops we've seen a lot of developers across languages and frameworks dive into <strong>Chef</strong> and <strong>Puppet</strong>. It's been sadly amusing watching people muck around with these great tools to make the deployment of 1-2 servers 'easier', when the real benefit of those tools has been to do things at scale. Things like deployments of fifty servers at once or deployment abstractions for hundreds of people (my fancy talk for PaaS).</p>
<p>In any case, things have changed. Deploying Python web apps is as trivial as deploying PHP code.</p>
<p>For developers I see great times ahead.</p>
<hr class="docutils" />
<p><a class="reference external" href="http://news.ycombinator.com/item?id=3643910">Discuss this post on Hacker News</a></p>
</div>
<p>There are <a href=".././you-should-heroku.html#disqus_thread">comments</a>.</p>
</article>
<p class="paginator">
Page 1 / 1
</p>
</aside><!-- /#featured -->
<section id="extras" class="body">
<div class="social">
<h2>social</h2>
<ul>
<li><a href=".././feeds/all.atom.xml" rel="alternate">atom feed</a></li>
<li><a href="http://twitter.com/pydanny">twitter</a></li>
<li><a href="https://github.com/pydanny">github</a></li>
<li><a href="http://www.facebook.com/daniel.greenfeld">facebook</a></li>
</ul>
</div><!-- /.social -->
</section><!-- /#extras -->
<footer id="contentinfo" class="body">
<address id="about" class="vcard body">
Proudly powered by <a href="http://alexis.notmyidea.org/pelican/">pelican</a>, which takes great advantages of <a href="http://python.org">python</a>.
</address><!-- /#about -->
<p>The theme is by <a href="http://smashingmagazine.com">Smashing Magazine</a>, thanks!</p>
</footer><!-- /#contentinfo -->
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-18066389-3");
pageTracker._trackPageview();
} catch(err) {}</script>
<script type="text/javascript">
var disqus_shortname = 'pydanny';
(function () {
var s = document.createElement('script'); s.async = true;
s.type = 'text/javascript';
s.src = 'http://' + disqus_shortname + '.disqus.com/count.js';
(document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);
}());
</script>
</body>
</html>