-
Notifications
You must be signed in to change notification settings - Fork 12
/
deploying-harmonia-with-recap.html
120 lines (98 loc) · 8.54 KB
/
deploying-harmonia-with-recap.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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
<meta name="viewport" content="width=device-width, minimum-scale=1.0" />
<link rel="stylesheet" href="/css/style-b3fa15dce221ff2373344e23bec3febe.css" type="text/css" />
<link rel="alternate" type="application/atom+xml" href="http://tomafro.net/atom.xml" />
<link rel="canonical" href="http://tomafro.net/2012/12/deploying-harmonia-with-recap"/>
<script type="text/javascript" src="http://use.typekit.com/brv6igt.js"></script>
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
<title>Deploying a rails app from scratch using recap · tomafro.net</title>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-1103395-2']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script');
ga.src = ('https:' == document.location.protocol ? 'https://ssl' :
'http://www') + '.google-analytics.com/ga.js';
ga.setAttribute('async', 'true');
document.documentElement.firstChild.appendChild(ga);
})();
</script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<nav>
<ul>
<li><a href='/'>tomafro.net</a><span class='byline'> – a blog by Tom Ward</span></li>
<li><a href='/about'>about</a></li>
<li><a href='https://github.com/tomafro'>github</a></li>
<li><a href='https://twitter.com/tomafro'>twitter</a></li>
</ul>
</nav>
<article>
<header>
<h1><a href="/2012/12/deploying-harmonia-with-recap">Deploying a rails app from scratch using recap</a></h1>
</header>
<div class="content">
<p>If you follow <a href="http://gofreerange.com/blog">our company blog</a> you’ll know that we’re working on <a href="http://harmonia.io">Harmonia</a>, our virtual office manager. I thought I’d explain how we use <a href="https://github.com/freerange/recap">recap</a> to deploy harmonia, to show how easy and fast <a href="https://github.com/freerange/recap">recap</a> makes application deployment.</p>
<p><a href="https://harmonia.io">Harmonia</a> is a fairly standard rails application. As well as a web front-end, it has two other processes. A queue <code>worker</code> is used to send outgoing emails, whilst the core of the application is the <code>ticker</code>; a process which ‘ticks’ every minute, assigning tasks to team members. We use <a href="https://github.com/ddollar/foreman">foreman</a> to declare these processes in the following <code>Procfile</code>:</p>
<div class="highlight"><pre>web: bundle <span class="nb">exec </span>unicorn -p <span class="nv">$PORT</span> -c unicorn.conf.rb
ticker: bundle <span class="nb">exec </span>rails runner script/ticker.rb
worker: bundle <span class="nb">exec </span>rake environment resque:work <span class="nv">QUEUE</span><span class="o">=</span>assignments <span class="nv">VVERBOSE</span><span class="o">=</span>1
</pre>
</div>
<p>All of these processes touch application code, so whenever we deploy a new version of the app (which we do frequently) they need to be restarted. Our app also has a database with associated migrations, uses environment variables like <code>DATABASE_URL</code> for configuration, and has a number of gem dependencies managed by bundler.</p>
<p>This is all handled by <a href="https://github.com/freerange/recap">recap</a>.</p>
<h2>Getting started – adding recap to the project</h2>
<p>Using recap with a rails project is simple. First add <code>gem 'recap'</code> to the <code>Gemfile</code> and run <code>bundle install</code>. Next run <code>bundle exec recap setup</code>, which will generate a <code>Capfile</code>, guessing values for the git repository and app name. You should check these values and change the server to point to your app server. As an example, the complete <code>Capfile</code> for harmonia is shown below:</p>
<div class="highlight"><pre><span class="nb">require</span> <span class="s1">'recap/recipes/rails'</span>
<span class="n">set</span> <span class="ss">:application</span><span class="p">,</span> <span class="s1">'harmonia'</span>
<span class="n">set</span> <span class="ss">:repository</span><span class="p">,</span> <span class="s1">'git@github.com:freerange/harmonia.git'</span>
<span class="n">server</span> <span class="s1">'bison.harmonia.io'</span><span class="p">,</span> <span class="ss">:app</span>
</pre>
</div>
<p>Applications deployed with <a href="https://github.com/freerange/recap">recap</a> need their own user, owning all files and processes. Assuming we can <code>ssh</code> into our server and are listed as a <code>sudoer</code>, we can create this user automatically running <code>cap bootstrap</code>. This will also add our own <code>ssh</code> user to the application group, allowing it to deploy the application.</p>
<p>Next we can set any environment variables we need for configuration. These are loaded in the application user’s <code>.profile</code>, so are available to all processes started by <a href="https://github.com/freerange/recap">recap</a>. In harmonia we set our smtp credentials, the server port, some api keys and more, using commands like <code>cap env:set PORT=7000</code> and <code>cap env:set SMTP_PASSWORD=secret</code>.</p>
<p>The app is now almost ready to deploy. We can prepare it for deployment with <code>cap deploy:setup</code>, which clones the code repository, installs our gem bundle, sets up the database and precompiles our assets.</p>
<p>Finally, running <code>cap deploy</code> will start the app for the first time, launching each process defined in the <code>Procfile</code> with the environment variables we previously set.</p>
<h2>Really fast deployments</h2>
<p>While <a href="https://github.com/freerange/recap">recap</a> makes it very easy to get apps up and running the first time, it comes into its doing subsequent deployments. At <a href="http://gofreerange.com">Go Free Range</a> we like to deploy apps we’re working on very frequently. One thing that helps ensure we do this is making each deployment as fast as it can be.</p>
<p>Using <code>git</code> as recap does is already a very quick way to get code changes onto servers, but recap takes things a step further. By testing to see which files have changed it knows which tasks can be skipped. For example, database migrations won’t be run if <code>db/schema.rb</code> has not changed; the gem bundle won’t be re-installed unless <code>Gemfile.lock</code> has been updated, and foreman process scripts won’t be exported if the <code>Procfile</code> is unchanged. In fact, if these files don’t exist, these tasks will never run at all.</p>
<h2>The future</h2>
<p>Using <a href="https://github.com/freerange/recap">recap</a> with <a href="https://harmonia.io">Harmonia</a> has made our deployment process very fast and simple. When the main harmonia server became over-burdened and we decided to commission a new machine dedicated to harmonia, recap made that process quick and painless. As well as harmonia, recap is also used to deploy <a href="http://gofreerange.com">the Go Free Range website</a>, <a href="http://tomafro.net">this blog</a>, and a number of other small sites and projects where it has proven itself well. For larger projects, there are some features (such as more control as to what processes run where) that are missing, but I plan to add these in the next release. For all other sites, recap has proven itself a lightweight and capable alternative to the standard Capistrano deployment recipes.</p>
</div>
<footer>
<span class='author'><a rel='author' href='http://tomafro.net'>Tom Ward</a></span>
<span class='date'><a href="/2012/12">27th December 2012</a></span>
<ul>
<li><a href="/tags/recap" rel="tag">recap</a></li>
<li><a href="/tags/harmonia" rel="tag">harmonia</a></li>
<li><a href="/tags/deployment" rel="tag">deployment</a></li>
</ul>
</footer>
</article>
<section class="related-links">
<h1>Related posts:</h1>
<ul>
<li>
<a class='title' href="/2012/11/past-present-future">Past, Present and Future</a>
<div class='meta'>
<span class='date'><a href="/2012/11">16th November 2012</a></span>
<ul class='tags'>
<li><a href="/tags/gds" rel="tag">gds</a></li>
<li><a href="/tags/government" rel="tag">government</a></li>
<li><a href="/tags/freerange" rel="tag">freerange</a></li>
<li><a href="/tags/harmonia" rel="tag">harmonia</a></li>
</ul>
</div>
</li>
</ul>
</section>
</body>
</html>