Tag Archives: Heroku

Deploying Discourse to Heroku

Recently I stumbled upon Discourse. Finally someone tackled that problem. Forums, while rich in content, have been so dull and unfriendly for so long. Anyway, I wanted to get  it up and running for myself, preferably on some cloud infrastructure, to play around. I’ve had previous experience with Heroku, so chose that setup, for no other reason. The Discourse’s own forum has plenty of other options so feel free to investigate.

As for the Heroku setup, there are existing guides, see [4] and [5]. The difference between them is that when using Discourse’s default configuration samples, you get Open Redis support, while I wanted to use Redis Cloud add-on, similar to Swrobel’s take on it. Also, I wanted to use Autoscaler for Sidekiq to reduce total cost on Heroku, as noted in Discourse’s document. All in all, I ended up with a mix of ideas from both sources. Add-ons used on Heroku:

Currently free plans are used for all of them as you can see below.

Heroku Configuration for a Discourse instance

To be able to repeat the process and easily deploy updates using Discourse’s Github repo, I’ve created a small Bash script for this. It basically performs the following tasks:

  • goes into your local Discourse git repo
  • creates a new branch, based on the current branch you’re on (all changes must be committed)
  • creates Redis configuration using provided sample and tweaked for Redis Cloud
  • adds mail configuration to production environment
  • removes clockwork from Procfile
  • set’s ruby version to 2.0 in Gemfile
  • configures Sidekiq for Autoscaler
  • creates temporary database and migrates it
  • precompiles assets using the above database
  • drops the temporary database
  • commits all configuration changes along with precompiled assets
  • pushes it all to Heroku
  • migrates the database on Heroku
  • and finally deletes the deployment branch

You can find the script here, feel free to use it, change it, do things to it you see fit 🙂 The main idea was to do as minimum manual work as possible, at least for this phase where I follow the default instructions closely. This of course might change, but for now is quite all right.

Prerequisites for executing the script:

  • You need to be able to run Discourse locally or at least to be able to precompile assets
  • This means you need:
    • PostgreSQL
    • Ruby 2.0
    • Cloned Discourse Github repo

When setting up PostgreSQL, take care to enable HStore on it [2] and to set appropriate discourse user permissions [3]. You can change username and password easily to match your setup.

Also, you need to replace the SECRET_TOKEN within the script and match it to your own setup. I took care to match it to the one set for the Heroku instance (heroku config:get SECRET_TOKEN).

Aside from the script, you should still follow the instructions on mentioned documents to e.g. create initial user, setup Amazon S3 upload etc.

Finally, the forum is up:

Running Discourse

Resources:

  1. Installing PostgreSQL on Ubuntu
  2. Enabling HStore for PostgreSQL
  3. Setting PostgreSQL permissions
  4. Swrobel’s take on Heroku deployment
  5. Discourse’s own Heroku deployment instruction
  6. Related topic on Discourse’s forum
Advertisements
Tagged , , , , , ,

Rails secret

Secret_token.rb has the word “secret” in it for a reason. Unfortunately, open sourced Rails applications tend to forged this. Ignoring the file in the SCM of your choice is not enough, the secret token is needed for Rails to work. So, how can we avoid publishing this information and still enable secret token configuration in production? The answer is simple. Either put you secret token in an .gitignored file and load it secret_token.rb or use the environment. So, how bout we use both?

class ConfigurationError < StandardError; end

secret_token_file = 'config/secret_token.yml'
secret_token = ENV['SECRET_TOKEN'] || secret_token = YAML::load(File.open(secret_token_file))[Rails.env]['token'] if File.exists?(secret_token_file)
raise ConfigurationError.new("Could not load secret token from environment or #{File.expand_path(secret_token_file)}") unless secret_token

Dealesque::Application.config.secret_token = secret_token

This configuration has the added bonus of being able to deploy on Heroku without any changes to the code.

SECRET_TOKEN can be added as environment variable or config var as Heroku calls them. The procedure is simple, open up your console and:


heroku config:set SECRET_TOKEN=...aba5a33f3dbad3b694f6154b...

And that’s it 🙂

Tagged , ,

Deploying Rails with Twitter Bootstrap on Heroku

Lately I’ve been playing with deploying a Rails application to Heroku. A most pleasurable experience but I’ve had some issues with Twitter Bootstrap. The reason is that Heroku discourages the usage of therubyracer gem, see https://devcenter.heroku.com/articles/rails3x-asset-pipeline-cedar#therubyracer for details. In my development environment I used the twitter-bootstrap-rails gem and I wanted to keep using it along with the less support. There are some other non less solutions, as described at the Ruby Source here, but that didn’t seem appealing. So, the only solution I could find was to precompile the assets and push them to Heroku. Aside from that, there were a few more issues to resolve:

  • Use of the helper bootstrap_flash doesn’t work when precompiling assets – the solution was to copy the helper to my Rails project, as described here
  • To be able to continue to use therubyracer gem in development, I had to move it to development group in Gemfile

Now, the procedure is pretty simple, just precompile the assets and push to Heroku and that’s it? Well, almost 🙂

I wanted also to be able to not use the precompiled assets in development, since this requires a bit of manual work (one needs to precompile for each run) and at the same time I didn’t want to forget precompiling them before pushing to Heroku. Hence, I put together a small shell script that:

  • creates a separate branch from the current one
  • precompiles the assets
  • pushes that branch to Heroku – it needs to be pushed to master
  • deletes the new branch

Tagged , ,