Steve Domino

@skdomino

How I Ran an Unsupported Discourse Install with Nanobox

At Nanobox, because of the nature of our product, we get a lot of tough questions. Anything from how to use our product to questions about various different languages and frameworks. We’ve been using Slack not only as an internal communication tool, but also as the main method of support for our users. It makes it very easy to help trouble shoot issues, and answer their questions. But, we find ourselves answering a lot of the same questions over and over again as new users join.

Naturally, we figured it was time to set up a forum. A forum would give us a place to put the answers to all the questions we get. We would then be able to direct people where to find answer to all the great questions we get.

We looked for quite some time for what would best fill our needs. There were a few good options out there but ultimately we landed on Discourse. The amount of stuff you get for the price tag (free) with Discourse is quite amazing. The team at Discourse has done a great job.

It has everything you would expect from a full-featured forum platform. Also, there are tons of great official, and community, plugins for anything you feel like it’s missing out of the box.

Easy to install… sort of

Discourse has creating an officially supported Docker installation. Which is very cool. They’re very very (very) adamant you use this. And have made it clear that not doing so comes at the cost of support:

I don’t call this out because I think there is anything wrong with what they’re doing. In fact the exact opposite. I think it makes complete sense. How could a small team be expected to support so many possible installs of their project?

I totally sympathize with the demands users put on a development team. Especially for a project that provides as much value as Discourse. I think it’s great they’ve taken the time to create such an easy installation method.

But…

The Task at Hand

You’re here because for whatever reason you don’t want to use their Docker install. That’s fine, I’ll show you how to run Discourse “without” Docker.

The reason I’m here is because I was tasked with setting up Discourse as our official forum. I could have easily followed their guide and had it up and running quickly. However, just like Discourse uses their own product as their official forum, it was important to me that I use our product as the method for deploying it.

Docker is a very powerful tool that has changed the way we think about web applications, but it requires a lot out of developers to learn, understand, and use. It’s not necessarily difficult, but there is a time investment to getting comfortable with it for sure.

Creating a “Dockerized” version of Discourse makes it much easier to control the outcome of every install. This really helps the team at Discourse ensure that their users have as good an experience as possible. That’s the same reason Nanobox exists. Not all developers have the time or talent available to be full time application developers and full-stack, DevOps, system administrators. Nanobox fills that gap.

Diving In

Let me reiterate. The process I followed goes directly against Discourse’s recommended procedure. Proceed at your own risk…

I won’t go into all the details of how to deploy Discourse with Nanobox (you can read about that on our blog). I’ll be talking more about my experience trying to get Discourse running using Nanobox.

Normally a “traditional” Rails app is very easy to deploy using Nanobox. In fact, our very own dashboard is a very large and complex Rails app that we’ve deployed to DigitalOcean using Nanobox.

Discourse is anything but a traditional Rails application. They do have various “getting started” guides ranging from beginner to advanced. Most of which only help you get Discourse running locally. You’re left to figure out production deploys on your own.

First Things First

I read through their requirements list to get a good idea of what I’d need to start with. At the very least I was going to need Ruby, Rails, Postgres, and Redis.

This was my initial boxfile.yml configuration:

run.config:
engine: ruby
extra_packages:
- nodejs
- nginx
data.db:
image: nanobox/postgresql:9.4
data.redis:
image: nanobox/redis

I modified the config/boot.rb so that the server would bind to 0.0.0.0 allow access from the outside world, and the config/database.yml so the app could connect to the database.

After running a rake db:migrate I tried to start the app. I noticed immediately I was missing some additional packages Discourse needed, so I made the following modifications to my boxfile.yml:

run.config:
engine: ruby
extra_packages:
- git
- nodejs
- nginx
- ImageMagick
- optipng
- jpegoptim
- gifsicle
- jhead
extra_steps:
- yarn install
extra_path_dirs:
- node_modules/.bin
cache_dirs:
- .bundle
- vendor/bundle
- node_modules

This gave me enough to get the application running locally. My next task was to get it deployed to production. This is where things got difficult…

Staging Discourse

