Discourse: Difference between revisions

From Open Source Ecology
Jump to navigation Jump to search
No edit summary
 
(320 intermediate revisions by 2 users not shown)
Line 1: Line 1:
This article describes OSE's use of the Discourse software.
For a detailed guide to updating our Discourse server, see [[Discourse/Updating]].
For a detailed guide on how we installed Discourse in 2020 on our CentOS 7 server, see [[Discourse/Install]].
=Official Discourse Documentation=
Discourse doesn't have any official documentation outside of their [https://docs.discourse.org/ API documentation].
It appears that this is intentional to make Discourse admins' lives difficult as a way to increase revenue. See [[#Strategic Open Source]] for more info.
=TODO=
List of outstanding tasks before attempting to install Discourse on production:
# <s>iptables rules that prevent the discourse app from being able to initiate calls to the Internet (it should *only* be able to *respond* to queries) as we do for our apache backend by blocking non-established traffic from going through the OUTPUT table by the apache uid</s>
## <s>test an upgrade after this is done as well.</s>
# <s>OWASP CORS rules to prevent sqli/XSS/etc attacks as we do in apache</s>
## <s>update the install-nginx script so that it compiles nginx with mod_security (and probably downloads the OWASP CRS as well) https://github.com/discourse/discourse_docker/blob/416467f6ead98f82342e8a926dc6e06f36dfbd56/image/base/install-nginx</s>
## <s>add a new templates/web.modsecurity.yml file that updates the /etc/nginx/conf.d/discourse.conf file to enable mod_security (and add some blacklisted rules as-needed), similar to the existing web.socketed.template.yml file https://github.com/discourse/discourse_docker/blob/416467f6ead98f82342e8a926dc6e06f36dfbd56/templates/web.socketed.template.yml</s>
# <s>iptables on docker container instead of total internet blocking so the docker container can actually update its own OS packages?</s>
## <s>TODO: document update to `launcher` script's run_start() function's final `docker run` command to add the argument '--add-cap=NET_ADMIN' so the docker container root's user has permission to modify iptables rules.</s>
# <s>Fix unattended-upgrade https://meta.discourse.org/t/does-discourse-container-use-unattended-upgrades/136296</s>
# <s>Test/document Discourse upgrade process</s>
# <s>Test/document backup & restore process</s>
# <s>Stable cron job for docker image cleanup to prevent disk-fill</s>
# Varnish cache https://meta.discourse.org/t/discourse-purge-cache-method-on-content-changes/132917
# Minimum/hardened permissions of the /var/discourse dir https://meta.discourse.org/t/minimum-hardened-file-permissions/148974
=Useful Commands=
=Useful Commands=


Line 4: Line 34:


<pre>
<pre>
# get docker info
docker info
# list running docker containers
docker ps
# list all docker containers
docker ps -a
# list all docker images
docker image list
# get docker disk usage (including reclaimable space)
docker system df
# get a shell on the Discourse's docker container
# get a shell on the Discourse's docker container
/var/discourse/launcher enter app
/var/discourse/launcher enter discourse_ose


