Building a Todo system with Tracks, Openshift, Postgresql, and Mailgun
Over the last year or so, I’ve been working on my own personal take on Getting Things Done. When I started working from home a little over a year ago, I knew I needed to be productive in the absence of people looking over my shoulder. I also wanted to be better at dealing with the stuff I personally wanted to achieve.
It’s taken a year of tweaking, but I’m going to share with you the system I’ve built, and as you’d expect from me, it’s all open. Let’s get started.
Firstly, lets discuss the technologies involved:
- We’re going to need somewhere to host our new app. You could use your own server, or maybe Heroku, but I’ve chosen to go with Openshift Online.
- We’re going to need a database for our app. We’ll be using Postgresql.
- We’re going to use the awesome todo management app Tracks. This is the cornerstone of the system, since it’s the app that actually stores and displays my Todos.
- We’ll also set up Mailgun integration with Tracks so that we can email Todos to our app (OK, this bit isn’t open source… but it is free-as-in-beer)
Tracks, Postgresql, and Openshift
The first part of our setup involves standing up an empty app on Openshift Online. You’ll want to register for a free account if you don’t already have one, at which point you’ll have access to your three ‘gears’ - these are the 3 free servers you get with a basic account. We only need 1 for this blog, so you can do what you like with the other 2.
You’ll need to choose a ‘domain’ name - it’s not a full domain name, but your
apps will have this in the URL, so keep it sensible :). I’ll assume your domain
user. You’ll also need to add an SSH key - this will be used for Git
access later on, so it’s a good idea to load this key into your SSH keyring.
Once logged in, click
Add Application and select the
Ruby 1.9 cartridge.
This will give us a basic Ruby environment to deploy Rails into. You’ll then
need to provide an app name (I’ll assume you used
app), giving you a URL like
app-user.rhcloud.com. The rest of the defaults are fine, so click
Now we have a server! Make a note of the SSH access and Git repo URL, for
Git - ssh://email@example.com/~/git/test.git/ SSH - firstname.lastname@example.org
( I’ve deliberately lined up the two user IDs you can see they’re the same.)
We now need a database. Fortunately Openshift makes it very easy for us to add
the awesome Postgresql database to our server. Go
to your app control panel in Openshift and click
Add Cartridge. Then select
Postgesql 9.2 cartridge and confirm it with
Add Cartridge. You’ll be given
some credentials, but you don’t need to note them down as the Openshift
environment variables contain the relevant data.
OK, time for something slightly more complex. Tracks is the centrepiece of our system, but we have to work slightly harder than the last two steps to get it set up. First though, let’s get an overview of the situation:
- Openshift gives us a Git repo to push code to.
- Tracks is stored in Git, but needs some small changes to work with Openshift
You can see where this is going, no doubt. Fortunately I’ve made it slightly easier for you by doing some of the work. I’ve made all the necessary changes to Tracks in my Openshift-Quickstart branch for you (as well as a backported Mailgun patch for the section below), based on the 2.2 stable branch of Tracks. But we still need to deal with things like database access, password salts, etc:
First, clone my fork of Tracks from my Github page to your local machine:
$ git clone https://github.com/GregSutcliffe/tracks -b openshift-quickstart <normal git output> $ cd tracks
There are a few variables you need to fill in yourself, such as passwords and such. I’ve marked these for you, so a handy grep will find them:
$ grep openshift config/*yml config/site.yml:salt: "change-me-openshift" config/site.yml:secret_token: "change-me-openshift"
As you can see, you need to set two salts. These can be any
random strings - there are comments in
site.yml as to how to generate
them. For example:
--- a/config/site.yml +++ b/config/site.yml -salt: "change-me-openshift" +salt: "gah0thohluSh" -secret_token: "change-me-openshift" +secret_token: "9dd9d694e4553f583734224631bbbef11001c0315cd47630ae2c4a24c918e0fc"
Once you’ve done that, you should be able to commit your changes:
$ git status # modified: config/site.yml $ git commit -a -m "Local OpenShift changes"
And now we can push the resulting configuration and code up to our Openshift server, using the git repo we made a note of earlier:
$ git remote add openshift ssh://email@example.com/~/git/test.git/ $ git push openshift HEAD:master -f -u remote: Stopping Ruby cartridge remote: Bundling RubyGems based on Gemfile/Gemfile.lock to repo/vendor/bundle with 'bundle install --deployment' remote: Postgres started remote: Precompiling with 'bundle exec rake assets:precompile' remote: Starting Ruby cartridge
This push will take a long time - Openshift will run
rake assets:precompile which are both lengthy tasks. I’ve
included the key lines that indicate things are progressing correctly.
Once complete, we should be able to visit our app at
https://app-user.rhcloud.com. You can create your admin account and
start using Tracks. Awesome!
Before progressing to the Mailgun support below, have a play with the Tracks
interface. I’m a big fan of the
Defer menu next to any Todo, in order to hide
something for a few days. At the very least, create at least one context for
new email Todos to be assigned to. There’s also a handy mobile interface at
If you have any issues, you can log into your Tracks app with the ssh
command from step 1. Some useful commands (run from the
- Database migration:
bundle exec rake db:migrate RAILS_ENV=production
Tracks alone is lovely to work with, but it’s even better to be able to mail Todos to yourself. We don’t need a complex 2-way synchronizing mobile app for our Todos - we just need to be able to use the smartphone’s ability to queue emails when we’re offline.
However, it’s not easy to install a mailserver on Openshift - and even if you could, the effort of maintaining it’s security would be too high. Surely we can do better? Enter Mailgun.
Mailgun is a service (from Rackspace) for converting emails into HTTP requests (and vice versa, although we don’t need that). It’s free for up to 10000 emails a month, which should be more than enough (unless you have an awful lot of Todos :P).
Register for a free account (I chose to use a hosted user.mailgun.com
address), and then head over to the Control Panel. Make a note of the
API key from the
My Account page. Then go to
Routes, and add a
Filter expression should be set to
catch_all() and the
action should be
forward('https://app-user.rhcloud.com/mailgun/mime') to forward an
HTTP version of the incoming email to your Tracks server. That’s it
for Mailgun config, but keep the
Logs tab open for testing in a moment.
Now for the Tracks config. Open up
config/site.yml and check these
email_dispatch: 'to' # this is the default in my quickstart anyway mailgun_api_key: '<api key from Mailgun>' mailmap: firstname.lastname@example.org: - email@example.com
The first two settings are easy to fill in. The
mailmap needs some
explaining. When you send an email to Tracks (via Mailgun), two checks
are performed. First, since Tracks is inherently multi-user, the
address is used to try and identify the particular login you wish to
add a Todo to. Then, for each incoming email address, a list of valid
From) address is created - after all, you wouldn’t want
spammers sending things to your Todo list.
To make this work, we thus set the first value to the address we send to (the mailgun address) and the second to the email we send from (say, a GMail address). We can then push this config to Openshift:
$ git diff --- a/config/site.yml +++ b/config/site.yml -# mailgun_api_key: key-abcdef1234567890 +mailgun_api_key: key-abcdef1234567890 -# mailmap: -# 'firstname.lastname@example.org': -# - 'email@example.com' -# - 'firstname.lastname@example.org' +mailmap: + 'email@example.com': + - 'firstname.lastname@example.org' + - 'email@example.com' $ git commit -m "Mailgun config" $ git push openshift HEAD:master
Once again, that will take a long time to run, but should be successful.
Finally, we also need to associate the Mailgun email in our
Tracks preferences. On your Tracks page, go to
and select the
Behaviour tab. Put your Mailgun address in the
That’s it! Try sending an email from your allowed sending address to your mailgun address. On the Mailgun Logs tab, you will see logs like:
25.09.2013 20:17 Posted: firstname.lastname@example.org → https://app-user.rhcloud.com/mailgun/mime 'test todo' 25.09.2013 20:16 Accepted: email@example.com → https://app-user.rhcloud.com/mailgun/mime 'test todo' 25.09.2013 20:15 Routed: firstname.lastname@example.org → email@example.com 'test todo' Route match: Import task via Mailgun(0): catch_all()
You should also see the task arrive in your Todo list.
We’ve built a full Todo management system, complete with email functionality, using free tools. I hope it’s useful to you - I’ve certainly got more blogs on my Todo list :)