Setup a self-hosted commenting system on your blog
After adding the privacy and data notice on this blog, it felt like it's time to reduce the 2-11 trackers that were being blocked by Brave browser and bring it down to zero. Also, since Disqus tracks visitor data on the free tier (still, they have a Do Not Sell My Data policy which can be toggled on and off, it still didn't feel okay to even allow Disqus tracking data on this blog by default), so, I decided to switch to a self-hosted commenting system that would respect the privacy of the users accessing this blog.
Let's get into the tutorial.
We will be replacing Disqus with Remark42 commenting system which can be self-hosted and ensures the privacy of incoming users. We will only allow GitHub login for the folks who decide to use their GitHub profile to interact in the comments section. Since, this is a tech blog, I hope everyone has a GitHub account. Also, you will be able to comment as an Anonymous user as well. (We can have moderators enabled on this system, so spam and abusive comments can be very well handled!)
For this tutorial, I'll be using one of my servers from Oracle Cloud free tier running Ubuntu 20.4 LTS:

Step 1: Download latest release from GitHub and extract it:
wget https://github.com/umputun/remark42/releases/download/v1.6.0/remark42.linux-amd64.tar.gz -O remark42.linux-amd64.tar.gz
tar xzf remark42.linux-amd64.tar.gz remark42.linux-amd64
mv remark42.linux-amd64 /usr/local/bin
Step 2: Create remark42 user and base directory:
useradd -r remark42
mkdir -m 770 /var/www/remark42
chown :remark42 /var/www/remark42
Step 3: Create the configuration file
vim /var/www/remark42/remark42.conf
REMARK_URL=http://remark42.example.com
SECRET=some_secret_key_phrase_1234
SITE=mywebpage
AUTH_ANON=true
EMOJI=true
Step 4: Create a systemd service for remark42:
[Unit]
Description=remark42 comment engine
After=network.target
[Service]
User=remark42
Group=remark42
EnvironmentFile=/var/www/remark42/remark42.conf
WorkingDirectory=/var/www/remark42
Restart=always
RestartSec=5
ExecStart=/usr/local/bin/remark42.linux-amd64 server
[Install]
WantedBy=multi-user.target
Activate the service:
systemctl enable --now remark42
Step 5: Setup GitHub OAuth in order to allow users to authenticate the commenting system using their GitHub account:
- Go to GitHub -> Click on Profile Icon -> Click on Settings -> Developers -> OAuth Apps
- Click on New OAuth App
- Set base URL to same value as in environment file
- Set callback URL by appending auth/github/callback to the base RemarkURL: http://remark42.example.com/auth/github/callback
- Note down client id and client secret and add them to environment configuration file
vim /var/www/remark42/remark42.conf
AUTH_GITHUB_CID=<API_ID>
AUTH_GITHUB_CSEC=<API_SECRET>
Step 6: Test the setup by going to the demo URL:
Append /web/ to the base URL which would look something like: http://remark42.example.com/web/

Step 7: Setup yourself as the moderator and admin:
Login into your commenting system with GitHub to get the login ID which would start with github_
vim /var/www/remark42/remark42.conf

ADMIN_SHARED_ID=<GitHub Login ID>
Step 8: Embed the commenting system on your Ghost blog:
Add the below <div> and <script> to the post.hbs file at /var/www/ghost/content/themes/<theme_name>/ where you want the comments to appear.
<div id="remark42"></div>
<script>
var remark_config = {
host: "REMARK_URL",
site_id: 'YOUR_SITE_ID',
components: ['embed'],
max_shown_comments: 10,
theme: 'light',
locale: 'en',
show_email_subscription: false
};
</script>
<script>
(function(c) {
for(var i = 0; i < c.length; i++){
var d = document, s = d.createElement('script');
s.src = remark_config.host + '/web/' +c[i] +'.js';
s.defer = true;
(d.head || d.body).appendChild(s);
}
})(remark_config.components || ['embed']);
</script>
And there it is. The commenting system should be up and running by now with GitHub and Anonymous login options.

Step 9: Setup reverse proxy with Nginx:
sudo vim /etc/nginx/sites-available/default
server {
server_name remark42.example.com;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
location / {
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:8080/;
}
}
sudo nginx -s reload
[Optional]
Configure the Ghost theme to detect Dark or Light mode from the user's browser and configure the comment system to match it while loading completes. The below script will detect browser if it has a dark mode enabled by default and match it. In case the browser is set to light mode by default, the above embedding configuration has light mode already enabled by default.
window.onload = function() {
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
window.REMARK42.changeTheme('dark');
}
}
[Bonus]
Configure the Ghost theme to change theme according to the Dark/Light theme toggle. Now, in most cases, the toggle to change theme is based on an <input> tag being used as a checkbox:
Add onchange event listener to the toggle:
<input type="checkbox" name="toggle-dark" onchange="toggleComments()">
var toggleComments = function() {
if (document.getElementById("toggle-dark").checked == true) {
window.REMARK42.changeTheme('dark');
} else {
window.REMARK42.changeTheme('light');
}
}
Cheers!
P.S. - I am happy to say that now with this change applied, the trackers on this blog as shown on Brave browser are down to zero. If you click the BMC widget, it does initiate some trackers (4-5 in total), but they are handled by Brave quite well. So, yeah, it's okay to say Brave is one of my favouite companies along with Cloudflare.

[Update - 13th March 2023]
As of today, I have retired this commenting system on the blog due to resource constraints.