Creating & Managing a Discourse Instance

This is the guide that Bevry uses to maintain its discourse instances, including this one.

Creation

Create a private github repo which only file is:

var/discourse/containers/app.yml

Which contains the following:

## https://github.com/discourse/discourse_docker/blob/master/samples/standalone.yml
## /var/discourse/launcher rebuild app

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
  - "templates/web.ssl.template.yml"  # ENABLES SSL
  - "templates/web.letsencrypt.ssl.template.yml"  # ENABLES SSL

expose:
  - "80:80"
  - "443:443"  # ENABLES SSL

params:
  db_default_text_search_config: "pg_catalog.english"

env:
  LANG: en_US.UTF-8
  
  ## List of comma delimited emails that will be made admin and developer
  ## on initial signup example '[email protected],[email protected]'
  DISCOURSE_DEVELOPER_EMAILS: "your.email"

  ## The domain name this Discourse instance will respond to
  DISCOURSE_HOSTNAME: "discourse.your.domain"

  ## If you added the Lets Encrypt template, uncomment below to get a free SSL certificate
  LETSENCRYPT_ACCOUNT_EMAIL: "[email protected]"  # ENABLES SSL

  ## The mailserver this Discourse instance will use
  DISCOURSE_SMTP_ADDRESS: "smtp.mailgun.org"
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: "[email protected]"
  DISCOURSE_SMTP_PASSWORD: "your.mailgun.password"

## Any custom commands to run after building
run:
  - exec: rails r "SiteSetting.notification_email='[email protected]'"

## These containers are stateless, all data is stored in /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## Plugins go here
## see https://meta.discourse.org/t/19157 for details
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - mkdir -p plugins
          - git clone https://github.com/discourse/discourse-solved.git
          - git clone https://github.com/discourse/discourse-github.git

This should be the only file in the repository, as it will be cloned out to the root directory of the droplet.

Management

Login to the system with:

ssh [email protected]

Or if you are using the secret tool, it would be something like this:

secret map DISCOURSE_SSH_KEY personal 'SSH Keys' 'bevry-scaleway-2017'
secret get DISCOURSE_SSH_KEY 
ssh discourse

Once logged into the machine, configure the variables we will use for the subsequent installation or update commands:

# The email that will access the repository
DEMAIL="[email protected]"

# The name that will access the repository
DNAME="Discourse Bot"   

# The name of the SSH key file we will create
DSSH="discourse.your.domain"

# The repository's git access url
DGIT="[email protected]:org/repo.git"

For Bevry, it is the following:

DEMAIL="[email protected]"
DNAME="Bevry Discourse Server"
DSSH="root-discuss.bevry.me-github"
DGIT="[email protected]:bevry/discourse.git"

Installation

Once logged into the machine, you can perform the initial installation via:

# Set root password if there isn't already one
passwd

# Login as sudo
sudo -s

# Update System
apt-get update
apt-get dist-upgrade

# Configure Automatic Security Updates
dpkg-reconfigure -plow unattended-upgrades

# Install Docker (if needed only)
wget -qO- https://get.docker.com/ | sh

# Prepare System
apt-get install git

# Install Discourse Docker Setup
mkdir -p /var/discourse
git clone https://github.com/discourse/discourse_docker.git /var/discourse
cd /var/discourse
git pull origin master

# Setup Git
git config --global user.email "$DEMAIL"
git config --global user.name "$DNAME"

# Create SSH Key for Git
ssh-keygen -t rsa -b 4096 -C "$DSSH" -f ~/.ssh/$DSSH
chmod 600 ~/.ssh/$DSSH
chmod 600 ~/.ssh/$DSSH.pub
cat ~/.ssh/$DSSH.pub
# Use the above output as the repository's deploy key:
# https://developer.github.com/v3/guides/managing-deploy-keys/#deploy-keys

# Add SSH Key to Git
eval "$(ssh-agent -s)" && ssh-add ~/.ssh/$DSSH
 
# Setup Configuration
cd /
git init
git remote add origin "$DGIT"
git fetch origin
git checkout master
git pull origin master

# Setup Discourse & Rebuild Discourse
# https://github.com/discourse/discourse/blob/master/docs/INSTALL-cloud.md
/var/discourse/launcher bootstrap app && /var/discourse/launcher rebuild app

Be sure to do any final email configurations:

And if emails aren’t sending:

And to restore a backup:

Update

Once logged into the machine, you can perform regular maintenance via:

# Add SSH Key to Git
eval "$(ssh-agent -s)" && ssh-add ~/.ssh/$DSSH

# Update Server Configuration
cd /
git fetch origin
git pull origin "$(git rev-parse --abbrev-ref HEAD)"

# Update Discourse Docker Setup
cd /var/discourse
git pull origin master

# Rebuild Discourse
/var/discourse/launcher rebuild app

If you need to update docker or the system, just create a new setup, and import your backup. As upgrading the existing machine often results in a failure.

SSL

SSL is now handled automatically.

Previously

Using Lets Encrypt

LETS_DOMAIN=discuss.your.domain
[email protected]

# Stop our app
/var/discourse/launcher stop app

# Get the latest letsencrypt software
rm -Rf ~/letsencrypt
git clone https://github.com/letsencrypt/letsencrypt ~/letsencrypt

# DISABLE CLOUDFLARE NOW
# If /etc/letsencrypt exists, renew existing certificate
~/letsencrypt/letsencrypt-auto renew
# if it doesn't, create new certificate
~/letsencrypt/letsencrypt-auto certonly --rsa-key-size 4096 --standalone -d $LETS_DOMAIN --agree-tos --email $LETS_EMAIL
# RE-ENABLE CLOUDFLARE NOW

# Remove letsencrypt app dir, as no longer needed, data is stored in /etc/letsencrypt which we keep
rm -Rf ~/letsencrypt

# Remove old discourse certs, and insert new letsencrypt certs
rm /var/discourse/shared/standalone/ssl/*
cp /etc/letsencrypt/live/$LETS_DOMAIN/fullchain.pem /var/discourse/shared/standalone/ssl/ssl.crt
cp /etc/letsencrypt/live/$LETS_DOMAIN/privkey.pem /var/discourse/shared/standalone/ssl/ssl.key

# Add letsencrypt data for renewals, and the updated discourse certs, and commit and push them
git add /etc/letsencrypt /var/discourse/shared/standalone/ssl -f
git commit -m "lets encrypt"
git push origin master

# Rebuild the site
/var/discourse/launcher rebuild app

Using Cloudflare

DO NOT USE THIS METHOD. The Cloudflare certificate is not trusted, Safari and Google Chrome will reject it.

  1. Follow the prompts to generate a Origin Certificate for your discourse hostname.
  2. Put the certificate in /var/discourse/shared/standalone/ssl/ssl.crt
  3. Put the key in /var/discourse/shared/standalone/ssl/ssl.key