Monday, May 4, 2020

Mumble server on a Raspberry Pi using Docker

I've recently needed to re-familiarize myself with the basics of Docker after some time away. A quick project to hit the ground running was launching a Mumble server (Murmur) on a Raspberry Pi 4 running Raspbian. There are certainly no shortage of Mumble servers on Docker Hub with the most popular one by far being this one. Unfortunately it won't do us any good as there is no armv7 build. Luckily, since Docker officially supports Alpine for armv7, and Murmur is packaged for Alpine, it is pretty easy to get up and running.


The first step is to install Docker on your Raspberry Pi. I simply followed a guide like this one.

Next, you'll need a Dockerfile:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
FROM alpine:latest
MAINTAINER Brandon Nielsen <bniels707@gmail.com>

RUN apk update && \
    apk add murmur

EXPOSE 64738/udp
EXPOSE 64738/tcp

USER murmur

ENTRYPOINT ["/usr/bin/murmurd","-fg"]

Looking at the Dockerfile, you can see we use the latest Alpine image, update the apk repository, and install Murmur using apk. We tell Docker to expose the required ports, both UDP and TCP. We change users to the 'murmur' user provided by the Murmur package so we don't have a server running a root. Finally, we run Murmur in the foreground ('-fg') so the Docker logs work correctly.

Simply save the code block as 'Dockerfile', and build it into a Docker image:

$ docker build -t murmur .

And run the image in a container publishing the necessary ports:

$ docker run murmur -p 64738:64738 -p 64738:64738/udp

The default publish behavior is TCP, note that we also need to publish the listening port specifically as UDP.

If everything worked correctly, 'docker ps' should show the container running with ports published (output abbreviated for clarity):

$ docker ps

CONTAINER ID        IMAGE      COMMAND                  PORTS                                             

1be5eb2ff2fa        murmur     "/usr/bin/murmurd -fg"   0.0.0.0:64738->64738/tcp, 0.0.0.0:64738->64738/udp

That should be it, you should now be able to connect to your Murmur server from a Mumble client (assuming you haven't set up a firewall on your Raspberry Pi). For the first sign on, you will want the 'SuperUser' password, which will be logged:

$ docker logs 1be5eb2ff2fa

<W>2020-05-05 11:44:37.837 SSL: OpenSSL version is 'OpenSSL 1.1.1d  10 Sep 2019'
<W>2020-05-05 11:44:37.837 Initializing settings from /var/lib/murmur/.murmurd/murmur.ini (basepath /var/lib/murmur/.murmurd)
<W>2020-05-05 11:44:40.040 MetaParams: TLS cipher preference is "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:AES256-SHA:AES128-SHA"
<W>2020-05-05 11:44:40.092 ServerDB: Opened SQLite database /var/lib/murmur/murmur.sqlite
<W>2020-05-05 11:44:40.092 ServerDB: Using SQLite's default rollback journal.
<W>2020-05-05 11:44:41.193 Performed initial PBKDF2 benchmark. Will use 4000 iterations as default
<W>2020-05-05 11:44:41.193 Generating new tables...
<W>2020-05-05 11:44:41.217 OSInfo: Failed to execute lsb_release
<W>2020-05-05 11:44:41.218 Murmur 1.3.0 (1.3.0) running on X11: Linux 4.19.97-v7l+: Booting servers
<W>2020-05-05 11:44:41.260 1 => Password for 'SuperUser' set to '7FeSHJrULfQ2'
<W>2020-05-05 11:44:41.307 1 => Server listening on 0.0.0.0:64738
<W>2020-05-05 11:44:41.316 1 => Failed to set IPV6_RECVPKTINFO for 0.0.0.0:64738
<W>2020-05-05 11:44:43.494 1 => Generating new server certificate.
<W>2020-05-05 11:44:47.797 1 => Announcing server via bonjour
<W>2020-05-05 11:44:47.806 1 => Registration needs nonempty 'registername', 'registerpassword' and 'registerurl', must have an empty 'password' and allowed pings.

In this case, the password was '7FeSHJrULfQ2'.

If you want to continue on with this guide, stop the container:

$ docker stop 1be5eb2ff2fa

It would be nice to handle publishing the ports "automatically", as well as being able to configure the server. For that we turn our attention toward docker-compose with the following 'docker-compose.yml':

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
version: '3.7'

services:
  mumble:
    build: ${PWD}/mumble-alpine
    restart: always
    ports:
      - 64738:64738/udp
      - 64738:64738/tcp
    volumes:
      - type: bind
        source: ${PWD}/murmur.ini
        target: /var/lib/murmur/.murmurd/murmur.ini
        read_only: true
      - data:/var/lib/murmur

volumes:
  data:

First this handles building the image (assuming the above Dockerfile is in the 'mumble-alpine' subdirectory), and exposes the ports (both UDP and TCP). The first volume bind mounts a configuration file ('mumur.ini') from our working directory into the container and exposes the Murmur data as a named volume, which allows for easily finding the data and backing it up if desired.

Not much is required for configuration, I recommend something like the following:

1
2
welcometext="<br />Welcome to the <b>Raspberry Pi</b> Mumble server.<br />"
registerName=Raspberry Pi Mumble

All we're doing is setting the welcome text (which supports some HTML and CSS), and the server name because it also serves as the default room name. Save this as 'mumur.ini'.

The above 'docker-compose.yml' assumes our original Dockerfile is in a 'mumble-alpine' subdirectory so move it there now if you haven't already. We can now rebuild the image, and run our server:

$ docker-compose build
$ docker-compose up -d

Again, 'docker ps' should show the result. You should be able to connect to your server now.

Assuming the default folders, the Murmur database will be available at:

/var/lib/docker/volumes/{{ PROJECT_DIR }}_data/_data/murmur.sqlite

where '{{ PROJECT_DIR }}' is the name of the folder your 'docker-compose.yml' file is contained in.

Whenever you change the configuration file, restart the server by running the following from the directory containing the compose file:

$ docker-compose restart

All in all, this makes for a pretty painless way to spin up and administrate a Mumble server and a good introduction to the 'docker' and 'docker-compose' commands.

No comments:

Post a Comment