Web-based GTD: Putting tracks on heroku

Published
24 March 2015
Tagged

Update: I've written about this in a bit more detail in a later post.

As of about three weeks ago, I have a proper, paying job. The job itself is great - I'm doing somrthing that (for now) I find interesting, engrossing, and worthwhile, at a really great place, in a pretty neat city. I get to hang out with incredibly geeky people and learn about a whole bunch of interesting things.

One of the things I've had to get used to, though, is having a work computer. During my Ph.D. I did all my computer work on my laptop, which was a mix of great and not-so-great. I could do what I wanted on my system, install whatever I wanted, process data with whatever tools appealed to me, and write my thesis in LaTeX, much to the consternation of my advisor. However, this did mean that I had to lug my laptop everywhere I went, and when I was working at Uni I was constrained to a rather small screen and generally pretty laptop-y keyboard. In addition, it meant I had to pay for my own work-station.

Now I have my own computer at work. It's great, in a way: I don't have to bring the laptop to work, and it's all kitted out and optimised for exactly the sort of work I'm doing[1]. Plus a nice big screen is handy when you need three different windows open for your current task.

There's one big thing I miss from my OS X-only days, though, and that's the miracle of productivity that is OmniFocus. OmniFocus kept me organised throughout both my degrees, and its project-and-context system (with a few hacks) was a miracle of organisation for both personal and work projects. As soon as I arrived at my new job, I started getting information from people - things I wanted to track or do or get more information about - and I had no inbox to put them in. A list in a book worked at first, but I was soon reaching the point where I needed something a bit more heavy-duty.

I started to look around for alternatives to OmniFocus - either Windows-based programs that I could run on my workstation with whatever privileges I had, or web-apps that I could have running in a tab in Firefox. And I found that all but one lacked some feature or other. The standout app was Tracks, a self-hosted, rails-based GTD app that I remember from the halcyon days when you could consider rails an "up-and-comer".

Tracks and OmniFocus are quite alike. They're not the simplest or prettiest apps in their field, but they do GTD really well. Tracks' projects and contexts fit right into my workflow, and its dependencies[2] are a godsend, sorely missing from almost every other GTD app in the field. There's only one main flaw with Tracks: you need to host it yourself.

Hosting with Heroku

So, how to host Tracks? More importantly, how to host tracks without paying a ridiculous amount every year for a service that only I will use? The hosting service Heroku was my first thought: it's one of the first cloud platforms I heard about, and I remembered that it was generally free as long as your app was small, low-traffic, and not that database-intensive. These all describe a one-person Tracks install, so I thought I'd give it a go.

Downloading and unzipping Tracks from the website, the first thing I needed to do was set up a couple of yaml files in the config folder. Of note, I needed to copy over database.yml.templ and site.yml.templ to database.yml and site.yml respectively, and set the appropriate values. To start I decided on sqlite as a database, however I'll be talking about why this is a bad choice soon enough.

Once everything was set up, it was time to upload to heroku. While heroku has a number of ways you can upload your webapp, I tend to prefer the heroku toolbelt. Once this is installed, all you need to do is cd to the right directory, initialise a git repo, and then make a heroku app:

$ git init
$ heroku create your-appname-here

If you go to your Heroku dashboard, you'll see your new app here as well:

Heroku dashboard, with the new app.

Heroku dashboard, with the new app.

Now all you need to do is add, commit and push:

$ git add -A .
$ git commit -m "First commit"
$ git push heroku master

After a series of status messages from heroku (and a bit of waiting as it installs the relevant gems), the process will probably result in failure:

remote:        checking for sqlite3.h... no
remote:        sqlite3.h is missing. Try 'port install sqlite3 +universal',
remote:        'yum install sqlite-devel' or 'apt-get install libsqlite3-dev'
remote:        and check your shared library search path (the
remote:        location where your sqlite3 shared library is located).
...
remote:  !     Failed to install gems via Bundler.
remote:  !     
remote:  !     Detected sqlite3 gem which is not supported on Heroku.
remote:  !     https://devcenter.heroku.com/articles/sqlite3
remote:  !
remote: 
remote:  !     Push rejected, failed to compile Ruby app

Which is less than ideal. Undeterred, I decided to switch to Heroku's own PostgreSQL plugin.

Postgres and Heroku

Heroku apps can take any number of add-ons, some free, some paid. Heroku supplies some of its own as well, including a handy PostgreSQL plugin. Heading to the add-ons page, a search for "postgresql" turns up a grand total of 5 add-ons, including, at the top, Heroku's own:

To the right of this table we see the text:

heroku addons:add heroku-postgresql

To add the add-on to our app, we just go back into the terminal and type that in:

