Emerald Reverie

Gwmngilfen's blog - Tech, cooking, walking and other randomness from the heart of Scotland

Building a Todo System With Tracks, Openshift, Postgresql, and Mailgun

| Comments

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

Openshift Online

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 is 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 Create. Now we have a server! Make a note of the SSH access and Git repo URL, for example:

1
2
Git - ssh://52433f38500446b10100008e@app-user.rhcloud.com/~/git/test.git/
SSH -       52433f38500446b10100008e@app-user.rhcloud.com

( I’ve deliberately lined up the two user IDs you can see they’re the same.)

Postgresql

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 the 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.

Tracks

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:

1
2
3
$ 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:

1
2
3
$ 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:

1
2
3
4
5
6
--- 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:

1
2
3
$ 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:

1
2
3
4
5
6
7
$ git remote add openshift ssh://52433f38500446b10100008e@app-user.rhcloud.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 bundle install and 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 /mobile

Side note: Troubleshooting

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 app-root/repo directory):

  • Logs: tail log/production.log
  • Database migration: bundle exec rake db:migrate RAILS_ENV=production

Mailgun

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 new route. 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 settings:

1
2
3
4
5
email_dispatch: 'to' # this is the default in my quickstart anyway
mailgun_api_key: '<api key from Mailgun>'
mailmap:
  app@user.mailgun.com:
  - sendingemail@domain.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 To 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 sending (i.e. 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ git diff
--- a/config/site.yml
+++ b/config/site.yml
-# mailgun_api_key: key-abcdef1234567890
+mailgun_api_key: key-abcdef1234567890
-# mailmap:
-#   'user@preferences.from.value':
-#   - 'acceptable1@personal.org'
-#   - 'acceptable2@work.com'
+mailmap:
+  'app@user.mailgun.com':
+  - 'acceptable1@personal.org'
+  - 'acceptable2@work.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 Admin > Preferences and select the Behaviour tab. Put your Mailgun address in the From email textbox, and save it.

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:

1
2
3
25.09.2013 20:17  Posted: acceptable1@personal.org → https://app-user.rhcloud.com/mailgun/mime 'test todo'
25.09.2013 20:16  Accepted: acceptable1@personal.org → https://app-user.rhcloud.com/mailgun/mime 'test todo'
25.09.2013 20:15  Routed: acceptable1@personal.org → app@user.mailgun.com 'test todo' Route match: Import task via Mailgun(0): catch_all()

You should also see the task arrive in your Todo list.

Conclusion

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 :)

Comments