docker matrix

Matrix bot: Maubot on Docker

Beep, boop, I’m a bot

maubot is a bot system for Matrix, the decentralised messaging platform. The good folks in the room I hang out in have expressed a desire for a bot on occasion, so I thought I’d check it out.

While it’s described as a ‘system’, maubot can just as happily run one a single bot, if that’s what you want. Features are provided by plugins- maubot won’t do anything out of the box.

It has a Docker image, so I figured I’d use that. I followed the instructions on the Wiki page with only minor modification:

0. Create a directory (mkdir maubot) and enter it (cd maubot).

1. Pull the docker image with docker pull

2. Run the container for the first time to create a config file:

docker run --rm -v `pwd:/data:z

3. Update the config to your liking. I added a username with password in the admins section, and my homeserver in the registration_secrets section.

I then created a short docker-compose.yml file:

version: "3"
    container_name: maubot
      - /home/robert/docker-containers/maubot:/data:z
      - 29316:29316
    restart: unless-stopped
      - "traefik.http.routers.maubot.rule=Host(``)"

      name: traefik_default

And start with docker-compose up -d.

(The traefik labels make the service available via

Setting up a Bot

This gets you a management interface, but the bot itself needs to be set up. It’s not entirely obvious, though the instructions are present elsewhere in the wiki.

I manually created a user using the Riot web interface; though there are instructions on how to do it via CLI using mbc. If you go the manual route the access token that maubot asks for can be yound by clocking your avatar/username dropdown in the top left to access ‘Settings’ -> ‘Help & About’ -> ‘Access Token’:

Once done, you should have a bot:

But it won’t do anything just yet, you need to add plugins!

As an aside, I managed to run into a permissions issue at this point, where the maubot interface wasn’t responding via HTTP, and docker logs was complaining:

[2019-11-29 19:18:15,617] [INFO@maubot.init] Initializing maubot 0.1.0.dev28
[2019-11-29 19:18:15,618] [] Preloading plugins...
Traceback (most recent call last):                             
  File "/usr/lib/python3.7/", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.7/", line 85, in _run_code
    exec(code, run_globals)
  File "/opt/maubot/maubot/", line 58, in <module>
  File "/opt/maubot/maubot/loader/", line 270, in init
  File "/opt/maubot/maubot/loader/", line 253, in load_all
    for file in os.listdir(directory):
PermissionError: [Errno 13] Permission denied: '/data/plugins'

It’s simplest to upload the desired plugins from the web interface itself. As the wiki points out elsewhere:

To add a plugin, upload a zip file containing the maubot.yaml and relevant files at the top level. Github releases of plugins have those premade (see i.e. – file casavant.tom.poll-v1.0.0.mbp) – has a CI that makes those. Also, mbc build will make those with the relevant files.

So, for the echo plugin, go to its GitHub releases page, grab the file xyz.maubot.echo-v1.3.1.mbp and upload that to the maubot web interface by hitting the plus arrow beside ‘plugins’.

Alternatively, you can compile the plugins to a .mbp yourself: clone the main maubot repo, run to get the dependencies, then clone the plugin[s] in maubot’s directory, and finally run mbc build <plugin> for the plugin you just cloned (per mChron’s comment).

Once you have the plugins you want, create an instance for them and assign them to the bot client. That interface will also show you configuration options and let you view logs, if needed. Then you’re good to go!

docker troubleshooting

Using Discourse Dev with Traefik (without ‘Bad Gateway’ + ‘blocked host’)


  • Traefik grabs the first port it sees, which on the dev image is 1080- we want port 9292. Use --label=traefik.http.routers.discourse-dev.port=9292
  • You need to set a dev host using en env var in the container: -e DISCOURSE_DEV_HOSTS=your_dev_hostname \

With the dev version of Discourse working, I wanted to let its connectivity be managed by the traefik proxy. But whichever way I sliced it, I would get a Bad Gateway error. The usual suspect for this is not setting a port, or having the service on a different network from traefik itself. However, this issue persisted for me.

I had to add the following to (discourse_source_root)/bin/docker/boot_dev, in the docker run ... section:

    --network=traefik_default \
    --label=traefik.port=80 \ \
    --label=traefik.http.routers.discourse-dev.rule=Host\(\`$DEVHOST\`\) \ \

I set DEVHOST=<my dev host> earlier in the file, or you can use the host there directly. The last line points traefik at the correct port (9292) in the discourse-dev container.

Accessing by host then produces a page with a blocked host error:

Blocked host: discourse_dev_host
To allow requests to discourse_dev_host, add the following to your environment configuration:
config.hosts << “discourse_dev_host”

Setting DISCOURSE_DEV_HOSTS permits access on those hosts. We need to do this in the container, so add the following to the same section in the same file:


Which permits access via that (or those) hostname(s).

docker linux troubleshooting

[solved] ‘Connection closed’ in Discourse Dev Install

tl;dr: this was a temporary issue solved by a later commit, if you checked out discourse after 28 Oct but before 4 Nov, git pull to update

Having installed a production Discourse forum, I wanted to get a local dev instance up and running for testing.

There are good instructions for doing just that using Docker. Don’t do what I did: follow the production install method and assume that will work by pointing the prod hostname at it in /etc/hosts.

Unfortunately, when I followed the instructions to set up the dev instance, I was greeted with an ‘Unable to connect’ screen. (ERR_FAILED). Even using telnet from the same host failed:

bertieb@ubunutu-vm:~/discourse$ telnet 9292
Connected to
Escape character is '^]'.
Connection closed by foreign host.

Dang. I tried this across fresh Arch and Ubuntu Server (19.10 + 18.04.3 LTS) installs and got the same thing.

Installing the non-Docker version worked but only for localhost; then a comment on that guide’s topic pointed me at a recent change to interface binding. Checking out the commit before that change let me connect from other hosts in both the Docker and non-Docker versions.

As of 2019-11-04 a later commit sorted this issues and added a specific flag (-b) for permitting connections from other hosts.

linux software

Adding Discourse to a mix of nginx-hosted sites [How]

I set up a Discourse server today. It was pleasantly straightforward. The official docs work well enough, though there are a few things I did:

  • integrated with existing nginx sites by cribbing from this guide (short version: forward Discourse requests to a socket)
  • set up email delivery via MailJet- their admin interface makes getting credentials and setting up + verifying SPF and DKIM records simple
  • set up certbot to generate LetsEncrypt certs (thanks Arch wiki) and get HTTPS rolling (bonus: https for existing sites for free!)
  • added SSO for GitHub and Discord (short version: create the applications on the respective sites, support for these Oauth is baked in)
  • typoed DenyUsers as DenyUser, locking myself out of ssh access

Maybe skip the last one if you’re doing the install yourself?