Discourse - tips and tricks

html
css
discourse-app
customization
blogging
knowledge-base
quick-tip
docker
latex
Tags: #<Tag:0x00007f389ea56ee0> #<Tag:0x00007f389ea56d78> #<Tag:0x00007f389ea56c10> #<Tag:0x00007f389ea56aa8> #<Tag:0x00007f389ea56940> #<Tag:0x00007f389ea56800> #<Tag:0x00007f389ea566c0> #<Tag:0x00007f389ea56580> #<Tag:0x00007f389ea56440>

#1

Discourse > Drupal > WordPress > Git blogs

##Summary:

This is my blog. There are many like it. But this one it mine.

There are many fantastic web apps nowadays. WordPress is definitely one of them. It’s used by a lot of people, and there are good reasons for that.

But as an InfoSec blogger I cannot host a Wordpress blog. The development culture around Wordpress seems to be a security nightmare. The Wordpress security issues don’t just tangent the plugins. It also tangents their PHP source code.

I used Drupal as an alternative. Sure, it has occasional security issues as well. But most of them are for authenticated users. My problem with Drupal is, that the editing is too complex. When I activated some plugins, I had to reconfigure Display Filters. That affected how articles were displayed entirely.

I tried static site generators, like Pelican. There are many tools like this, and these minimal solutions have their users. Their workflows work well with Git, and that’s how most people set them up. I didn’t like the experience. I like to rely on spell-checking and WYSIWYG, seamless editing and reading.

Something better

I was looking for something… better. When I read that the developers of StackOverflow have developed a discussion platform, I became interested.

Discourse is the 100% open source discussion platform built for the next decade of the Internet. Use it as a mailing list, discussion forum, long-form chat room, and more!

Fair enough… OpenSource. Modern. Can be all kinds of things.

We’re on a ten year mission to improve the Internet with free, open-source discussion software that raises the level of discourse for the entire world. We’ve come a long way, but it’s still a work in progress.

You know what, that’s exactly what InfoSec needs. So I am using that.

My requirements here, my features there

I use Discourse as a Blog, and as a Wiki knowledge base.

  • I can host it in a Docker container on my dedicated root server. The setup is a one-liner.
    • Portable. Small. Segregated.
    • I have it in a KVM guest, with Docker.
    • It’s behind an Apache Reverse Proxy, and Discourse supports this. Some apps don’t.
    • the Nginx, Redis, PostgreSQL can be containerized. One or multiple.
  • the WYSIWYG editor is great for my random style of blogging
    • I brain-dump my ideas into short internal posts, mature them, and at some point publish.
    • the editor doesn’t lose posts or revisions.
      • even if the internet connection gets disrupted, which can easily happen when your are mobile, there is a remaining draft. It saves early, it saves often. For me.
    • source code syntax highlighting is great, and supported out of the box.
  • it supports mathematical expressions. I have a couple of upcoming posts on Machine Learning. The rendering can take some extra seconds.

\begin{equation}
\int \mathrm{d}{x} \sin(x) = -\cos(x) + \mathrm{\text{h.c.}} \tag{A simple identity}
\end{equation}

  • I like that they use Ember.js. The sites feels fast and loads seamlessly; into mobile as well. There are even update notifications, due to the API driven design.
  • I use Discourse since over 1 year. Very little problems. Nearly no downtime.
    • it’s not in my way. Updates work. It’s actively developed.

Discourse Configuration tricks

Generally I chose a simple typography and a grey newspaper-style color. That’s easy on the eyes and creates a natural reading experience.

OAuth Single Sign On

I configured Discourse to support Facebook, Twitter and GitHub. This means

  • I can use 2-Factor authentication
  • no local accounts, privileges get delegated in OAuth
  • I don’t rely on a single provider
  • works on mobile as well

At some point I will open up the registration and I don’t expect much Spam. I doubt that Spammers will make Twitter accounts to spam here, and fight through the Troll detection of Discourse.

Discourse customization - design matters

Discourse can easily be customized, even without Ruby or JavaScript.

