Table of Contents
After I moved from WordPress to Hugo, I was missing a commenting system. Actually, I never did receive that many comments when using WordPress, but I still want to give folks the ability to leave comments. I was looking for a simple, self-hosted solution that would work with my VPS. My VPS provider does not permit root access, so that was an additional restriction. My VPS does support using a “rootless” version of Docker, and I learned that Remark42 will work with it.
This post describes how to set up a self-hosted Remark42 commenting system, using Docker, on a Hugo website. My Hugo website and the Remark42 system runs on my Fully-managed VPS (with no root access) provided by Pair. I also include notes about how to use Docker. This was a big learning curve for me, so I am hoping that this post might help others.
Privacy-focused Lightweight Commenting Engine
In a nut shell, that describes Remark42. You can go to their excellent website to see a list of features. Their system is well documented. I am going to hit on the highlights about what I did to integrate their system with my Hugo website. You can also read about how they value privacy. Their system supports various ways to login and leave a comment. You can configure various social logins such as Google and GitHub. You can login via an email address (which is not displayed). And there is even optional anonymous access. I chose to use Google, GitHub, and email access. I do not allow anonymous access; I was afraid that method would create a lot of spam comments.
They also have an active support community that quickly answered my question about Remark42 working in a rootless docker environment. As part of my Pair environment, I am also using a reverse proxy. Pair provides the ability to easily create a reverse proxy for my remark42 hosting domain.
Set Up Your Environment
You need to ensure that docker and docker-compose is working on your host. There are many excellent Docker tutorials on the net, so I will not cover the details of installing and using it. You can refer to the Docker Docs to get started. After Docker is installed, you can run docker run hello-world to verify your installation.
Next, you need to configure a subdomain, such as remark42.example.com, to host your commenting system. I enabled “https” and a reverse proxy on my remark42 subdomain. With Pair, this only took a couple of clicks. The reverse proxy maps to http://localhost:8080.
Install the Remark42 Docker Image
You are going to use docker compose to install and manage your Remark42 commenting system (don’t use docker-compose). Do the following to verify that docker compose is installed and working:
$ sudo docker compose version
Docker Compose version v5.2.0
Next, in my remark42 subdomain root, I created a docker-compose.yml file that defines my Remark42 Docker configuration. The Remark42 GitHub repository provides an example docker-compose.yml file that you can customize to your needs. Here’s what my docker-compose.yml looks like:
---
name: remark42
services:
remark42:
image: ghcr.io/umputun/remark42:latest
container_name: "remark42"
hostname: "remark42"
ports:
- "127.0.0.1:8080:8080"
restart: always
environment:
- REMARK_URL=https://comments.example.com
- SITE=example
- SECRET=My-very-long-random-string
- STORE_BOLT_PATH=/srv/var/db
- BACKUP_PATH=/srv/var/backup
- EMOJI=true
- AUTH_ANON=true
- AUTH_GITHUB_CID=My-github-cid
- AUTH_GITHUB_CSEC=My-github-csec
- AUTH_EMAIL_ENABLE=true
- AUTH_EMAIL_FROM=user@example.com
- SMTP_HOST=mail.example.com
- SMTP_PORT=465
- SMTP_TLS=true
- SMTP_USERNAME=user@example.com
- SMTP_PASSWORD=My-SMTP-password
- NOTIFY_USERS=email
- NOTIFY_EMAIL_FROM=user@example.com
- NOTIFY_ADMINS=email
- ADMIN_SHARED_EMAIL=user@example.com
- ADMIN_SHARED_ID=My-github-shared-id
volumes:
- remark42-db:/srv/var
networks:
- remark42
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:8080/api/v1/ping"]
interval: 30s
timeout: 10s
retries: 3
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
volumes:
remark42-db:
name: remark42-db
networks:
remark42:
name: remark42
You can read about the interface parameters at the Remark42 site. They show the minimal docker-compose.yml file with all the required parameters. I have added a few additional ones for my application.
To generate a “a long random string” for the SECRET parameter, I like using the Homebrew pwgen tool:
$ pwgen -s 64 1
H8qRx8F8UnypUqTU8zep8UJFH5KSm6DQHTGSCBwonilj5kSXpzzn5SfqIPAay1JQ
You can adjust the string length (64) as desired.
The Remark42 documentation provides detailed procedures for configuring OAuth providers, so I will not repeat it here.
The “ports” definition allows access to the Remark42 instance on the local host, including the reverse proxy. But it blocks access from an external IP.
ADMIN_SHARED_ID
The ADMIN_SHARED_ID was a bit tricky to get. After you have your Remark42 commenting system working with Hugo, login, for example with GitHub, and click on your user name. You will see a slide-in screen on the right with your GitHub Admin shared ID. Then you can add the ADMIN_SHARED_ID to your docker compose file (be sure to stop and start your docker container after making any changes to the config file).
Pull the Docker Remark42 Image
Ok, let’s get started. You first need to download the Remark42 image using the Docker Compose pull command. Change directory to the location of your docker compose configuration and “pull” the Remark42 image, using docker compose:
$ sudo docker compose pull
[sudo] password for apcom:
[+] pull 11/11
✔ Image ghcr.io/umputun/remark42:latest Pulled 3.4s
You will see each subimage being pulled down and installed. Your final pull state should look simalar to the above.
You can verify that the Remar42 image is installed:
$ sudo docker image ls
i Info → U In Use
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
ghcr.io/umputun/remark42:latest ce499d39502b 130MB 33.1MB U
Start the Remark42 Docker Container
Start the Remark42 server with:
$ sudo docker compose up -d
[+] up 3/3
✔ Network remark42 Created 0.0s
✔ Volume remark42-db Created 0.0s
✔ Container remark42 Started 0.3s
You can verify that the remark42 container is running with the Docker ps command:
$ sudo docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
remark42 ghcr.io/umputun/remark42:latest "/init.sh /srv/remar…" remark42 4 minutes ago Up 4 minutes (healthy) 127.0.0.1:8080->8080/tcp
Your want to verify that the STATUS is “healthy”. You can also run the following “ping” command, via the curl command, to verify that you can communicate with the Remark42 container:
$ curl http://127.0.0.1:8080/ping
pong
You want to see the pong response.
You can stop and start the Remark42 with these commands:
$ sudo docker stop remark42
remark42
$ sudo docker start remark42
remark42
Integrate Remark42 with Hugo
Exactly how you do that will depend on which Hugo theme you are using. Some themes may already have Remark42 support built in. I added the following to just after the {{ .Content }} section in my layouts single.html configuration file:
{{ .Content }}
{{ if and .Site.Params.remark42.enabled (.Params.remark42 | default true) }}
{{ partial "comments.html" . }}
{{ end }}
In my Hugo site configuration file (hugo.yaml or config.yaml), I added:
params:
remark42:
enabled: true
host: "https://remark42.example.com"
site: "example"
locale: "en"
Note: The site parameter must match the one that you used for the SITE variable in your docker-compose.yml file. Also, be sure that host matches your REMARK_URL in docker compose configuration. You get the idea.
You might want to disable commenting for a particular post. You can add a Frontmatter variable remark42 and set it to false.
Finally, here is my remark42.html layouts partials file:
{{- with .Site.Params.remark42 -}}
<hr>
<p><b>Your comments are welcome!</b></p>
<div id="remark42"></div>
<script>
var remark_config = {
host: '{{ .host }}',
site_id: '{{ .site }}',
url: '{{ $.Permalink }}',
theme: localStorage.getItem("theme")
};
</script>
<script>
! function(e, n) {
for(var o = 0; o < e.length; o++) {
var r = n.createElement("script"),
c = ".js",
d = n.head || n.body;
"noModule" in r ? (r.type = "module", c = ".mjs") : r.async = !0, r.defer = !0, r.src = remark_config.host + "/web/" + e[o] + c, d.appendChild(r)
}
} (remark_config.components || ["embed"], document);
</script>
{{- end -}}
You can look below to see the final results. Better yet, try leaving a comment! There is a lot more to learn about using Remark42. You can review their extensive documentation.
How to Delete your Remark42 Installation (Optional)
This section includes additional information about how to use Docker to delete your Remark42 installation. This is what has worked for me, but I am still learning all about Docker, so your mileage may vary. My goal is to illustrate some useful Docker commands. I will show how to completely remove your Remark42 Docker installation.
First, stop the Remark42 Docker container:
$ sudo docker stop remark42
remark42
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Next, delete the container:
$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5c4aa4b0351a ghcr.io/umputun/remark42:latest "/init.sh /srv/remar…" 7 minutes ago Exited (0) 3 minutes ago remark42
$ sudo docker rm remark42
remark42
$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Delete the Remark42 data volume if you don’t want to keep the comment data. Careful, you will not be able to restore the data unless you made a backup!!
$ sudo docker volume ls
DRIVER VOLUME NAME
local remark42_data
$ sudo docker volume rm remark42_data
remark42_data
Finally, you can delete the Remark42 downloaded image:
$ sudo docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ghcr.io/umputun/remark42 latest 274272164479 9 months ago 81.2MB
$ sudo docker image rmi 274272164479
That was a quick fly over; please refer to the Docker Docs for additional details.
Final Thoughts
I finally have a commenting system working with Hugo! It’s self-hosted, so I am not paying for an external 3rd party service. The comments stay on my server, under my control, so they remain private. I hope that I provided enough information for you to add commenting to your Hugo site. Please, let me know if something is not clear or you have a question. I will be happy to try to answer it. Just leave a comment below. :smile:
Your Comments Are Welcome!
I am currently porting to a new host.
For now, you can use my contact form..