Public | Automated Build

Last pushed: 2 months ago
Short Description
A discourse image, that has discourse baked in.
Full Description

Discourse docker-compose configuration

The preffered way to deploy Discourse is to use, but this flow didn't fit our
deployment strategies.

Our goals are:

  • Have image that has all dependencies baked in, and have it tested with all our
    system, and then deployed, first to preprod then to prod enviornments.
  • Be able to run discourse inside our normal docker clusters.
  • Acknowlediging that my understanding of Ruby world is. . . limited, I wanted to
    re-use as much of discourse_docker code.
  • I definetely didn't want to fork discourse.
  • Use 12 factor guildelines as much as possible.

What we didn't need:

  • Magic button that updates discourse --- to update we'll re-build the image, test
    everything and then deploy.

So here we ware.

How this works

Build time

discourse_docker relies on a provisioning tool called pups that uses
templates to provision server. It works kinda sorta like Ansible.

So our Dockerfile is based on discourse/discourse, and during image
creation we apply two templates: web.template.yml, and web.ratelimited.template.yml.

We have updated web.template.yml to disable running migrations.


At runtime we have two containers and couple of volumes.

Containers are:

  • discourse_migrate --- It runs migrations and compiles assets, then it exits.
  • discourse --- Runs discourse: Rails app, nginx, rsyslog, you name it ;).
    It would be good to 12 factorize it, but this probably not worth the effort.

Volumes are:

  • discourse_assets for compiled assets, assets are shared inside volume,
    as they are generated in discourse_migrate.
  • discourse_logs logs.
  • discourse_shared all other stuff, including: backups, letsencrypt certs etc.

Developement enviornment

docker-compose.yml contains a fully working development enviornment,
just docker-compose up and after a while point your browser to:

If you need to test email sending, locally head to: http://localhost:8025,
mailhog is located there.

Runtime enviorment variables

Before deploying this to producition you'll probably want to set
this variables:

Sane defaults:


Some ruby magic that makes discourse run faster:

# this gives us very good cache coverage, 96 -> 99
# in practice it is 1-2% perf improvement
# stop heap doubling in size so aggressively, this conserves memory
## Uncomment if you want the container to be started with the same
## hostname (-h option) as specified above (default "$hostname-$config")

How many threads to use:


Emails of discourse developers (will be used to initialize your instance):


SMTP Server address:

DISCOURSE_SMTP_ENABLE_START_TLS=false           # (optional, default true)

Postgres database connection:


How to update to newer discourse version

This probably should be more or less painless, but can't be automated.
I'm unsure how many resources we'll be able to commit to keeping this up to date
(PR's welcome!).

So to update you'll need to:

  1. Clone current version of: discourse_docker.
  2. Check if templates in discourse_composite/*/templates have been changes,
    if they have been changed update them. See description to what have been changed,
    at the time of writing only migration tasks were commented out.
  3. Test it.

Configuration and extensions

If you want to run some extra customisations like:

  • Set admin user
  • Enable SSO

Just drop *.rb file to /discourse-composite/run/ruby-scripts
(in the container). These files will be executed after database migrations.

Configure sso

To configure SSO set following enviornment variables:

  • COMPOSE_DISCOURSE_SSO_SECRET --- contains SSO secret
  • COMPOSE_DISCOURSE_SSO_PROVIDER_URL --- contains SSO provider url

NOTE: Enabling of SSO is non-reversible.

Configure admin user

To configure admin user set following enviornment variables:

  • COMPOSE_DISCOURSE_ADMIN_EMAIL --- contains admin email
  • COMPOSE_DISCOURSE_ADMIN_PASSWORD --- contains admin password
  • COMPOSE_DISCOURSE_ADMIN_USERNAME --- contains admin username

NOTE: While after each run admin with this email and password
will exist, previously created admins won't be deleted. If user
with such password

Misc settings

You can also set following "misc" settings:

  • DJANGO_COMPOSE_INVITE_ONLY Boolean setting, controls invite_only property.
  • DJANGO_COMPOSE_LOGIN_REQUIRED Boolean setting, controls invite_only property.
  • DJANGO_COMPOSE_BOOTSTRAP_MODE Boolean setting, controls bootstrap mode.

Boolean settings can should have value f for false or t for true.

  • DJANGO_COMPOSE_TITLE String site title.
  • DJANGO_COMPOSE_SITE_DESCRIPTION String site description

  • DJANGO_COMPOSE_CONTACT_EMAIL String contact email

  • DJANGO_COMPOSE_CONTACT_URL String contact url


  • DJANGO_COMPOSE_COMPANY_FULL_NAME String company full name
  • DJANGO_COMPOSE_COMPANY_DOMAIN String company domain


  1. Right now assets are generated inside discourse_migrate and not during
    image creation, asset creation during image build is not easy as Rails insists
    that database needs to be present for asset generation I'm not sure this is Rails
    fault, or Discourse just needs database for this.
  2. Enable and test letsencrypt template.
Docker Pull Command
Source Repository