Nanobox lets me stage a production deploy locally with the dry-run command. This is awesome because I can make sure everything works before I deploy. This turned out to be much more difficult than it should have been. All of my problems stemmed when I tried to precompile assets…

In Rails 3, there was a nice little setting called initialize_on_precompile. Setting this to false would tell Rails you didn’t want to initialize the app to precompile all the assets. That was exactly what I wanted. You shouldn’t need to initialize your entire application just to precompile assets.

Turns out, in Rails 4+ they removed this setting. This caused huge issues for me. Now when I was precompiling assets, Discourse was trying to connect to Postgres and Redis.

When running Nanobox locally all services are running, so I never ran into any issues. When trying to deploy however, The services aren’t running when I try to precompile assets (because they don’t need to be).

Nanobox lets you define “hooks” that are run at specific times during the provisioning and deployment process. Well, neither Postgres nor Redis existed when I was trying to precompile assets because neither gets created until later in the process.

I tried to get around this with a few modification to the core application. I thought I’d use an environment variable to skip anything that was trying to connect to either service, so I went around the code adding this:

if ENV["PRECOMPILE"]...

This did NOT work… there are so many dependencies on Postgres and Redis that it was turning into a monster. I took a step back…

Knowing how Nanobox worked, and the requirements of Discourse, I decided that I wasn’t going to be able to compile assets during the build. I’d have to do it in production, after the deploy.

This is not the ideal way to do it, but in the end it worked out ok. I modified the boxfile.yml one more time to give me a local storage component. Storing the assets here, makes them accessible to anything that needs them.

This is the final boxfile.yml I used to get Discourse staged and deployed successfully:

You can find info about each different node and what they do in the guide.

There are a couple of strange things in there that you wouldn’t normally see when deploying a Rails application. Luckily the boxfile.yml is flexible enough that I was able to get everything I needed to get things working.

Tying up Loose Ends

There were just a few more things that I needed to take care of before everything ran smoothly.

discourse.conf

Discourse provides a discourse.conf file for production configuration. At the top it gives you a few different options on how to use the file.

You can:

  1. Do nothing (not recommend).
  2. Copy the config file and update with your own settings.
  3. Use environment variables in the form DISCOURSE_*

At first, I interpreted this to mean that you could use the config file and evars at the same time. After I noticed it wasn’t using some of my evars, I dug into the source and found they are mutually exclusive.

Rather than use half evars and half config file, I ended up using only the config file (I still used evars in the config file, I just wasn’t expecting them to get pulled directly from the environment anymore):

Nanobox automatically generates evars for data services, so I was able to include those in the config right away. Any additional evars I needed, I had to add manually. For example our SMTP credentials:

DISCOURSE_SMTP_ADDRESS
DISCOURSE_SMTP_PORT
DISCOURSE_SMTP_DOMAIN
DISCOURSE_SMTP_USER_NAME
DISCOURSE_SMTP_PASSWORD
Even though I didn’t use the evars straight out of the environment I still used the convention Discourse outlined when creating them, and just added them to the config file.

With that all in place, running Discourse on Nanobox turned out to be a breeze. And, while I wasn’t using their official Docker installation, Nanobox uses Docker under the hood, so same thing right?

Wrapping Up

Discourse was not the traditional Rails application I was hoping it would be. After spending a lot of time digging around in the source code trying to get it working, I found that they’ve overridden, or removed, a lot of what you might expect to find.

All of the initializers are custom, and many standard rake tasks have been completely re-written. They also make a lot of assumptions about the state of the application when you’re trying to run it.

That being said, they’re expecting you to use their Docker image, which works great. So it doesn’t really matter what the underlying application looks like. Once I compensated for all that, the problems went away.

Thanks again to the team at Discourse for such a great project and all the work they’ve done, and continue to do. Now that it’s running, Discourse has worked well for us.

If you’re wanting to get you’re own forum up-and-running with Discourse follow the detailed guide on our blog. If you just want to launch a forum with out doing any work, check out our quickstart.

Please reach out if you run into any issues, or have any questions. You can comment here, or join our Slack team and we’ll do what we can to help.

More by Steve Domino

Topics of interest

More Related Stories