An Open Source Forum with Discourse and Nanobox

Discourse is a very popular open source forum because of its robust features. The amount of stuff you get for the price tag with Discourse is quite amazing and the team behind it has done a great job.

Discourse has everything you would expect from a full-featured forum platform. And for anything you don't get out of the box, there are tons of both great official and community plugins.

Installation (with Discourse)

If you're interested, Discourse offers paid plans to get your forum installed, configured and hosted quickly. This is a good option for anyone wanting to get a forum up right away with little work.

The next option is their officially supported Docker installation. They've put a lot of work into this to make it as easy as possible (but I'll be showing you an easier way).

Installation (with Nanobox)

This article outlines how to create and deploy a Discourse forum using Nanobox. If you're not familiar with Nanobox, it's a micro-platform that allows you to build, deploy, and manage your app anywhere.

I feel at this time I need to bring up one very important thing... What I'll show you here is an unsupported installation and highly frowned upon by the Discourse team. They have an official supported installation method (mentioned above), which is the only method for which they provide support.

With that out of the way, if I haven't scared you off (yet), let's get started!

This tutorial assumes you already have a Nanobox account and have downloaded Nanobox. If you need to, create an account, and download Nanobox Desktop before you begin.

Getting Started

I'll cover two separate methods of installing Discourse with Nanobox:

Using the Quickstart

First things first. Clone the nanobox-discourse quickstart and change into its directory:

git clone https://github.com/nanobox-quickstarts/nanobox-discourse && cd nanobox-discourse  

From here you have a few options:

I would suggest you do these in order, but you're welcome to skip ahead.

Run Discourse Locally

Before you do anything, add a convenient way to access your application from the browser:

nanobox dns add local discourse.dev  

Once you have the application cloned you can simply run the following:

# start your dev env and drop into a console
nanobox run

# migrate your data
rake db:migrate

# start your server
rails s  

You should now be able to visit your application at discourse.dev

Note: You'll likely need to add an admin user to get past the welcome screen. The easiets way to do this is from a nanobox console (nanobox run) do rake admin:create

Stage Discourse Locally

Note: Discourse takes a ton of resources. Unless you've got a lot of resources dedicated to it, you might have some problems getting it to stage.

Nanobox lets you stage your application in a production setting before deploying it. To simulate running in production you'll want to tell rails to run in production:

nanobox evar add dry-run RAILS_ENV=production  
nanobox deploy dry-run  

This spins up an environment that is an exact replica of a production environment.

Deploy Discourse to Production

Note: Discourse takes a ton of resources. You'll need to scale your application to at least 1GB of ram before you can deploy (I would recommend 2GB).

Before you can deploy to production you'll need to create a new app on Nanobox. Once your app's created, link it to your local codebase and deploy:

nanobox remote add <your-app-name>  
nanobox deploy  

This deploys your app to production. Nanobox uses the boxfile to provision and configure the same infrastructure you're app's already been running in.

That's it!

If you have any questions or run into any issues please reach out!

Note: You'll likely need to add an admin user to get past the welcome screen. The easiets way to do this is from a nanobox console (nanobox console web.main) do rake admin:create

Discourse From Scratch

To run Discourse from scratch you'll first need to clone Discourse and cd into the directory:

git clone git@github.com:discourse/discourse.git && cd discourse  

Add a Boxfile

Nanobox uses a simple yml config file called a boxfile. The boxfile is used to describe your applications infrastructure to Nanobox.

Discourse has quite a few requirements to run. I'll add comments to the boxfile highlighting important configurations:

run.config:

  # Discourse is a Ruby on Rails application so we need to tell Nanobox to install Ruby
  engine: ruby

  # These are all the extra packages required by Discourse to run. The notable ones here are nodejs and nginx, which Nanobox will install for us and make them available to use
  extra_packages:
    - git
    - nodejs
    - nginx
    - ImageMagick
    - optipng
    - jpegoptim
    - gifsicle
    - jhead

  # Discourse uses some node packages, so we need to tell Nanobox to install them for us
  extra_steps:
    - yarn install

  # Some of the node packages used have executables that we'll need access to, so we need to add them to our PATH
  extra_path_dirs:
    - node_modules/.bin
  cache_dirs:
    - .bundle
    - vendor/bundle
    - node_modules

# When deploying our application we can provide Nanobox with some extra instructions. Tell Nanobox to migrate data and precompile assets before the application's live.
deploy.config:  
  before_live:
    web.main:
      # - bundle exec rake db:setup_or_migrate
      - bundle exec rake db:migrate RAILS_ENV=production
      - bundle exec rake assets:precompile --trace RAILS_ENV=production PRECOMPILE=true

# Specify a web component and give it start commands
web.main:  
  start:
    nginx: nginx -c /app/config/nginx.conf
    puma: bundle exec puma -C /app/config/puma.rb
  writable_dirs:
    - log
    - plugins
    - public
    - vendor
  network_dirs:
    data.assets:
      - public/assets
      - tmp
  log_watch:
    rails[discourse]: log/production.log
    puma: log/puma.log

# Discourse uses a sidekiq worker queue. This tells Nanobox to create a worker component, give it a start command.
worker.main:  
  start: bundle exec sidekiq
  writable_dirs:
    - log
    - public
  network_dirs:
    data.assets:
      - tmp

  # stream the worker logs to the dashboard
  log_watch:
    sidekiq: log/sidekiq.log

# Discourse is married to postgres, so we'll tell Nanobox to create a postgres database for us
data.db:  
  image: nanobox/postgresql:9.4