I wanted:

  • a sidebar on the left with my focus topics
  • a column on the right, at the start page, for the disclaimer and some introduction
  • a filtered set of posts on the start page (directly supported now)

That’s all doable.

Header links on the top

I found that somewhere in the official Discourse forums:

nav ul { 
    text-align: center;
}

nav ul li { 
    display: inline-block;
}

a:hover {
    transition: color 150ms ease-out 0s;
    color: rgb(44, 174, 195);
}

a {
    transition: color 150ms ease-out 0s;
    color: rgb(35, 137, 153);
}

nav#bar {
    width: 100%;
    height: 48px;
    background: #1b1f20;
    top: 20;
    z-index: 1;
}

nav#bar a.nav-link {
    color: rgb(255, 255, 255);
    text-decoration: none;
    text-align: center;
    font-family: 'Montserrat', sans-serif; 
    line-height: 48px;
    min-width: 90px;
    font-size: 16px;
    float: left;
}

nav#bar a.red.selected {
  color: #d13332;
  border-color: #d13332 !important; }

nav#bar a.red:hover {
  color: #d13332;
  text-shadow: 0px 0px 5px #d13332; }

nav#bar a.orange.selected {
  color: #ea5932;
  border-color: #ea5932 !important; }

nav#bar a.orange:hover {
  color: #ea5932;
  text-shadow: 0px 0px 5px #ea5932; }

nav#bar a.yellow.selected {
  color: #fff9ae;
  border-color: #fff9ae !important; }

nav#bar a.yellow:hover {
  color: #fff9ae;
  text-shadow: 0px 0px 5px #fff9ae; }

nav#bar a.green.selected {
  color: #18b159;
  border-color: #18b159 !important; }

nav#bar a.green:hover {
  color: #18b159;
  text-shadow: 0px 0px 5px #18b159; }

nav#bar a.blue.selected {
  color: #00aeef;
  border-color: #00aeef !important; }

nav#bar a.blue:hover {
  color: #00aeef;
  text-shadow: 0px 0px 5px #00aeef; }

nav#bar a.grey.selected {
  color: #aaa;
  border-color: #aaa !important; }

nav#bar a.grey:hover {
  color: #aaa;
  text-shadow: 0px 0px 5px #aaa; }

nav#bar a.nav-link.selected {
  line-height: 42px;
  border-top: 3px solid #0b0d0d;
  background-color: #0b0d0d;
  height: 45px;
}

And the HTML:

<nav id="bar">
    <ul>
        <li><a class="nav-link blue" href="https://blog.because-security.com/">Home</a></li>
              ...
    </ul>
</nav>

Sidebar on the left - for the wiki tags

This is a hack by a contributor to the official forums.

Here’s the CSS code for that:

   body[class*="wiki"] .lnav-box{
        padding:0;
        display: block !important;
        position: absolute;
        overflow: hidden; 
        padding-right: 1em;    
        display: table;
        top:0;
        left:0;
        width:160px;
        min-width:100px;
        min-height:100%;
        z-index: 2;
    }

   body[class*="blog.posts"] .lnav-box{
        padding:0;
        display: block !important;
        position: absolute;
        top:0;
        left:0;
        width:160px;
        min-width:100px;
        min-height:100%;
        z-index: 2;
    }


   body[class*="category-blog"] .lnav-box{
        padding:0;
        display: block !important;
        position: absolute;
        top:0;
        left:0;
        width:160px;
        min-width:100px;
        min-height:100%;
        z-index: 2;
    }

body[class*="wiki"] .topic-meta-data,
body[class*="wiki"] .topic-avatar{
    display:none;
}
 
body[class*="category-blog"] .topic-meta-data,
body[class*="category-blog"] .topic-avatar{
    display:none;
}

body[class*="category-blog"] .list-container,
body[class*="category-blog"] #topic-title,
body[class*="category-blog"] .container.posts, 
body[class*="category-blog"] .list-controls {
    margin-left: 165px;
}
body[class*="category-blog"] .sidebar {
    display: none;
    visibility: hidden;
}