# access the rails console (exec from inside the docker container)
# access the rails console (exec from inside the docker container)
rails c
rails c
# restart a process from within the docker container (ie: cron, nginx, postgres, redis, rsyslog, unicorn)
sv stop nginx && sv start nginx
# stop/start/restart the Discourse container
/var/discourse/launcher stop discourse_ose
/var/discourse/launcher start discourse_ose
/var/discourse/launcher restart discourse_ose
# "rebuild" Discourse app (ie: for upgrades or changes to "templates/" yaml files)
# Takes 5-20 minutes to run, and it may break. Test on staging first.
/var/discourse/launcher rebuild discourse_ose
# "enter" a docker image to inspect/debug/troubleshoot the image itself
[root@osestaging1 ~]# docker image ls
REPOSITORY                      TAG                IMAGE ID            CREATED            SIZE
local_discourse/discourse_ose  latest              b4d3feecf9e1        5 days ago          2.62GB
discourse_ose                  latest              2ea22070a06d        2 weeks ago        2.33GB
[root@osestaging1 ~]# docker run --rm -it --entrypoint /bin/bash 2ea22070a06d
root@00841db59cd7:/#
# get capabilities of discourse docker container
id=`docker inspect --format="{{.Id}}" discourse_ose`
grep -E 'CapAdd|CapDrop|Capabilities' /var/lib/docker/containers/$id/hostconfig.json
# tail "outer" nginx logs
tail -c0 -f /var/log/nginx/*log /var/log/nginx/discourse.opensourceecology.org/*log
# monitor varnish for discourse-specific queries only
varnishlog -q "ReqHeader eq 'Host: discourse.opensourceecology.org'"
# tail "inner" discourse logs (run this on the docker host, not inside the container)
tail -c0 -f /var/discourse/shared/standalone/log/rails/*log /var/discourse/shared/standalone/log/var-log/redis/current /var/discourse/shared/standalone/log/var-log/postgres/current /var/discourse/shared/standalone/log/var-log/nginx/*log
</pre>
</pre>


Line 21: Line 99:
<pre>
<pre>
/var/discourse/
/var/discourse/
/var/discourse/launcher
/var/discourse/containers/discourse_ose.yml
/var/discourse/templates/
/var/discourse/templates/templates/iptables.template.yml
/var/discourse/templates/templates/postgres.template.yml
/var/discourse/templates/templates/redis.template.yml
/var/discourse/templates/templates/web.template.yml
/var/discourse/templates/templates/web.ratelimited.template.yml
/var/discourse/templates/templates/web.socketed.template.yml
/var/discourse/templates/templates/web.modsecurity.template.yml
/var/discourse/image/base/
/var/discourse/image/base/Dockerfile
/var/discourse/image/base/install-nginx
</pre>
And the following logs may be helpful:
<pre>
/var/discourse/shared/standalone/log/rails/production.log
/var/discourse/shared/standalone/log/rails/production.log
/var/discourse/shared/standalone/log/rails/unicorn.stderr.log
/var/discourse/shared/standalone/log/rails/unicorn.stderr.log
Line 28: Line 124:
</pre>
</pre>


And the following files & directories on the Docker Container:
And the following files & directories inside the Discourse Docker Container:


<pre>
<pre>
Line 36: Line 132:
</pre>
</pre>


=2019-11 Install Guide=
==Web Server Issues==
 
This section will cover troubleshooting issues with Nginx, Varnish, etc.


In 2019-11, I ([[User:Maltfield|Michael Altfield]]) tested an install of Discourse on the [[OSE Staging Server]]. I documented the install steps here so they could be exactly reproduced on production
Below will be just a list of error messages posted here primarily for the purpose of catching search queries on this wiki and directing them to this text:


==Install Prereqs==
To troubleshoot Discourse web server issues, this is a reminder: remember that there are two distinct nginx servers:


First we have to install docker. The version in the yum repos (1.13.1) was too old to be supported by Discourse (which states it requires a minimum of 17.03.1).
# nginx running on the server (docker host)
# nginx running _inside_ the discourse container running on the server


Note that the install procedure recommended by Docker and Discourse for Docker is a curl piped to shell. This should never, ever, ever be done. The safe procedure is to manually add the gpg key and repo to the server as get.docker.org script should do -- assuming it were not modified in transit. Note that Docker does *not* cryptographically sign their install script in any way, and it therefore cannot be safely validated.
Don't forget to troubleshoot both!


<pre>
<pre>
# first, install the (ASCII-armored) docker gpg key to /etc/pki/rpm-gpg/docker.gpg
user@ose:~$ curl -kI https://discourse.opensourceecology.org/
cp docker.gpg /etc/pki/rpm-gpg/docker.gpg
HTTP/1.1 502 Bad Gateway
chown root:root /etc/pki/rpm-gpg/docker.gpg
Server: nginx
chmod 0644 /etc/pki/rpm-gpg/docker.gpg
Date: Mon, 30 Mar 2020 09:03:23 GMT
Content-Type: text/html
Content-Length: 150
Connection: keep-alive
 
user@ose:~$
</pre>
 
===502 Bad Gateway===
 
Relevant error messages:


# and install the repo
* cURL
cat << EOF > /etc/yum.repos.d/docker-ce.repo
[docker-ce-stable]
name=Docker CE Stable - $basearch
baseurl=https://download.docker.com/linux/centos/7/$basearch/stable
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/docker.gpg
EOF


# finally, install docker from the repos
<pre>
yum install docker-ce
Failed to connect to discourse.opensourceecology.org port 80: Connection refused
</pre>
</pre>


==Install Discourse==
===Unable to Connect===
 
Relevant error messages:


From the [https://github.com/discourse/discourse/blob/master/docs/INSTALL-cloud.md Disourse Install Guide], checkout the github repo as root to /var/discourse. You'll want to validate that this wasn't modified in transit; there are no cryptographic signatures to validate authenticity of the repo's contents here. A huge failing on Discourse's part (but, again, Discourse's sec is rotten from its foundation in Docker; see above).
* cURL


<pre>
<pre>
sudo -s
Failed to connect to discourse.opensourceecology.org port 80: Connection refused
git clone https://github.com/discourse/discourse_docker.git /var/discourse
cd /var/discourse
</pre>
</pre>


The Discourse install script doesn't support the very simple config of an smtp server running on localhost:25 without auth. That is to say, Discourse doesn't support the default postfix config for RHEL/CentOS and most web servers on the net..
* Firefox


We have to manually edit the /var/discourse/containers/app.yml. I couldn't find any Discourse documentation for these DISCOURSE_SMTP_* variables, but I did have success with these values:
<pre>
Unable to connect


Note that 'localhost' resolves to the IP Address of the container created by docker when referenced from within the context of Discourse, but our smtp server is running on the host server. Therefore, we cannot use 'localhost' for the DISCOURSE_SMTP_ADDRESS. Instead, we use the IP Address of the host server's docker0 interface. In this case, it's 172.17.0.1, and that can be verified via the output of `ip address show dev docker0` run on the host where docker is installed (in this case, osestaging1).
Firefox can’t establish a connection to the server at discourse.opensourceecology.org.


TODO: change the name of the Discourse docker app from 'app' to something more sane, such as 'discourse_ose'
    The site could be temporarily unavailable or too busy. Try again in a few moments.
    If you are unable to load any pages, check your computer’s network connection.
    If your computer or network is protected by a firewall or proxy, make sure that Firefox is permitted to access the Web.
</pre>


TODO: make these sed commands to update the 'container/discourse_ose.yml' file in an automated, robust, and idempotent manner
* Chromium


<pre>
<pre>
  DISCOURSE_SMTP_ADDRESS: 172.17.0.1 # this is the IP Address of the host server on the docker0 interface
This site can’t be reached discourse.opensourceecology.org refused to connect.
  DISCOURSE_SMTP_PORT: 25
Try:
  DISCOURSE_SMTP_AUTHENTICATION: none
 
  DISCOURSE_SMTP_OPENSSL_VERIFY_MODE: none
Checking the connection
  DISCOURSE_SMTP_ENABLE_START_TLS: false
Checking the proxy and the firewall
ERR_CONNECTION_REFUSED
</pre>
</pre>


Also note that I had to update the postfix configuration (/etc/postfix/main.cf) to bind on the docker0 interface, change the `mynetworks_style`, and add the docker0 subnet to the 'mynetworks' list to auth the Discourse docker client to be able to send mail through the smtp server.
This is because literally nothing is responding on the ip address and port.
 
==`git pull` fail==
 
The built-in Discourse '<code>launcher</code>' script may try to do a `<code>git pull</code>` that may fail when it tries to update a file that we've modified in OSE's config. For example:


<pre>
<pre>
root@osestaging1 discourse]# grep -E 'mynetworks|interfaces' /etc/postfix/main.cf
[root@osestaging1 discourse]# /var/discourse/launcher rebuild discourse_ose
# The inet_interfaces parameter specifies the network interface
Ensuring launcher is up to date
# the software claims all active interfaces on the machine. The
Fetching origin
# See also the proxy_interfaces parameter, for network addresses that
remote: Enumerating objects: 6, done.
#inet_interfaces = all
remote: Counting objects: 100% (6/6), done.
#inet_interfaces = $myhostname
remote: Compressing objects: 100% (4/4), done.
#inet_interfaces = $myhostname, localhost
remote: Total 6 (delta 2), reused 2 (delta 2), pack-reused 0
#inet_interfaces = localhost
Unpacking objects: 100% (6/6), done.
inet_interfaces = 127.0.0.1, 172.17.0.1
From https://github.com/discourse/discourse_docker
# The proxy_interfaces parameter specifies the network interface
  bb9a173..b0c92ba  master    -> origin/master
# the address list specified with the inet_interfaces parameter.
Updating Launcher
#proxy_interfaces =
Updating bb9a173..b0c92ba
#proxy_interfaces = 1.2.3.4
error: Your local changes to the following files would be overwritten by merge:
# receives mail on (see the inet_interfaces parameter).
launcher
# to $mydestination, $inet_interfaces or $proxy_interfaces.
Please, commit your changes or stash them before you can merge.
# ${proxy,inet}_interfaces, while $local_recipient_maps is non-empty
Aborting
# The mynetworks parameter specifies the list of "trusted" SMTP
failed to update
# By default (mynetworks_style = subnet), Postfix "trusts" SMTP
Ensuring launcher is up to date
# On Linux, this does works correctly only with interfaces specified
Fetching origin
# Specify "mynetworks_style = class" when Postfix should "trust" SMTP
Updating Launcher
# mynetworks list by hand, as described below.
Updating bb9a173..b0c92ba
# Specify "mynetworks_style = host" when Postfix should "trust"
error: Your local changes to the following files would be overwritten by merge:
#mynetworks_style = class
launcher
#mynetworks_style = subnet
Please, commit your changes or stash them before you can merge.
#mynetworks_style = host
Aborting
# Alternatively, you can specify the mynetworks list by hand, in
failed to update
# which case Postfix ignores the mynetworks_style setting.
Ensuring launcher is up to date
#mynetworks = 168.100.189.0/28, 127.0.0.0/8
Fetching origin
#mynetworks = $config_directory/mynetworks
Updating Launcher
#mynetworks = hash:/etc/postfix/network_table
Updating bb9a173..b0c92ba
mynetworks = 127.0.0.0/8, 172.17.0.0/16
...
# - from "trusted" clients (IP address matches $mynetworks) to any destination,
</pre>
# - destinations that match $inet_interfaces or $proxy_interfaces,
 
# unknown@[$inet_interfaces] or unknown@[$proxy_interfaces] is returned
The above output was an endless loop complaining about the conflict between the file '<code>launcher</code>' in the '<code>/var/discourse/</code>' directory. In order to fix the conflict, you must merge the changes--which may be a non-trivial process.
 
The easiest action is to just move the locally modified files out of the way, do a clean `<code>git pull</code>`, make note a diff of the changes, and re-apply the local changes by re-visiting the relevant section of install guide. For detailed instructions on this process, see the "Updating Discourse" [[#Step 3: Update git]] section.
 
==Removal In Progress==
 
You may get an error when attempting to rebuild the Discourse docker container because an old docker container is stuck in a "Removal In Progress" state. For example:
 
<pre>
[root@osestaging1 discourse]# time /var/discourse/launcher rebuild discourse_ose
...
169:M 23 Mar 2020 10:19:33.054 # Redis is now ready to exit, bye bye...
2020-03-23 10:19:33.127 UTC [52] LOG:  database system is shut down
sha256:6e6c81a3529175c1aa8e3391599499704f3abb9833ca3e943cf1b5443da4f47c
fbf51479947c537d2247bf38bd0ca2f1cb96257dbbf86e93038e6a19f2bab5d6
Removing old container
+ /bin/docker rm discourse_ose
Error response from daemon: container 12bb1e40517bb4893ff428096fa204f145c75d64be6a269cbe3093543373c6a8: driver "overlay2" failed to remove root filesystem: unlinkat /var/lib/docker/overlay2/99f609ae22d509152fd6db0120ba111c4d892b153d41d2e720790c864d5d678a/merged: device or resource busy
 
starting up existing container
+ /bin/docker start discourse_ose
Error response from daemon: container is marked for removal and cannot be started
Error: failed to start containers: discourse_ose
 
real    8m39.585s
user    0m1.764s
sys    0m1.684s
[root@osestaging1 discourse]#  
[root@osestaging1 discourse]#  
</pre>
</pre>


Restarting docker _may_ help you to manually delete the docker container. Or not


TODO: how to resolve the errors (bug?) that the username & password is not defined on first install? Try just running `./launcher bootstrap` instead of the `docker-setup` script that will fail.
<pre>
[root@osestaging1 containers]# docker ps -a
CONTAINER ID        IMAGE              COMMAND            CREATED            STATUS                PORTS              NAMES
12bb1e40517b        4d92ff0b76a7        "/sbin/boot"        6 days ago          Removal In Progress                      discourse_ose
[root@osestaging1 containers]# systemctl restart docker
[root@osestaging1 containers]# docker ps -a
CONTAINER ID        IMAGE              COMMAND            CREATED            STATUS              PORTS              NAMES
12bb1e40517b        4d92ff0b76a7        "/sbin/boot"        6 days ago          Dead                                    discourse_ose
[root@osestaging1 containers]# docker rm 12bb1e40517b
Error response from daemon: container 12bb1e40517bb4893ff428096fa204f145c75d64be6a269cbe3093543373c6a8: driver "overlay2" failed to remove root filesystem: unlinkat /var/lib/docker/overlay2/99f609ae22d509152fd6db0120ba111c4d892b153d41d2e720790c864d5d678a/merged: device or resource busy
[root@osestaging1 containers]# docker ps -a
CONTAINER ID        IMAGE              COMMAND            CREATED            STATUS                PORTS              NAMES
12bb1e40517b        4d92ff0b76a7        "/sbin/boot"        6 days ago          Removal In Progress                      discourse_ose
[root@osestaging1 containers]#
</pre>


Also, we already have nginx bound to port 443 as our ssl terminator, so the defaults in app.yml will fail. Instead, we add the 'web.socketed.template.yml' file, remove the 'expose' block, and we'll setup nginx to proxy connections to the resulting discourse unix socket file <ref>https://meta.discourse.org/t/running-other-websites-on-the-same-machine-as-discourse/17247</ref>
This issue coincides with the following error being written to the systemd journal log


Add this line to the "templates" block in /var/discourse/containers/app.yml.
<pre>
Mar 23 10:44:55 osestaging1 dockerd[16920]: time="2020-03-23T10:44:55.578997874Z" level=error msg="Error removing mounted layer 12bb1e40517bb4893ff428096fa204f145c75d64be6a269cbe3093543373c6a8: unlinkat /var/lib/docker/overlay2/99f609ae22d509152fd6db0120ba111c4d892b153d41d2e720790c864d5d678a/merged: device or resource busy"
Mar 23 10:44:55 osestaging1 dockerd[16920]: time="2020-03-23T10:44:55.579614708Z" level=error msg="Handler for DELETE /v1.40/containers/12bb1e40517b returned error: container 12bb1e40517bb4893ff428096fa204f145c75d64be6a269cbe3093543373c6a8: driver \"overlay2\" failed to remove root filesystem: unlinkat /var/lib/docker/overlay2/99f609ae22d509152fd6db0120ba111c4d892b153d41d2e720790c864d5d678a/merged: device or resource busy"
</pre>
A fix is to stop docker, force remove the problem container's directory, and start docker again. '''It would be wise to make a backup before attempting to proceed with this, just in-case you permanently delete the wrong container's directory!'''


<pre>
<pre>
   - "templates/web.socketed.template.yml"
[root@osestaging1 containers]# docker ps -a
CONTAINER ID        IMAGE              COMMAND            CREATED            STATUS                PORTS              NAMES
12bb1e40517b        4d92ff0b76a7        "/sbin/boot"        6 days ago          Removal In Progress                      discourse_ose
[root@osestaging1 containers]# docker ps -a --no-trunc
CONTAINER ID                                                      IMAGE                                                                    COMMAND            CREATED            STATUS                PORTS              NAMES
12bb1e40517bb4893ff428096fa204f145c75d64be6a269cbe3093543373c6a8  sha256:4d92ff0b76a725a5252fce8567e961fc01eebe68c2b34d1abc9c94cae041597e   "/sbin/boot"       6 days ago          Removal In Progress                      discourse_ose
[root@osestaging1 containers]# systemctl stop docker
[root@osestaging1 containers]# rm -rf /var/lib/docker/containers/12bb1e40517bb4893ff428096fa204f145c75d64be6a269cbe3093543373c6a8
[root@osestaging1 containers]# systemctl start docker
[root@osestaging1 containers]# docker ps -a
CONTAINER ID        IMAGE              COMMAND            CREATED            STATUS              PORTS              NAMES
[root@osestaging1 containers]#
</pre>
</pre>


And also comment-out the entire "expose" block and all its contents
=Installing Themes and Components=
 
By design, our [[Web_server_configuration|web servers]] can only <em>respond</em> to requests; they cannot initiate requests. And [[Discourse/Install#iptables|Discourse is no different]].
 
This means that the usual route of installing themes and components in Discourse via the WUI (<code>Admin -> Customize -> Themes -> Install -> Popular -> Install</code>) won't work.


<pre>
<pre>
#expose:
Error cloning git repository, access is denied or repository is not found
#  - "80:80"  # http
#  - "443:443" # https
</pre>
</pre>


TODO: try the 'discourse-setup' script now
==Step #1: Find repo==
 
To install a theme or theme component in our Discourse, first find its git repo. You can find many Discourse theme repos by listing all repos tagged with the topic '<code>discourse-theme</code>' or '<code>discourse-theme-component</code>' in the [https://github.com/discourse Discourse project on github].
 
* https://github.com/search?q=topic%3Adiscourse-theme+org%3Adiscourse+fork%3Atrue
* https://github.com/search?q=topic%3Adiscourse-theme-component+org%3Adiscourse+fork%3Atrue
 
==Step #2: Download zip==
 
[[File:202005_discourseInstallTheme1.jpg|left|600px]]
 
For example, here's a link to the github repo for the Discourse "Classic Theme"
 
* https://github.com/discourse/discourse-classic
 
From the theme's github repo page, download a zip of the repo by clicking <code>"Clone or download" -> "Download ZIP"</code>
 
<br style="clear:both;" />
==Step #3: Upload zip==
 
[[File:202005_discourseInstallTheme2.jpg|right|600px]]


==discourse.opensourcecology.org DNS==
Now, login to our Discourse site and navigate to <code>Admin -> Customize -> Themes</code>


Add 'discourse.opensourceecology.org' to the list of domain names defined for our VPN IP Address in /etc/hosts on the staging server.
Click <code>Install</code>


In production, this will mean actually adding A & AAAA DNS entries for 'discourse' to point to our production server.
<br style="clear:both;" />
[[File:202005_discourseInstallTheme3.jpg|left|600px]]


==Nginx Vhost Config==
In the JS modal "pop-up", choose <code>From your device</code>.


Create the following nginx vhost config file to proxy connections sent to 'discourse.opensourceecology.org' to the unix socket file created by Discourse.
Finally, click <code>Browse</code> and upload the <code>.zip</code> file downloaded above.


<pre>
<br style="clear:both;" />
cat << EOF > /etc/nginx/conf.d/discourse.opensourceecology.org.conf
################################################################################
# File:    discourse.opensourceecology.org.conf
# Version: 0.1
# Purpose: Internet-listening web server for truncating https, basic DOS
#          protection, and passing to varnish cache (varnish then passes to
#          apache)
# Author:  Michael Altfield <michael@opensourceecology.org>
# Created: 2019-11-07
# Updated: 2019-11-07
################################################################################


# this whole site is a subdomain, so the below block for redirecting a naked
=Looking Forward=
# domain does not apply here
#server {
#      # redirect the naked domain to 'www'
#      #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
#  #                  '$status $body_bytes_sent "$http_referer" '
#  #                  '"$http_user_agent" "$http_x_forwarded_for"';
#      #access_log /var/log/nginx/www.opensourceecology.org/access.log main;
#      #error_log /var/log/nginx/www.opensourceecology.org/error.log main;
#  include conf.d/secure.include;
#  include conf.d/ssl.opensourceecology.org.include;
#  listen 10.241.189.11:443;
#      server_name opensourceecology.org;
#      return 301 https://www.opensourceecology.org$uri;
#
#}


server {
This section will outline possible changes to be made to the Docker install/config in the future


access_log /var/log/nginx/discourse.opensourceecology.org/access.log main;
==Moving DBs outside docker==
error_log /var/log/nginx/discourse.opensourceecology.org/error.log;


  include conf.d/secure.include;
It's worthwhile to consider moving the redis and postgresql components of Discourse outside of the docker container <ref>https://meta.discourse.org/t/performance-scaling-and-ha-requirements/60098/8</ref>
  include conf.d/ssl.opensourceecology.org.include;
  #include conf.d/ssl.openbuildinginstitute.org.include;


  listen 10.241.189.11:443;
=Strategic Open Source=
  #listen [2a01:4f8:172:209e::2]:443;


  server_name discourse.opensourceecology.org;
[[File:202005_discourseStrategicOpenSource_PURGEtopic1.jpg|right|500px]]
[[File:202005_discourseStrategicOpenSource_PURGEtopic2.jpg|right|600px]]


#############
As of 2020, Discourse does appear to be the best solution to replace our deprecated [[Vanilla Forums]]. Unfortunately, it became clear over the course of its POC that the Discourse project is yet another example of [[Strategic Open Source]].
# SITE_DOWN #
#############
# uncomment this block && restart nginx prior to apache work to display the
# "SITE DOWN" webpage for our clients


#      root /var/www/html/SITE_DOWN/htdocs/;
While the code is open, Discourse does <em>not</em> have a open and collaborative culture.
#  index index.html index.htm;
#
#      # force all requests to load exactly this page
#      location / {
#              try_files $uri /index.html;
#      }


###################
This escalated in May 2020 on meta.discourse.org after I ([[User:Maltfield|Michael Altfield]]) published my varnish config to a [https://meta.discourse.org/t/discourse-purge-cache-method-on-content-changes/132917 topic I was using to document integration of Discourse with Varnish]. The Discourse staff told me (again) that Discourse already has built-in caching.
# SEND TO VARNISH #
###################


#  location / {
I responded (again) asking where their built-in caching was documented. Then Jeff Atwood (co-founder of Discourse) stepped-in and linked me to their source code. Frustrated, I asked:
#      proxy_pass http://127.0.0.1:6081;
#      proxy_set_header X-Real-IP $remote_addr;
#      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#      proxy_set_header X-Forwarded-Proto https;
#      proxy_set_header X-Forwarded-Port 443;
#      proxy_set_header Host $host;
#  }


##################
<blockquote>
# SEND TO DOCKER #
Michael Altfield: Serious question: Does the discourse team have a policy against writing documentation? Does the discourse project have any documentation-related policies at all?
##################
</blockquote>


location / {
Atwood's response was to threaten to ban me
proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Real-IP $remote_addr;
}


}
<blockquote>
EOF
Jeff Atwood: We do have a policy against people being rude to us. Would you like to explore that policy now?
</pre>
</blockquote>


==Varnish==
I made clear how I appreciate and value anyone's contributions to an open-source code base and added "but code alone is not a substitute for documentation" before reiterating my question about their documentation polcies. Atwood's response was


TODO: actually include varnish
<blockquote>
Atwood: ...We don't tend to spend time on that, as historically it is not a good use of our engineering budget. If you'd like to pay us...
</blockquote>


* https://meta.discourse.org/t/discourse-purge-cache-method-on-content-changes/132917
Then, what really shocked me was that the entire thread was marked to be deleted in 14 days. Note that I had been using this thread as a place to document how to integrate Discourse with Varnish--something that as-yet hasn't been documented in such detail anywhere on the 'net.


==Backups==
I added:


TODO: initiate backups via cron & validate a restore
<blockquote>
So I just noticed this:


==Hardening==
> This topic will be automatically deleted in 14 days.


Hardening TODO:
Please tell me this means this thead will become read-only and not deleted.


# iptables rules that prevent the discourse app from being able to initiate calls to the Internet (it should *only* be able to *respond* to queries) as we do for our apache backend by blocking non-established traffic from going through the OUTPUT table by the apache uid
I've gone through a lot of effort using this thread as a means to provide documentation to other users, and I want to ensure that it won't be deleted...
## TODO: test an upgrade after this is done as well.
</blockquote>
# OWASP CORS rules to prevent sqli/XSS/etc attacks as we do in apache


==SSL Cert==
Their response? The immediately deleted the entire topic. But not before I made a backup ([[:File:202005_discourseStrategicOpenSource_PURGEtopic_full.gif|gif]], [[:File:202005_discourseStrategicOpenSource_PURGEtopic_full.pdf|pdf]]).


TODO: update the certbot cron script to add a Subject Alt Name for discourse.opensourceecology.org
This whole interaction made it clear to me that:


==Import Vanilla Forums==
# Discourse has a toxic community that doesn't care about open collaboration
# Discourse intentionally doesn't document their product
# Discourse intentionally deletes user-submitted documentation
# I think that Discorse intentionally tries to make their product obscure and their users more helpless as a means to generate revenue


TODO: attempt to import our old forum's data into Discourse.
<br style="clear:both;" />


=MJ Feb 2019 Review=
=MJ Feb 2019 Review=
Line 328: Line 468:
# Whonix https://forums.whonix.org/
# Whonix https://forums.whonix.org/
# Manjaro https://forum.manjaro.org
# Manjaro https://forum.manjaro.org
=Alternatives=
A much simpler-to-maintain alternative to Discourse might be [[Flarum]]


=See Also=
=See Also=


* [[Discourse/Updating]]
* [[Discourse/Install]]
* [[OSE Forum]]
* [[OSE Forum]]
* [[Vanilla Forums]]
* [[Vanilla Forums]]
Line 339: Line 485:


=Links=
=Links=
# https://docs.discourse.org- API Docs only (not very useful)
#[[Michael Log]]
#[[Using Discourse]]
#'''[[OSE Forums]]'''
#[[Discourse Install Log]]
# https://docs.discourse.org API Docs only (not very useful)
# https://meta.discourse.org/c/10-howto - "howto" tagged topics on meta.discourse.org
# https://meta.discourse.org/c/10-howto - "howto" tagged topics on meta.discourse.org
# https://meta.discourse.org/c/howto/faq/4 - Discourse FAQ
# https://meta.discourse.org/c/howto/faq/4 - Discourse FAQ
Line 345: Line 495:
# https://meta.discourse.org/t/where-are-all-the-discourse-logs/58022
# https://meta.discourse.org/t/where-are-all-the-discourse-logs/58022
# https://meta.discourse.org/t/discourse-moderation-guide/63116
# https://meta.discourse.org/t/discourse-moderation-guide/63116
#
#Civilized Discourse Construction Kit - positively biased post about Discourse by its founder - [https://blog.codinghorror.com/civilized-discourse-construction-kit/]
#Civilized Discourse Construction Kit - positively biased post about Discourse - [https://blog.codinghorror.com/civilized-discourse-construction-kit/]
# https://www.slant.co/options/2789/~discourse-review
# https://www.slant.co/options/2789/~discourse-review
# https://forums.whonix.org/t/change-whonix-forum-software-to-discourse/1181
# https://forums.whonix.org/t/change-whonix-forum-software-to-discourse/1181

Latest revision as of 00:04, 28 February 2023

This article describes OSE's use of the Discourse software.

For a detailed guide to updating our Discourse server, see Discourse/Updating.

For a detailed guide on how we installed Discourse in 2020 on our CentOS 7 server, see Discourse/Install.

Official Discourse Documentation

Discourse doesn't have any official documentation outside of their API documentation.

It appears that this is intentional to make Discourse admins' lives difficult as a way to increase revenue. See #Strategic Open Source for more info.

TODO

List of outstanding tasks before attempting to install Discourse on production:

  1. iptables rules that prevent the discourse app from being able to initiate calls to the Internet (it should *only* be able to *respond* to queries) as we do for our apache backend by blocking non-established traffic from going through the OUTPUT table by the apache uid
    1. test an upgrade after this is done as well.
  2. OWASP CORS rules to prevent sqli/XSS/etc attacks as we do in apache
    1. update the install-nginx script so that it compiles nginx with mod_security (and probably downloads the OWASP CRS as well) https://github.com/discourse/discourse_docker/blob/416467f6ead98f82342e8a926dc6e06f36dfbd56/image/base/install-nginx
    2. add a new templates/web.modsecurity.yml file that updates the /etc/nginx/conf.d/discourse.conf file to enable mod_security (and add some blacklisted rules as-needed), similar to the existing web.socketed.template.yml file https://github.com/discourse/discourse_docker/blob/416467f6ead98f82342e8a926dc6e06f36dfbd56/templates/web.socketed.template.yml
  3. iptables on docker container instead of total internet blocking so the docker container can actually update its own OS packages?
    1. TODO: document update to `launcher` script's run_start() function's final `docker run` command to add the argument '--add-cap=NET_ADMIN' so the docker container root's user has permission to modify iptables rules.
  4. Fix unattended-upgrade https://meta.discourse.org/t/does-discourse-container-use-unattended-upgrades/136296
  5. Test/document Discourse upgrade process
  6. Test/document backup & restore process
  7. Stable cron job for docker image cleanup to prevent disk-fill
  8. Varnish cache https://meta.discourse.org/t/discourse-purge-cache-method-on-content-changes/132917
  9. Minimum/hardened permissions of the /var/discourse dir https://meta.discourse.org/t/minimum-hardened-file-permissions/148974

Useful Commands

This section will describe useful commands when working with Discourse

# get docker info
docker info

# list running docker containers
docker ps

# list all docker containers
docker ps -a

# list all docker images
docker image list

# get docker disk usage (including reclaimable space)
docker system df

# get a shell on the Discourse's docker container
/var/discourse/launcher enter discourse_ose

# access the rails console (exec from inside the docker container)
rails c

# restart a process from within the docker container (ie: cron, nginx, postgres, redis, rsyslog, unicorn)
sv stop nginx && sv start nginx

# stop/start/restart the Discourse container
/var/discourse/launcher stop discourse_ose
/var/discourse/launcher start discourse_ose
/var/discourse/launcher restart discourse_ose

# "rebuild" Discourse app (ie: for upgrades or changes to "templates/" yaml files)
# Takes 5-20 minutes to run, and it may break. Test on staging first.
/var/discourse/launcher rebuild discourse_ose

# "enter" a docker image to inspect/debug/troubleshoot the image itself
[root@osestaging1 ~]# docker image ls
REPOSITORY                      TAG                 IMAGE ID            CREATED             SIZE
local_discourse/discourse_ose   latest              b4d3feecf9e1        5 days ago          2.62GB
discourse_ose                   latest              2ea22070a06d        2 weeks ago         2.33GB
[root@osestaging1 ~]# docker run --rm -it --entrypoint /bin/bash 2ea22070a06d
root@00841db59cd7:/# 

# get capabilities of discourse docker container
id=`docker inspect --format="{{.Id}}" discourse_ose`
grep -E 'CapAdd|CapDrop|Capabilities' /var/lib/docker/containers/$id/hostconfig.json

# tail "outer" nginx logs
tail -c0 -f /var/log/nginx/*log /var/log/nginx/discourse.opensourceecology.org/*log

# monitor varnish for discourse-specific queries only
varnishlog -q "ReqHeader eq 'Host: discourse.opensourceecology.org'"

# tail "inner" discourse logs (run this on the docker host, not inside the container)
tail -c0 -f /var/discourse/shared/standalone/log/rails/*log /var/discourse/shared/standalone/log/var-log/redis/current /var/discourse/shared/standalone/log/var-log/postgres/current /var/discourse/shared/standalone/log/var-log/nginx/*log

Troubleshooting

This section will provide tips on how to troubleshoot the Discourse install

Important Files & Directories

For more information about our Discourse configuration, please see the following files & directories on the Docker Host:

/var/discourse/
/var/discourse/launcher
/var/discourse/containers/discourse_ose.yml
/var/discourse/templates/
/var/discourse/templates/templates/iptables.template.yml
/var/discourse/templates/templates/postgres.template.yml
/var/discourse/templates/templates/redis.template.yml
/var/discourse/templates/templates/web.template.yml
/var/discourse/templates/templates/web.ratelimited.template.yml
/var/discourse/templates/templates/web.socketed.template.yml
/var/discourse/templates/templates/web.modsecurity.template.yml
/var/discourse/image/base/
/var/discourse/image/base/Dockerfile
/var/discourse/image/base/install-nginx

And the following logs may be helpful:

/var/discourse/shared/standalone/log/rails/production.log
/var/discourse/shared/standalone/log/rails/unicorn.stderr.log
/var/discourse/shared/standalone/log/var-log/redis/current
/var/discourse/shared/standalone/log/var-log/nginx/{access.log,error.log}
/var/discourse/shared/standalone/log/var-log/postgres/current

And the following files & directories inside the Discourse Docker Container:

/var/www/discourse/
/var/www/discourse/public
/etc/nginx/conf.d/discourse.conf

Web Server Issues

This section will cover troubleshooting issues with Nginx, Varnish, etc.

Below will be just a list of error messages posted here primarily for the purpose of catching search queries on this wiki and directing them to this text:

To troubleshoot Discourse web server issues, this is a reminder: remember that there are two distinct nginx servers:

  1. nginx running on the server (docker host)
  2. nginx running _inside_ the discourse container running on the server

Don't forget to troubleshoot both!

user@ose:~$ curl -kI https://discourse.opensourceecology.org/
HTTP/1.1 502 Bad Gateway
Server: nginx
Date: Mon, 30 Mar 2020 09:03:23 GMT
Content-Type: text/html
Content-Length: 150
Connection: keep-alive

user@ose:~$ 

502 Bad Gateway

Relevant error messages:

  • cURL
Failed to connect to discourse.opensourceecology.org port 80: Connection refused

Unable to Connect

Relevant error messages:

  • cURL
Failed to connect to discourse.opensourceecology.org port 80: Connection refused
  • Firefox
Unable to connect

Firefox can’t establish a connection to the server at discourse.opensourceecology.org.

    The site could be temporarily unavailable or too busy. Try again in a few moments.
    If you are unable to load any pages, check your computer’s network connection.
    If your computer or network is protected by a firewall or proxy, make sure that Firefox is permitted to access the Web.
  • Chromium
This site can’t be reached discourse.opensourceecology.org refused to connect.
Try:

Checking the connection
Checking the proxy and the firewall
ERR_CONNECTION_REFUSED

This is because literally nothing is responding on the ip address and port.

`git pull` fail

The built-in Discourse 'launcher' script may try to do a `git pull` that may fail when it tries to update a file that we've modified in OSE's config. For example:

[root@osestaging1 discourse]# /var/discourse/launcher rebuild discourse_ose
Ensuring launcher is up to date
Fetching origin
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 2), reused 2 (delta 2), pack-reused 0
Unpacking objects: 100% (6/6), done.
From https://github.com/discourse/discourse_docker
   bb9a173..b0c92ba  master     -> origin/master
Updating Launcher
Updating bb9a173..b0c92ba
error: Your local changes to the following files would be overwritten by merge:
		launcher
Please, commit your changes or stash them before you can merge.
Aborting
failed to update
Ensuring launcher is up to date
Fetching origin
Updating Launcher
Updating bb9a173..b0c92ba
error: Your local changes to the following files would be overwritten by merge:
		launcher
Please, commit your changes or stash them before you can merge.
Aborting
failed to update
Ensuring launcher is up to date
Fetching origin
Updating Launcher
Updating bb9a173..b0c92ba
...

The above output was an endless loop complaining about the conflict between the file 'launcher' in the '/var/discourse/' directory. In order to fix the conflict, you must merge the changes--which may be a non-trivial process.

The easiest action is to just move the locally modified files out of the way, do a clean `git pull`, make note a diff of the changes, and re-apply the local changes by re-visiting the relevant section of install guide. For detailed instructions on this process, see the "Updating Discourse" #Step 3: Update git section.

Removal In Progress

You may get an error when attempting to rebuild the Discourse docker container because an old docker container is stuck in a "Removal In Progress" state. For example:

[root@osestaging1 discourse]# time /var/discourse/launcher rebuild discourse_ose
...
169:M 23 Mar 2020 10:19:33.054 # Redis is now ready to exit, bye bye...
2020-03-23 10:19:33.127 UTC [52] LOG:  database system is shut down
sha256:6e6c81a3529175c1aa8e3391599499704f3abb9833ca3e943cf1b5443da4f47c
fbf51479947c537d2247bf38bd0ca2f1cb96257dbbf86e93038e6a19f2bab5d6
Removing old container
+ /bin/docker rm discourse_ose
Error response from daemon: container 12bb1e40517bb4893ff428096fa204f145c75d64be6a269cbe3093543373c6a8: driver "overlay2" failed to remove root filesystem: unlinkat /var/lib/docker/overlay2/99f609ae22d509152fd6db0120ba111c4d892b153d41d2e720790c864d5d678a/merged: device or resource busy

starting up existing container
+ /bin/docker start discourse_ose
Error response from daemon: container is marked for removal and cannot be started
Error: failed to start containers: discourse_ose

real    8m39.585s
user    0m1.764s
sys     0m1.684s
[root@osestaging1 discourse]# 

Restarting docker _may_ help you to manually delete the docker container. Or not

[root@osestaging1 containers]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                PORTS               NAMES
12bb1e40517b        4d92ff0b76a7        "/sbin/boot"        6 days ago          Removal In Progress                       discourse_ose
[root@osestaging1 containers]# systemctl restart docker
[root@osestaging1 containers]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
12bb1e40517b        4d92ff0b76a7        "/sbin/boot"        6 days ago          Dead                                    discourse_ose
[root@osestaging1 containers]# docker rm 12bb1e40517b
Error response from daemon: container 12bb1e40517bb4893ff428096fa204f145c75d64be6a269cbe3093543373c6a8: driver "overlay2" failed to remove root filesystem: unlinkat /var/lib/docker/overlay2/99f609ae22d509152fd6db0120ba111c4d892b153d41d2e720790c864d5d678a/merged: device or resource busy
[root@osestaging1 containers]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                PORTS               NAMES
12bb1e40517b        4d92ff0b76a7        "/sbin/boot"        6 days ago          Removal In Progress                       discourse_ose
[root@osestaging1 containers]#

This issue coincides with the following error being written to the systemd journal log

Mar 23 10:44:55 osestaging1 dockerd[16920]: time="2020-03-23T10:44:55.578997874Z" level=error msg="Error removing mounted layer 12bb1e40517bb4893ff428096fa204f145c75d64be6a269cbe3093543373c6a8: unlinkat /var/lib/docker/overlay2/99f609ae22d509152fd6db0120ba111c4d892b153d41d2e720790c864d5d678a/merged: device or resource busy"
Mar 23 10:44:55 osestaging1 dockerd[16920]: time="2020-03-23T10:44:55.579614708Z" level=error msg="Handler for DELETE /v1.40/containers/12bb1e40517b returned error: container 12bb1e40517bb4893ff428096fa204f145c75d64be6a269cbe3093543373c6a8: driver \"overlay2\" failed to remove root filesystem: unlinkat /var/lib/docker/overlay2/99f609ae22d509152fd6db0120ba111c4d892b153d41d2e720790c864d5d678a/merged: device or resource busy"

A fix is to stop docker, force remove the problem container's directory, and start docker again. It would be wise to make a backup before attempting to proceed with this, just in-case you permanently delete the wrong container's directory!

[root@osestaging1 containers]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                PORTS               NAMES
12bb1e40517b        4d92ff0b76a7        "/sbin/boot"        6 days ago          Removal In Progress                       discourse_ose
[root@osestaging1 containers]# docker ps -a --no-trunc
CONTAINER ID                                                       IMAGE                                                                     COMMAND             CREATED             STATUS                PORTS               NAMES
12bb1e40517bb4893ff428096fa204f145c75d64be6a269cbe3093543373c6a8   sha256:4d92ff0b76a725a5252fce8567e961fc01eebe68c2b34d1abc9c94cae041597e   "/sbin/boot"        6 days ago          Removal In Progress                       discourse_ose
[root@osestaging1 containers]# systemctl stop docker
[root@osestaging1 containers]# rm -rf /var/lib/docker/containers/12bb1e40517bb4893ff428096fa204f145c75d64be6a269cbe3093543373c6a8
[root@osestaging1 containers]# systemctl start docker
[root@osestaging1 containers]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@osestaging1 containers]# 

Installing Themes and Components

By design, our web servers can only respond to requests; they cannot initiate requests. And Discourse is no different.

This means that the usual route of installing themes and components in Discourse via the WUI (Admin -> Customize -> Themes -> Install -> Popular -> Install) won't work.

Error cloning git repository, access is denied or repository is not found

Step #1: Find repo

To install a theme or theme component in our Discourse, first find its git repo. You can find many Discourse theme repos by listing all repos tagged with the topic 'discourse-theme' or 'discourse-theme-component' in the Discourse project on github.

* https://github.com/search?q=topic%3Adiscourse-theme+org%3Adiscourse+fork%3Atrue
* https://github.com/search?q=topic%3Adiscourse-theme-component+org%3Adiscourse+fork%3Atrue

Step #2: Download zip

202005 discourseInstallTheme1.jpg

For example, here's a link to the github repo for the Discourse "Classic Theme"

* https://github.com/discourse/discourse-classic

From the theme's github repo page, download a zip of the repo by clicking "Clone or download" -> "Download ZIP"


Step #3: Upload zip

202005 discourseInstallTheme2.jpg

Now, login to our Discourse site and navigate to Admin -> Customize -> Themes

Click Install


202005 discourseInstallTheme3.jpg

In the JS modal "pop-up", choose From your device.

Finally, click Browse and upload the .zip file downloaded above.


Looking Forward

This section will outline possible changes to be made to the Docker install/config in the future

Moving DBs outside docker

It's worthwhile to consider moving the redis and postgresql components of Discourse outside of the docker container [1]

Strategic Open Source

202005 discourseStrategicOpenSource PURGEtopic1.jpg
202005 discourseStrategicOpenSource PURGEtopic2.jpg

As of 2020, Discourse does appear to be the best solution to replace our deprecated Vanilla Forums. Unfortunately, it became clear over the course of its POC that the Discourse project is yet another example of Strategic Open Source.

While the code is open, Discourse does not have a open and collaborative culture.

This escalated in May 2020 on meta.discourse.org after I (Michael Altfield) published my varnish config to a topic I was using to document integration of Discourse with Varnish. The Discourse staff told me (again) that Discourse already has built-in caching.

I responded (again) asking where their built-in caching was documented. Then Jeff Atwood (co-founder of Discourse) stepped-in and linked me to their source code. Frustrated, I asked:

Michael Altfield: Serious question: Does the discourse team have a policy against writing documentation? Does the discourse project have any documentation-related policies at all?

Atwood's response was to threaten to ban me

Jeff Atwood: We do have a policy against people being rude to us. Would you like to explore that policy now?

I made clear how I appreciate and value anyone's contributions to an open-source code base and added "but code alone is not a substitute for documentation" before reiterating my question about their documentation polcies. Atwood's response was

Atwood: ...We don't tend to spend time on that, as historically it is not a good use of our engineering budget. If you'd like to pay us...

Then, what really shocked me was that the entire thread was marked to be deleted in 14 days. Note that I had been using this thread as a place to document how to integrate Discourse with Varnish--something that as-yet hasn't been documented in such detail anywhere on the 'net.

I added:

So I just noticed this:

> This topic will be automatically deleted in 14 days.

Please tell me this means this thead will become read-only and not deleted.

I've gone through a lot of effort using this thread as a means to provide documentation to other users, and I want to ensure that it won't be deleted...

Their response? The immediately deleted the entire topic. But not before I made a backup (gif, pdf).

This whole interaction made it clear to me that:

  1. Discourse has a toxic community that doesn't care about open collaboration
  2. Discourse intentionally doesn't document their product
  3. Discourse intentionally deletes user-submitted documentation
  4. I think that Discorse intentionally tries to make their product obscure and their users more helpless as a means to generate revenue


MJ Feb 2019 Review

  • Legend: Check.png = exists, Check.pngCheck.png = good, Check.pngCheck.pngCheck.png = great
  • Check.pngQ&A plugin appears to be adequate, but does not have downvotes. Downvotes are important, as a knowledgeable person should ideally be able to downsize bull****. This is important for collaborative learning - and should be developed to approach the usefulness of Stack Exchange and Reddit. Would need to put development time into this.
  • Check.pngCheck.pngCheck.pngRating - appears excellent - [1]
  • Check.pngCheck.pngCheck.pngCommenting plugin - excellent, up with Disqus. [2]
  • Check.pngCheck.pngCheck.pngBug Tracking - a simple wiki/Discourse hack can be done by a Bugtracking or Known Bugs category on the wiki, and embedding a thread on that bug from Discourse, so discussion can happen, and when resolved, thread can be closed. We'd have to see in practice how this looks. That is the simplest way to go without installing yet another pieces of software, and using Discourse and Wiki hold most of the weight, the rest being Wordpress.

Cons

  • Free to try rather than really free? See last con at [3]

OSE Use Case

  • The generic OSE use case for transparency is using the Wiki for embedding all kinds of content, where the wiki is a proven and scalable tool for collaborative development - and a core tool in OSE's usage. With this said, it is useful to have various forms of content embedded in the wiki, so that we don't have to use many different platforms for different functions: we can just embed content from other common platforms. The intent is modular design where content can be reused and mixed throughout OSE's web presence.
  1. Embed individual Discourse threads on wiki pages. This way we upgrade content from wiki pages to live discussion - where content for discussion can be edited right in the wiki page. The intent of this is to improve the use of the Wiki as a development platform so that the wiki is more intuitive. See embed of thread example - [4]. This must allow any single thread from Discourse to be embedded.
  2. Rating of a service or product - in an open source franchise, products/services of collaborators can be rated. A simple tool like the wiki can have a rating feature - without having to use any other software. This is yet another way to make the wiki more functional and user-friendly. See example - [5]
  3. Upvoting - no evidence of Discourse serving this function well compared to Askbot. By upvoting, we mean simply that all the content remains visible, and a single solution is not marked. This allows users to pick nuggets from different answers - while allowing bulk filtering to occur before looking at the answer. From the OSE perspective, marking a question as resolved is not inclusive or abundant. What if someone else has a better solution? It may be that Discourse can be modified to do upvoting readily, or can simulate this function well - but we would have to see in practice if this is feasible.

2018-09 Review

In 2018-09, I (Michael Altfield) had just learned about Discourse as I was working on the phplist project. phplist's forums use Discourse. At the same time, Alex Au recommended to Marcin that we setup a replacement forum using Discourse.

Pros

  1. Very pleasant interface
  2. Very nice functionality ootb. Badges, user trust system for easy moderation, climbing ranks, love, at-calls (@), etc -- co-founder Jeff Atwood also founded Stack Exchange, so expect similar functionality
  3. Very popular. Many, many forums have switched to Discourse over the past several years
  4. Great selection of plugins & integrations (though no decent db/index for searching them) https://meta.discourse.org/c/plugin https://github.com/discourse
    1. ie: replace wordpress comments with a discourse thread. This may or may not be good.
      1. Example wordpress blog post: https://blog.discourse.org/2018/06/understanding-discourse-trust-levels/
      2. Corresponding discourse thread for the comments to the above post: https://meta.discourse.org/t/wp-discourse-dysfunctional-shows-only-start-the-discussion-at/36016
  5. Looks like we can import our content from Vanila https://meta.discourse.org/t/how-to-migrate-from-vanilla-to-discourse/27273
  6. Well-funded org that hosts their project (think wordpress.com) for many of their customers. The good here is that Discorse can pay a salary to devs, unlike many open source projects. But it's worth nothing that people choose to pay for hosting probably because it's Ruby on Rails, and a PIA to self-host.
  7. While not officially supported, it looks like users have setup Discourse behind varnish 4 [2]

Cons

  1. Ruby on rails
  2. They openly state that they're hard to install, and therefore _only_ support installation via a docker container [3]
  3. I'm seriously worried about the security of a project that thinks it's acceptable to use wget -qO- https://get.docker.com/ | sh as a step in their install guide [4]
  4. Discourse explicitly states that they only support newer devices. I'm concerned that means that we may make our content inaccessible to, say, that 6-year-old desktop running windows xp in the machine shop. Indeed, discourse only supports IE 11+, which came with Windows 8.1 in 2013--5 years ago. [5]
  5. If javascript is disabled, the site is read-only. JS is a requirement for posting, replying, etc. But because Discourse also functions as a mailing list, JS-free users can still contribute content in a limited way by replying to threads via email [6]

Neutral

  1. Project has been around for 5 years (initial release in 2013) https://en.wikipedia.org/wiki/Discourse_%28software%29

Noteable sites using Discourse

  1. Ubuntu https://discourse.ubuntu.com/
  2. Phplist https://discuss.phplist.org/
  3. Whonix https://forums.whonix.org/
  4. Manjaro https://forum.manjaro.org

Alternatives

A much simpler-to-maintain alternative to Discourse might be Flarum

See Also

References

Links

  1. Michael Log
  2. Using Discourse
  3. OSE Forums
  4. Discourse Install Log
  5. https://docs.discourse.org API Docs only (not very useful)
  6. https://meta.discourse.org/c/10-howto - "howto" tagged topics on meta.discourse.org
  7. https://meta.discourse.org/c/howto/faq/4 - Discourse FAQ
  8. https://meta.discourse.org/t/advanced-troubleshooting-with-docker/15927
  9. https://meta.discourse.org/t/where-are-all-the-discourse-logs/58022
  10. https://meta.discourse.org/t/discourse-moderation-guide/63116
  11. Civilized Discourse Construction Kit - positively biased post about Discourse by its founder - [6]
  12. https://www.slant.co/options/2789/~discourse-review
  13. https://forums.whonix.org/t/change-whonix-forum-software-to-discourse/1181