As part of my mission to build a lean and fast blog with privacy features, I have settled on Commento for my embedded comment system, and now need to go about getting it installed and embedded in this blog.

Getting started with Commento and Docker on my test server

As part of my selection process test installations, I found that the combination of Commento with its default PostgreSQL database in Docker container form took up a footprint of 44MB of memory and 142MB of disk space in an "out of the box" build. For my production build I had a similar increase of 41MB and 145MB respectively.

Key Commento features I like

  • Can be self hosted
  • Robust Docker options
  • Low footprint server and on the page
  • Privacy focus
  • Endorsed by Mozilla
  • Open source (MIT license)
  • Allows anonymous comments
  • Integrates with Akismet

Planning the Commento build

I will be following the self-hosting and Docker installation guide from their doc pages. My go-to model is to make use of a Traefik-fronted stack to handle the proxy and HTTPS encryption.

I have decided to colocate the Commento server on the same server as this blog. I will be adding it as two more containers to my Docker / Ghost build, which was initially configured as described here. It could easily be run on a separate server, and that is an option for the future if I need to scale, but it should be well within the 1GB total memory I have on my primary blog server.

The Commento container has no volatile storage area needed. The PostgreSQL database does, and I will create a /data/postgresdb local directory for the database files, which will get backed up periodically to S3 with the rest of /data.

Choosing a comment server domain

After considering that the same Commento instance can serve multiple sites, I will still opt to use the domain as it represents a sort of technical resource in my mind. However, as it will appear in the page load calls as an external domain, I would like to convey the fact somehow that it's privately hosted. Also I would like to use a similar domain for analytics in future. So I will serve up from a "privateapp" subdomain like so:

Adding to docker-compose.yml for the Commento and PostgreSQL containers

The Commento container

This container is the only one that doesn't live on Docker hub. The latest regular build is available in the GitLab registry. The latest version can be pulled in using the "latest" tag, so a suitable image will look like:

Be aware of what it means to pull the latest, and take note of the registry location should you need to roll back to an earlier version.

The Commento container in docker-compose.yml

There are docker compose examples on the Commento site, it could look something like this when fronted by Traefik.

                restart: always
                        - 8080:8080
                        - /YOUR_PATH_HERE/commento.env:/commento/commento.env
                        COMMENTO_CONFIG_FILE: /commento/commento.env
                        COMMENTO_PORT: 8080
                        COMMENTO_POSTGRES: postgres://commento:your_password_here@postgresdb:5432/commento?sslmode=disable
                        - traefik.backend=commento
                        - traefik.port=8080
                        driver: syslog
                        - postgresdb
                        - web
                        - internal


"@postgresdb" should be the name of the postgreSQL container in docker compose. Change commento:commento to the user and password you'd like.

SSL mode is disabled as the Commento front end container talks over the private Traefik internal network to the database.

Other Docker Compose Commento notes

GitHub and other Oauth providers can be added if you wish to allow readers to use other providers to log in. At the time of writing GitHub, GitLab, Twitter and Google are supported.

Further information on the configuration options is here:

The options describe breaking out the Commento parameters into a separate commento.env file. This is good practice with the SMTP password in there in plain text. My attempts with this allowed me to get the bulk of the settings into a separate file but only with the COMMENTO_POSTGRES parameter retained in the main Docker compose file.

Logging set to syslog will send output to the default log file (e.g. /var/log/syslog on Ubuntu 18). This will help a lot if having trouble getting set up, although by default it is mixed in with the main syslog noise.

The commento.env file

I got this working with separate parameters farmed out to a commento.env file, which needs to be mounted in the container as demonstrated. The container image includes a /commento directory which I have used when mapping the local volume.


# Uncomment SMTP and test after admin is registered

# As soon as you have registered your admin/s, immediately uncomment/set this to "true"

# You should probably get yourself an Akismet key, set it here, and uncomment

# Set third party OAuth credentials, optional.

If you are going to add SMTP parameters, they need to work. If they don't you won't be able to register your admin login. You may wish to leave them out just to get started, if it causes you problems. I recommend that you comment out SMTP settings until after you have first registered your admin account. Mine didn't work at first and I got caught in a "Email dispatch failed" death spiral where I have to activate from the email but it had never sent one - and there is no resend option. I had to disable SMTP settings and use a different email address to get in.

Even when you have the settings right you will definitely need to spend some time posting comments to test it until the notifications work. SMTP is notoriously fickle.

Docker compose "networks"

This relies on the existence of networks for web, for our external facing ports, and internal, for our back end virtual network traffic. If unsure about the web network, check my Traefik build post. For the internal network, if it's not already in your docker compose file, you can add it next to the web one, ending up like so:

                external: true
                external: false