body[class*="wiki"] .list-container,
body[class*="wiki"] #topic-title,
body[class*="wiki"] .container.posts,
body[class*="wiki"] .list-controls {
    margin-left: 165px;
}
body[class*="wiki"] .sidebar {
    display: none;
    visibility: hidden;
}
  
 
 
 .lnav-menu{
        list-style:none;
        margin: 0;
        padding: 0;
        border: 0;
    }
    
    .lnav-menu .navhead{
       font-weight:400;
       background-color: #efefef;
    }
    
    .lnav-menu > li{
        width:100%;
        border-left: 5px solid #ccc;
        border-bottom: 1pt solid #efefef;
        float: left;
        min-height: 1px;
        line-height: 1em;
        vertical-align: middle;
    }
    
    .lnav-menu > li:first-child{
        padding-top:20px;
    }
    
    .lnav-menu > li:hover{
        border-left: 5px solid #4c7fff;
        background-color: #efefef;
    }
    
    .lnav-menu > li > a{
        color: #808080;
        display: block;
        padding: 7px 20px;
    }
    
    .lnav-vspacer{
        width:165px;
        height:60px;
        background-color: #efefef;
    }

And the HTML (Footer):

<div class="lnav-box" style="display:none;">
    <div class="lnav-vspacer"></div>
    <ul class="lnav-menu">
        <li class="navhead"><a href="/"><strong>Because Security</strong></a></li>
        <li class="navhead"><a href="/tags/malware-analysis">Malware &amp; Forensics</a></li>
          ...
    </ul>
</div>

It works well, unless you use a plugin which adds elements on the left with a dynamic size. That why the .sidebar is hidden here. This element is from a plugin.

A better coding font for discourse

You can override the coding font via CSS @font-face and load just any font, because modern browsers support this:

@font-face {
    font-family: "PxPlus VGA Square Px";
    src: url("/uploads/default/original/1X/698e427dae31f4bd85986e3f2beb0bbfff502e9f.ttf") format('truetype');
}

code, pre {
    font-family: "PxPlus VGA Square Px" !important;
    font-size: 20px !important;
}

This CSS is a bit hacky, but does the trick for code and pre environments,

I am loading a special font here. A pixel-perfect reproduction of a raster front of the IBM PC era. My first computer was an old DOS PC.

Discourse Plugins

Sidebar plugin - for the introduction and disclaimer

At the moment Sidebar Blocks is the way to go.
This is where the .sidebar comes from.

Configure MathJax - Discourse can do LaTeX

MathJax is a larger JS project. It allows me to use LaTeX to render math.

I use the new Cloudflare CDN link. Using Cloudflare with Discourse is supported.

I supply the following config.js :

MathJax.Hub.Config({
  displayAlign: "left",
  displayIndent: "2em",
  webFont: "Neo-Euler"
})
  • equations get aligned left
  • I shift equations by about 0,8 cm which is 2 em
  • I use the Euler front in LaTeX

The config looks like this, based on the documentation:

TeX-AMS-MML_HTMLorMML,https://blog.because-security.com/uploads/default/original/1X/4b4e76ddb9b200f67a65f6e48e0c97d8f7208c93.js

Workaround and fixes

This is what went wrong, and how I fixed it.

Images got deleted...

They didn’t get deleted. Some routine decided that I wasn’t using them, and put them up for deletion. Solution was in the forums.

# copy the "deleted" images from their to-be-deleted staging area
cd /var/discourse
./launcher enter app
rake uploads:recover_from_tombstone

# rebake to see that it doesn't happen again
rake posts:rebake

Docker container got stuck

I had it once that the Docker container got stuck.

[email protected]:~$ sudo docker images
[sudo] password for marius: 
REPOSITORY             TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
local_discourse/app    latest              de874b66a2ac        12 days ago         2.564 GB

docker ps revealed that there were 2 running containers. I’d say basic Docker skills are required every now and then to run Discourse.

Summary

Discourse as a blog and wiki is a win.

Version history

06.05.2017 - beta release, brain-dump style
04.07.2017 - added font override


Web typography - just a little bit longer