# This is actually used 
data.assets:  
  image: nanobox/unfs

# Discourse uses redis to store cache, so we'll have Nanobox create a redis component for us
data.redis:  
  image: nanobox/redis

Run Discourse Locally

To run Discourse locally, copy the boxfile from above. Place it at the root of your project's directory and run the following command:

nanobox run  

Configure Discourse

Before starting the application you'll need to add a few pieces of configuration.

Connecting to the Database

To connect Discourse to your database, update the database.yml. Nanobox generates environments variables for you to use here:

development:  
  prepared_statements: false
  adapter: postgresql
  database: gonano
  min_messages: warning
  pool: 5
  timeout: 5000
  host: <%= ENV['DATA_DB_HOST'] %>
  username: <%= ENV['DATA_DB_USER'] %>
  password: <%= ENV['DATA_DB_PASS'] %>
  host_names:
    ### Don't include the port number here. Change the "port" site setting instead, at /admin/site_settings.
    ### If you change this setting you will need to
    ###   - restart sidekiq if you change this setting
    ###   - rebake all to posts using: `RAILS_ENV=production bundle exec rake posts:rebake`
    - "localhost"

The pieces that need to be changed here are database, host, username, and password.

Use the default database gonano which is generated when adding a data component. This way you won't need to create a new database, and deploy to production is a little easier.

If you decide to use discourse_development you'll need to create your database first. When it's time to deploy you'll need a special rake task that does this for you as well.

Up and Running

Next, you'll need to add the following to your config/boot.rb:

# NANOBOX: change the default binding from localhost to 0.0.0.0
require 'rails/commands/server'  
module Rails  
  class Server
    def default_options
      super.merge(Host: '0.0.0.0', Port: 8080)
    end
  end
end  

This tells Rails to listen on all available hosts. This makes the application accessible outside the VM.

Note: If your version of Discourse is using Rails 5+, this method doesn't work anymore. Later, when starting your server you'll need to start with rails s -b 0.0.0.0 -p 8080.

Make Your App Accessible

The final thing to do is add a DNS alias to make your application easily accessible from a browser.

You do this with the nanobox dns command:

nanobox dns add local discourse.dev  
Final Configurations

With all that configuration in place, it's finally time to start up Nanobox for some final steps.

The nanobox run command will create your local development environment. This mounts your local code base into a VM where your infrastructure is running.

nanobox run  

Once nanobox run has completed you're dropped into a Nanobox console. From in here the final thing you'll need to do is migrate your data and then start your server:

rake db:migrate  
rails s  

Once your server is running you should be able to visit your application at discourse.dev (or whatever DNS you setup above).

Note: You'll likely need to add an admin user to get past the welcome screen. The easiets way to do this is from a nanobox console (nanobox run) do rake admin:create

Configure Discourse for Production

There are a few different methods for getting Discourse configured for production. Nanobox automatically generates some environment variables for you to use. Copy Discourse's example config to use as your own:

cp config/discourse_defaults.conf discourse.conf  

Inside your new discourse.conf find and add the following environment variables:

db_host = <%= ENV['DATA_DB_HOST'] %>  
db_name = gonano  
db_username = <%= ENV['DATA_DB_USER'] %>  
db_password = <%= ENV['DATA_DB_PASS'] %>  
hostname = <%= ENV['DISCOURSE_HOSTNAME'] || "www.example.com" %>  
smtp_address = <%= ENV['DISCOURSE_SMTP_ADDRESS'] %>  
smtp_port = <%= ENV['DISCOURSE_SMTP_PORT'] %>  
smtp_domain = <%= ENV['DISCOURSE_SMTP_DOMAIN'] %>  
smtp_user_name = <%= ENV['DISCOURSE_SMTP_USER_NAME'] %>  
smtp_password = <%= ENV['DISCOURSE_SMTP_PASSWORD'] %>  
redis_host = <%= ENV['DATA_REDIS_HOST'] %>

This will give your application everything it needs to run in production.

Stage Discourse Locally

Note: Discourse takes a ton of resources. Unless you've got a lot of resources dedicated to it, you might have some problems getting it to stage.

Once you're ready to deploy to production it's recommended you stage your app to ensure it works.

Normally, you would need to configure a production server and deploy there. Nanobox allows you to simulate a production environment from the safety of your own machine.

To simulate a production environment first make sure Rails is running in production:

nanobox evar add dry-run RAILS_ENV=production  
nanobox deploy dry-run  

This fires up a local staging environment and configures it exactly as it will be when deployed to production. Once staged (and working) it's finally ready to deploy to production.

Deploy to production

Note: Discourse takes a ton of resources. You'll need to scale your application to at least 1GB of ram before you can deploy (I would recommend 2GB).

Before you can deploy to production you'll need to launch a new application on Nanobox.

Once your app is createdlink your local codebase to your new application:

nanobox remote add <your app name>  

Once your codebase is linked you can deploy:

nanobox deploy  

Using the boxfile, Nanobox creates the same environment in production you've been using locally.

That's it!

At this point, you should have your very own Discourse forum up-and-running.

Note: You'll likely need to add an admin user to get past the welcome screen. The easiets way to do this is from a nanobox console (nanobox console web.main) do rake admin:create

Help!

If you've run into any issues, or have any problems please reach out, I'd love to help!

Steve Domino

Husband, father, and tech enthusiast passionate about finding, using, and creating awesome stuff. Engineer at https://nanobox.io.

Subscribe to Nanobox

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!