The Commento PostgreSQL Container

Add to the compose file similar to this.

                image: postgres:11-alpine
                restart: always
                        POSTGRES_DB: commento
                        POSTGRES_USER: commento
                        POSTGRES_PASSWORD: your_password_here
                        - internal
                        - /YOUR_PATH_HERE:/var/lib/postgresql/data
                        - traefik.enable=false

The entry should be named the same as the commento @ entry that's connecting to the database, in this example postgresdb.

I have chosen the postgres:11-alpine image of PostgreSQL. This should make use of the latest version 11 database image from Docker hub including any patches, with an alpine build for a small footprint. There are a variety of image tags with different consequences that can be reviewed at .

The network is internal, and Traefik is disabled, as it does not need to be exposed directly to the internet.

Running docker compose to create the containers

Don't be disheartened if it takes a bit of fiddling for the two containers to get up and stay up. After some tinkering I finally have success.

$ docker-compose up -d
traefik_traefik_1 is up-to-date
Recreating traefik_postgresdb_1 ...
Recreating traefik_postgresdb_1 ... done
Recreating traefik_commento_1   ... done

My endpoint is alive, on, I am rewarded with a first login screen and can hit the Sign up link. As soon as you have signed up, if you don't have others immediately waiting to sign up as admins, change the compose file parameter to forbid new owners.

It seems that whatever email address you create as a moderator is fixed as a notification recipient. So register with the same email that you would expect moderation mails to come to.

Follow the setup steps on until you are ready to embed the comment link into your blog pages.

I am going to start out fairly light on the moderation and see if Akismet does it's thing well, if spam makes its way through, I'll have to enable it - reluctantly.

Embedding Commento in a containerised Ghost deployment

If you, like me, have the default Ghost Casper theme, and are running Ghost in a container, some tinkering is needed to get the Commento hook into the post template. The file we want to edit is post.hbs, which normally lives inside the container itself. We need to copy it out for editing, then link it back in to the running container.

Customising post.hbs in a Ghost Docker container

There is a handy command set to dump out the contents of a container so you can pick over the files and directory structure, but watch the disk space.

$ docker run --name tmp-ghost-container -d ghost:2-alpine
$ docker cp tmp-ghost-container:/ /tmp/ghost-dump
$ docker rm -f tmp-ghost-container

Search the ghost-dump for the post.hbs file and copy it to your data volume. In my case that it was in /tmp/ghost-dump/var/lib/ghost/versions/2.20.1/content/themes/casper/post.hbs .

Your paths may differ, but I could then copy the file and edit it with VI. The destination I have chosen /data/ghost/themes is arbitrary, I just wanted to keep it in a directory that I back up, together with the rest of the Ghost custom config, and easy to remember so I can find it again.

cp /tmp/ghost-dump/var/lib/ghost/versions/2.20.1/content/themes/casper/post.hbs /data/ghost/themes
vim /data/ghost/themes/post.hbs

There is a part of the post file especially for embedding comment systems which can be injected with the Commento code. In the default post file for this version it looks like this:


            <section class="post-full-comments">
                If you want to embed comments, this is a good place to do it!


Remove the comment wrapper and add the code for your Commento server. It should end up something like this. Substitute your domain.


            <section class="post-full-comments">
<div id="commento"></div>
<script src=""></script>


Finally, mount the custom post.hbs over top of the default one inside the container by adding a second volume map inside the compose file. Update the origin path for your local configuration.

                        - /data/ghost:/var/lib/ghost/content
                        - /data/ghost/themes/post.hbs:/var/lib/ghost/content/themes/casper/post.hbs

The Ghost container will need a restart to map the new volume.

You might want to clean up the temporary dump you took of the Ghost container by removing /tmp/ghost-dump, or your equivalent.

Loading pages with your embedded comment system

Once you have followed the config procedures, added the site to Commento etc you should see the comment box appear under your articles. This example is from the default Ghost welcome page on a test server.

I can't imagine it's hugely difficult injecting a couple of lines into Wordpress or just about any web site code.

Page load performance with Commento - embedded on this site

Running the preview of this page through Webpagetest, I am getting a fully loaded page at 1.68 seconds. The Commento overhead is in the 1.3-1.7 second space. 0.2 seconds involves loading Source-sans fonts which may be an opportunity to remove later.

I'll be interested to see the impact on load times if I happen to get a page with a lot of comments.

That's about it. If the stars are aligned, you might also see a Commento box below this very article, which I hope you make use of. If you did follow this tech road, I hope you made it!

Main photo courtesy of Gritte on Unsplash