$ heroku addons:add heroku-postgresql
Adding heroku-postgresql on your-appname-here... done, v6 (free)
Attached as HEROKU_POSTGRESQL_TEAL_URL
Database has been created and is available
 ! This database is empty. If upgrading, you can transfer
 ! data from another database with pgbackups:restore.
Use `heroku addons:docs heroku-postgresql` to view documentation.

Which is relatively painless. Heading back to your app's page on heroku, you'll now see the PostgreSQL database sitting there, waiting for us to interact with it:

production: adapter: pg database: $DATABASE_NAME host: $HOST_NAME port: $PORT username: $USER_NAME password: $PASSWORD

With appropriate values added in place, of course. If you're smart, you'll have also noticed that Tracks lists mysql2 and sqlite3 in its Gemfile, which you'll need to shift out. If you want to try development on your machine with sqlite, you may want to do something like this:

# Databases
gem "sqlite3",  group: [:development, :test]
gem "pg",       group: :production

That should be all you need to do, right? Let's re-install our gem bundle and push:

$ bundle install
$ git add -A .
$ git commit -m "Using pg"
$ git push heroku master

And everything should work! Kinda-sorta. You'll probably received a few warnings from heroku, but we'll deal with those later. To set up your database, you can run:

heroku run rake db:migrate

Now when you access your app, you should be ready to roll! For this app, the url will be http://your-appname-here.herokuapp.com.

Squashing warnings

What about those warnings that come up? Most aren't too problematic to fix.

remote:        #######################################################
remote:        The bcrypt-ruby gem has changed its name to just bcrypt.  Instead of
remote:        installing `bcrypt-ruby`, you should install `bcrypt`.  Please update your
remote:        dependencies accordingly.
remote:        #######################################################

This is as easy to fix as it sounds. Go into your gemfile and replace the bcrypt-ruby line with:

gem 'bcrypt', "~>3.1"

Or the appropriate version of bcrypt at the time of reading. Don't forget to run bundle install after modifying your gemfile.

remote:        DEPRECATION WARNING: You have Rails 2.3-style plugins in vendor/plugins! Support for these plugins will be removed in Rails 4.0. Move them out and bundle them in your Gemfile, or fold them in to your app as lib/myplugin/* and config/initializers/myplugin.rb. See the release notes for more on this: http://weblog.rubyonrails.org/2012/1/4/rails-3-2-0-rc2-has-been-released. (called from <top (required)> at /tmp/build_78983489f1251de269bbccfc8a7dda97/Rakefile:7)

I'm currently not sure what's causing these warnings to call, as vendor/plugins is empty before you push to the server. I'm ignoring them for now: I assume that when the Tracks team upgrades to Rails 4, they'll make sure that these warnings go away as well.

remote: ###### WARNING:
remote:        Injecting plugin 'rails_log_stdout'
remote: 
remote: ###### WARNING:
remote:        Injecting plugin 'rails3_serve_static_assets'
remote: 
remote: ###### WARNING:
remote:        Add 'rails_12factor' gem to your Gemfile to skip plugin injection

These plugins imitate previous rails behaviour that got removed in later versions of rails. I don't know the details, but Heroku seems to want them to stay around, so I let it by adding rails_12factor to my gemfile (and running bundle install).

remote: ###### WARNING:
remote:        You have not declared a Ruby version in your Gemfile.
remote:        To set your Ruby version add this line to your Gemfile:
remote:        ruby '2.0.0'
remote:        # See https://devcenter.heroku.com/articles/ruby-versions for more information.

Another interesting use of the Gemfile is to specify the version of ruby you want Heroku to run for your app. Ruby 2.0.0 works fine with tracks, so you can add this line to the top of your Gemfile without any worries.

remote: ###### WARNING:
remote:        No Procfile detected, using the default web server (webrick)
remote:        https://devcenter.heroku.com/articles/ruby-default-web-server

I haven't had any experience with Procfiles in the past, but Heroku has a bit of documentation about why you shouldn't use webrick, as well as more info about the purpose Procfiles serve. Right now I'm running without a procfile and everything seems fine. I might see a performance increase if I started using a Procfile, but right now I care about my GTD app not crashing, rather than performance increases.

Poking around the innards

You may find that Heroku crashes in new and interesting ways for you. The easiest way to see what's going on under the hood is by inspecting your logs. While in the same directory as your git repo, type:

$ heroku logs

And bask in the colour-coded glory. Hopefully that'll help you sort things out.

Now go forth and be productive, on whatever platform you wish.


  1. And in the world of dictionary-editing, the setup and software you need are relatively specialised ↩︎

  2. In which one task won't show until every task it depends on is complete. ↩︎