gcgarner/IOTstack

running rtl_433 container problem

bogus105 opened this issue Β· 7 comments

Dear Fellows,

On my RB Pi4 i'm running IoTstack so docker with number of containers. One of the containers is rtl_433. When i enter the rtl_433 container via container manager (i'm using Portainer) and start its console and enter:
rlt_433
i'm getting:
usb_claim_interface error -6
rlt_433 issue1

I've read that it might be the problem that other piece of software accessed this usb prior rtl_433. But everything is inside container and i can not figure out how to obey this issue. I'm not Linux expert:(

I've connected to my headless Pi with Putty and tried to use "rtl_433" there but i got "-bash: rtl_433: command not found" which is not surprising for me as rtl is hidden inside container...
Please direct me toward good direction.
Thank you

i've already checked, using "lsmod", if there are some drivers in use and , as per advise from on github, used:
echo 'blacklist dvb_usb_rtl28xxu' | sudo tee --append /etc/modprobe.d/blacklist-dvb_usb_rtl28xxu.conf
and checked the drivers again. There was no things related to rtl/dvb after blacklistinh it. The problem however remains - in rtl_433 container's console when i use:
rtl_433
i'm still getting "usb_claim_interface error -6"

First, if you're wondering at the comparative silence in response to your question, perhaps see this project is dormant.

Second, once you read the above, I'd recommend joining the Discord channel. You'll find a link on the SensorsIot site (which is linked to in the above). You might find someone on the channel who knows about this stuff. You can also re-post your question as an issue on that repo if what I'm about to say doesn't help.

Third, despite owning an SDR dongle for a couple of years, I'd never actually heard of rtl_433 until I read your issue. The only time I use my dongle is on an iMac with CubicSDR so I can "see" LoRa transmissions while I'm testing gizmos. I mention this so you can judge what I say next.

Having dug around a bit, I now have some idea of what rtl_433 is meant to do and I'm thinking "cool, I might give that a whirl". But it'll probably be on the to-do list for a while.

My "experience" is more in the IOTstack and Docker side of things, and it's that which has aroused my curiosity about this issue. I look at how rtl_433 is built for IOTstack and it occurs to me to ask you a couple of questions, including how long ago did you start to use rtl_433, did it ever actually work, how long has it been working, and do you have any theories on why it might have stopped? Sort of "please colour in the picture" kinds of questions.

Why? Well, it looks to me like the gcgarner/IOTstack template for the rtl_433 container was set up a good two years ago. SensorsIot/IOTstack is using the same template. The template builds the service from scratch as a local container on top of debian:buster-slim.

There is nothing wrong with this approach but there are some issues around building containers this way to make sure they are fit for purpose, so that's why I'd like to get a feeling for your timeframes.

I just spun-up the container myself "as is" and noticed a whole bunch of grizzles as it went along:

-- Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR (missing: OPENSSL_CRYPTO_LIBRARY OPENSSL_INCLUDE_DIR) 
-- OpenSSL development files not found, TLS won't be possible.
-- Could NOT find PkgConfig (missing: PKG_CONFIG_EXECUTABLE) 
-- Could NOT find SoapySDR (missing: SoapySDR_DIR)
-- SoapySDR development files not found, SoapySDR device input won't be possible.
-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE) 

I doubt that Doxygen is an issue, SSL might not be, PkgConfig might be, while a missing SoapySDR could well be the cause of some conniptions.

What might be going on is this chunk of the Dockerfile:

RUN apt-get update && apt-get install -y  git libtool libusb-1.0.0-dev librtlsdr-dev rtl-sdr cmake automake && \
	git clone https://github.com/merbanan/rtl_433.git /tmp/rtl_433 && \
	cd /tmp/rtl_433/ && \
	mkdir build && \
	cd build && \
	cmake ../ && \
	make && \
	make install

See how it is installing dependencies (git, libtool, etc) then doing the clone from git and build steps. It's possible that just adding more dependencies will solve the problem. But don't rush to do anything yet. Keep reading.

If that's the explanation, I can kind of understand how it happens. Two years is a long time. The rtl_433 repo moves on. The Debian base moves on. If nobody does any maintenance...

The doubt you might sense in my words is because of:

$ lsusb
Bus 001 Device 003: ID 0bda:2838 Realtek Semiconductor Corp. RTL2838 DVB-T

In short, my RPi4 can "see" my SDR dongle and the "as is" container itself seems reasonably happy:

$ docker logs rtl_433 
rtl_433 version 21.05-1-ga773fd0a branch master at 202105091257 inputs file rtl_tcp RTL-SDR
Use -h for usage help and see https://triq.org/ for documentation.
Trying conf file at "rtl_433.conf"...
Trying conf file at "/root/.config/rtl_433/rtl_433.conf"...
Trying conf file at "/usr/local/etc/rtl_433/rtl_433.conf"...
Trying conf file at "/etc/rtl_433/rtl_433.conf"...
Publishing MQTT data to mosquitto port 1883
Publishing events info to MQTT topic "RTL_433".
Registered 157 out of 186 device decoding protocols [ 1-4 8 11-12 15-17 19-23 25-26 29-36 38-60 63 67-71 73-100 102-105 108-116 119 121 124-128 130-149 151-161 163-168 170-175 177-186 ]
Found Rafael Micro R820T tuner
Exact sample rate is: 250000.000414 Hz
[R82XX] PLL not locked!
Sample rate set to 250000 S/s.
Tuner gain set to Auto.
Tuned to 433.920MHz.
Allocating 15 zero-copy buffers
baseband_demod_FM: low pass filter for 250000 Hz at cutoff 25000 Hz, 40.0 us
MQTT Connected...
MQTT Connection established.

Yet you have this "claim" problem which I'm not seeing ...

But, let's put a pin in that.


As I said, two years is a long time and the world has moved on. After a fair amount of futzing around, I have come up with this replacement for rtl_433 in docker-compose.yml:

  rtl_433:
    container_name: rtl_433
    image: hertzg/rtl_433:debian
    devices:
      - '/dev/bus/usb/001/003'
    command:
      - '-Mtime:unix:usec:utc'
      - '-Mbits'
      - '-Mlevel'
      - '-Mprotocol'
      - '-Mstats:2:300'
      - '-Fmqtt://mosquitto:1883,retain=1'
      - '-Finflux://influxdb:8086/write?db=rtl433'
    volumes:
      - ./volumes/rtl_433/config:/root
    depends_on:
      - mosquitto
      - influxdb
#   networks:
#     - iotstack_nw

Some of that is from hertzg/rtl_433_docker, some of it is my own, based on experience.

You'll need to do a bit of spade-work to try it out:

$ cd ~/IOTstack
$ docker-compose stop rtl_433
$ docker-compose rm -f rtl_433
$ docker rmi iotstack_rtl_433:latest debian:buster-slim

then edit docker-compose.yml to comment-out the current service definition and replace it with the above.

The two lines at the end that are commented-out are to do with "new menu" in SensorsIot/IOTstack but I will assume you will know whether you need that or not.

When an issue is opened on gcgarner/IOTstack, it is never 100% clear whether the person opening the issue is still running gcgarner, or migrated to SensorsIot some time ago but opened the issue on the old repo in error. If you're still on gcgarner then the answer is that you don't need those lines.

I also noticed the mention of "influxdb" in the docker-compose.yml fragment so I took the precaution of creating the database "rtl433" before I spun up rtl_433. That's because Influx can sometimes get a bit pernickety if something tries to write to a non-existent database.

Anyway, when I spin-up that revised service definition, I get:

$ docker logs rtl_433 
rtl_433 version 21.05-1-ga773fd0a branch master at 202105091257 inputs file rtl_tcp RTL-SDR SoapySDR
Use -h for usage help and see https://triq.org/ for documentation.
Trying conf file at "rtl_433.conf"...
Trying conf file at "/root/.config/rtl_433/rtl_433.conf"...
Trying conf file at "/usr/local/etc/rtl_433/rtl_433.conf"...
Trying conf file at "/etc/rtl_433/rtl_433.conf"...
Publishing MQTT data to mosquitto port 1883
Publishing device info to MQTT topic "rtl_433/55cd54a7c43f/devices[/type][/model][/subtype][/channel][/id]".
Publishing events info to MQTT topic "rtl_433/55cd54a7c43f/events".
Publishing states info to MQTT topic "rtl_433/55cd54a7c43f/states".
Publishing data to InfluxDB (http://influxdb:8086/write?db=rtl433)
Registered 157 out of 186 device decoding protocols [ 1-4 8 11-12 15-17 19-23 25-26 29-36 38-60 63 67-71 73-100 102-105 108-116 119 121 124-128 130-149 151-161 163-168 170-175 177-186 ]
Detached kernel driver
Found Rafael Micro R820T tuner
Exact sample rate is: 250000.000414 Hz
[R82XX] PLL not locked!
Sample rate set to 250000 S/s.
Tuner gain set to Auto.
Tuned to 433.920MHz.
Allocating 15 zero-copy buffers
baseband_demod_FM: low pass filter for 250000 Hz at cutoff 25000 Hz, 40.0 us
MQTT Connected...
MQTT Connection established.

If you compare/contrast the two sets of logs outputs, they are pretty close. The same version and registration of "157 out of 186 device decoding protocols". The key differences:

  • hertzg/rtl_433 mentions "SoapySDR" at the end of the first line. So, the image on DockerHub has fixed whatever causes its omission from the IOTstack Dockerfile-from-scratch approach.
  • it has (in my view) a more sensible MQTT message structure.
  • "Detached kernel driver" - whatever that means.

The key similarity, of course, is:

Found Rafael Micro R820T tuner

There were some swings and roundabouts getting to this point. I'm going to explain this so you don't fall into the same holes. I began with:

image: hertzg/rtl_433:latest

but that pulled down an image built on top of Alpine Linux. Nothing wrong with that but it chucked up:

Assertion failed: clock_gettime(1, tp) == 0 (libusbi.h: usbi_get_monotonic_time: 497)

I traced that to hertzg/rtl_433_docker Issues 3 which, strangely enough, is "closed" even though it still seems to be a current issue.

I tried the recommended fix:

image: hertzg/rtl_433:alpine-3.12-latest

but that was pretty ancient (January) and the "n" and "m" in "Registered n out of m device" was a bit lower. The logical conclusion is that whatever ails Alpine is taking a long time to fix. There can be good reasons to pin to old versions but I'd always try to find another way first.

The list of tags at hertzg/rtl_433_docker implied Debian might work so I took myself to DockerHub, nosed around and selected:

image: hertzg/rtl_433:debian-latest-19.08

which seemed to work, so I took the pin off that to arrive at my final answer of:

image: hertzg/rtl_433:debian

which also seemed to work.

Along the way, I also set up a mosquitto subscriber:

$ mosquitto_sub -v -h "127.0.0.1" -t "#" -F "%I %t %p"

but it wasn't showing me anything. Influx was also remaining silent so I had no idea whether anything was actually working.

I live in a small town in country NSW. Between the size of the town, my total ignorance of whether 433MHz is common in Australia (eg LoRa uses 915MHz as part of the ISM band), and the total silence from the monitoring tools, I wondered whether anything was happening…

… but, then, mosquitto_sub suddenly emitted a ton of junk. I left it for a while and, yes, I am getting sporadic MQTT messages. Stuff is also getting into the database:

$ influx -database rtl433
Connected to http://localhost:8086 version 1.8.5
InfluxDB shell version: 1.8.5

> show series
key
---
rtl_433_55cd54a7c43f

> select * from rtl_433_55cd54a7c43f tz('Australia/Sydney')
name: rtl_433_55cd54a7c43f
time                             enabled frames                          since               stats
----                             ------- ------                          -----               -----
2021-05-16T12:04:21.278819+10:00 157     {"count":8,"fsk":0,"events":0}  2021-05-16T01:59:21 array
2021-05-16T12:09:21.160893+10:00 157     {"count":16,"fsk":0,"events":0} 2021-05-16T02:04:21 array
2021-05-16T12:14:21.043313+10:00 157     {"count":2,"fsk":0,"events":0}  2021-05-16T02:09:21 array
2021-05-16T12:19:21.45121+10:00  157     {"count":2,"fsk":0,"events":0}  2021-05-16T02:14:21 array
2021-05-16T12:24:21.334472+10:00 157     {"count":8,"fsk":0,"events":0}  2021-05-16T02:19:21 array
2021-05-16T12:29:21.216516+10:00 157     {"count":3,"fsk":0,"events":0}  2021-05-16T02:24:21 array
2021-05-16T12:34:21.099328+10:00 157     {"count":1,"fsk":0,"events":0}  2021-05-16T02:29:21 array
2021-05-16T12:39:20.982378+10:00 157     {"count":2,"fsk":0,"events":0}  2021-05-16T02:34:21 array
2021-05-16T12:44:21.389641+10:00 157     {"count":4,"fsk":0,"events":0}  2021-05-16T02:39:21 array
2021-05-16T12:49:21.273341+10:00 157     {"count":3,"fsk":0,"events":0}  2021-05-16T02:44:21 array
2021-05-16T12:54:21.156781+10:00 157     {"count":1,"fsk":0,"events":0}  2021-05-16T02:49:21 array
2021-05-16T12:59:21.038745+10:00 157     {"count":0,"fsk":0,"events":0}  2021-05-16T02:54:21 array
2021-05-16T13:04:20.919156+10:00 157     {"count":3,"fsk":0,"events":0}  2021-05-16T02:59:21 array
2021-05-16T13:09:21.324682+10:00 157     {"count":1,"fsk":0,"events":0}  2021-05-16T03:04:21 array
2021-05-16T13:14:21.206708+10:00 157     {"count":14,"fsk":0,"events":0} 2021-05-16T03:09:21 array
2021-05-16T13:19:21.089145+10:00 157     {"count":17,"fsk":0,"events":0} 2021-05-16T03:14:21 array
2021-05-16T13:24:20.971748+10:00 157     {"count":9,"fsk":0,"events":0}  2021-05-16T03:19:21 array
2021-05-16T13:29:21.378822+10:00 157     {"count":17,"fsk":0,"events":0} 2021-05-16T03:24:21 array
2021-05-16T13:34:21.26085+10:00  157     {"count":8,"fsk":0,"events":0}  2021-05-16T03:29:21 array
2021-05-16T13:39:21.142616+10:00 157     {"count":8,"fsk":0,"events":0}  2021-05-16T03:34:21 array
> exit
$ 

I've also added:

    volumes:
      - ./volumes/rtl_433/config:/root

This is something you won't see in either the gcgarner or SensorsIot templates or, indeed, in the various examples. I just noticed these lines:

Trying conf file at "rtl_433.conf"...
Trying conf file at "/root/.config/rtl_433/rtl_433.conf"...
Trying conf file at "/usr/local/etc/rtl_433/rtl_433.conf"...
Trying conf file at "/etc/rtl_433/rtl_433.conf"...

I wondered what would happen if I mapped one of those. Opening a shell into the running container arrived at /root as the working directory so I assumed rtl_433 (the process) was looking for the file named rtl_433.conf in that directory. Mapping that to an IOTstack-compliant volumes path results in docker-compose auto-creating the left hand side on first launch. Then I did:

$ sudo touch ~/IOTstack/volumes/rtl_433/config/rtl_433.conf

and restarted the container. The log changed to be:

Trying conf file at "rtl_433.conf"...
Reading conf from "rtl_433.conf".

In short, there is an easy mechanism for "configuring" rtl_433, assuming that is something a sophisticated user of this container is likely to want to do.

ANYWAY, it would be helpful if you could try this out and see if it solves your problem.

Even if it doesn't we'll be slightly further forward because this service definition clearly "works", albeit with my dongle and RPi4. If you still get:

usb_claim_interface error -6

then we will have narrowed it down to something peculiar about your system, and that will also get back to whether you are running gcgarner or SensorsIot, and when you installed it.

Assuming you get the same "claim" message, I have a suspicion about the cause but I won't be able to confirm that until I get some more info from you.

Hope this helps.

Another thing I've just noticed in the influx database is:

> show series
key
---
rtl_433_234e0f4fcf6b
rtl_433_55cd54a7c43f
rtl_433_e3852ecbbf92

Those suffixes are from the container identifier, which gets regenerated each time a container is reconstructed from an image:

$ docker exec rtl_433 uname -a
Linux 234e0f4fcf6b 5.10.17-v7l+ #1414 SMP Fri Apr 30 13:20:47 BST 2021 armv7l GNU/Linux

Sort of faked me out for a while. I could see MQTT traffic but it wasn't showing up in the database. My guess is this is something that would be configurable.

update on situation: my last try was to test different usb cables between rtl sharp dongle and my RB Pi4, last try was to connect RTL directly to Pi usb - it was barely possible as usb ports on Pi are very close to each other and as i'm using SSD drive as boot device and storage - my USB-SSD adapter plug is bit big. Finally i've managed to insert it and it is working now! At that time i was in hotel and in Node-Red debug node i found i can see many infos from TPS sensors of the cars parked around the hotel:D:D So i know that on Ford one tire was almost flat reporting 0.85 bar while everythig was ok on some Toyoda, Renault, another Fors and so on:) There was no weather stations around however but i'm sure i can pick my neighbours wheaterstations now:D
thanks!

@Paraphraser - thanks for your very complete response. I was having a problem getting the Mosquitto container to start correctly and you provided a breadcrumb with your comment:

`I wondered what would happen if I mapped one of those. Opening a shell into the running container arrived at /root as the working directory so I assumed rtl_433 (the process) was looking for the file named rtl_433.conf in that directory. Mapping that to an IOTstack-compliant volumes path results in docker-compose auto-creating the left hand side on first launch. Then I did:

$ sudo touch ~/IOTstack/volumes/rtl_433/config/rtl_433.conf`

...
Similarly, I noticed that the Mosquitto container's /mosquitto/config/mosquitto.conf didn't exist, so similar to manually creating the rtl_433.conf file, I created the mosquitto.conf file and after restarting the mosquitto container, viola - mosquitto started and the rtl_433 connected to it via the Docker network.

Thanks!

Hi @cklann1 ,

Just like happened with my original response to this issue, what you've just written also makes me wonder whether you are using:

The reason why I'm wondering is because, with SensorsIot/IOTstack, there should never be any situation where mosquitto.conf doesn't exist.

Let me explain. If you are using SensorsIot then you should see the following:

$ tree ~/IOTstack/.templates/mosquitto/
/home/pi/IOTstack/.templates/mosquitto/
β”œβ”€β”€ docker-entrypoint.sh
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ iotstack_defaults
β”‚   β”œβ”€β”€ config
β”‚   β”‚   β”œβ”€β”€ filter.acl
β”‚   β”‚   └── mosquitto.conf
β”‚   └── pwfile
β”‚       └── pwfile
β”œβ”€β”€ iotstack_healthcheck.sh
└── service.yml

Everything in the iotstack_defaults directory gets embedded into the Mosquitto image when the container gets built. That includes the mosquitto.conf file.

I'll do a walk-through beginning with the default service definition:

$ cat ~/IOTstack/.templates/mosquitto/service.yml 
mosquitto:
  container_name: mosquitto
  build:
    context: ./.templates/mosquitto/.
    args:
    - MOSQUITTO_BASE=eclipse-mosquitto:latest
  restart: unless-stopped
  environment:
    - TZ=Etc/UTC
  ports:
    - "1883:1883"
  volumes:
    - ./volumes/mosquitto/config:/mosquitto/config
    - ./volumes/mosquitto/data:/mosquitto/data
    - ./volumes/mosquitto/log:/mosquitto/log
    - ./volumes/mosquitto/pwfile:/mosquitto/pwfile

The only difference between that and what's in your docker-compose.yml should be the TZ set to your own timezone.

The build clause sends docker-compose to:

~/IOTstack/.templates/mosquitto/Dockerfile

The relevant lines in that are:

# where IOTstack template files are stored
ENV IOTSTACK_DEFAULTS_DIR="iotstack_defaults"

# copy template files to image
COPY --chown=mosquitto:mosquitto ${IOTSTACK_DEFAULTS_DIR} /${IOTSTACK_DEFAULTS_DIR}

In words, "copy iotstack_defaults into the image". If you look through the Dockerfile, you'll see that docker-entrypoint.sh is also copied into the image.

The docker-entrypoint.sh script runs each time the container starts. The relevant line in that is:

rsync -arpv --ignore-existing /${IOTSTACK_DEFAULTS_DIR}/ "/mosquitto"

In words, "compare the templates directory with the /mosquitto directory and replace anything that has gone missing".

This check to replace missing files occurs every time the container starts. Here's a practical example:

$ DPS mosquitto
NAMES       CREATED      STATUS
mosquitto   2 days ago   Up 2 days (healthy)

Mosquitto is running. Move to its persistent storage and see what's to be seen:

$ cd ~/IOTstack/volumes/mosquitto/
$ tree
.
β”œβ”€β”€ config
β”‚   β”œβ”€β”€ filter.acl
β”‚   └── mosquitto.conf
β”œβ”€β”€ data
β”‚   └── mosquitto.db
β”œβ”€β”€ log
└── pwfile
    └── pwfile

Rename the configuration file so the rsync inside the docker-entrypoint.sh script will not find it:

$ sudo mv config/mosquitto.conf config/mosquitto.conf.off
$ tree
.
β”œβ”€β”€ config
β”‚   β”œβ”€β”€ filter.acl
β”‚   └── mosquitto.conf.off
β”œβ”€β”€ data
β”‚   └── mosquitto.db
β”œβ”€β”€ log
└── pwfile
    └── pwfile

Restart the container:

$ RESTART mosquitto
[+] Running 1/1
 β Ώ Container mosquitto  Started                                                                                        1.2s

$ tree
.
β”œβ”€β”€ config
β”‚   β”œβ”€β”€ filter.acl
β”‚   β”œβ”€β”€ mosquitto.conf
β”‚   └── mosquitto.conf.off
β”œβ”€β”€ data
β”‚   └── mosquitto.db
β”œβ”€β”€ log
└── pwfile
    └── pwfile

See how mosquitto.conf has come back? Is mine the same as the default?

$ diff config/mosquitto.conf config/mosquitto.conf.off 
17,19d16
< # Reduce size and SD-card flash wear, safe to remove if using a SSD
< connection_messages false
< 

Something has been added to the default since my Mosquitto was first spun up. I've never adopted that because my mosquitto.conf has never gone walkabout.

Put things back the way they were.

$ sudo mv config/mosquitto.conf config/mosquitto.conf.new
$ sudo mv config/mosquitto.conf.off config/mosquitto.conf

$ RESTART mosquitto
[+] Running 1/1
 β Ώ Container mosquitto  Started                                                                                        1.2s

$ tree
.
β”œβ”€β”€ config
β”‚   β”œβ”€β”€ filter.acl
β”‚   β”œβ”€β”€ mosquitto.conf
β”‚   └── mosquitto.conf.new
β”œβ”€β”€ data
β”‚   └── mosquitto.db
β”œβ”€β”€ log
└── pwfile
    └── pwfile

$ diff config/mosquitto.conf config/mosquitto.conf.new
16a17,19
> # Reduce size and SD-card flash wear, safe to remove if using a SSD
> connection_messages false
> 

You can see that, if mosquitto.conf isn't present, it gets replaced with the default from the template. The same would happen if filter.acl went missing. That "replace if missing" is the only thing that happens but it does always happen.

A file differing from its template is left alone, as are any extra files that don't have a counterpart in the template directory.

Two things should be evident:

  1. Using touch to create mosquitto.conf should never have been necessary.
  2. Using touch to create mosquitto.conf would have created an empty file that didn't contain any of the directives that, in theory at least, are actually needed to make Mosquitto function properly:
$ grep -v -e "^#" -e "^$" ~/IOTstack/.templates/mosquitto/iotstack_defaults/config/mosquitto.conf 
listener 1883
persistence true
persistence_location /mosquitto/data
log_dest stdout
log_timestamp_format %Y-%m-%dT%H:%M:%S
connection_messages false
allow_anonymous true

My understanding is that listener and allow_anonymous are pretty much essential. I think the former is always needed, the latter until you set up a credential system.

There's more background on the theory of all this at Issue 331.

I hope you see why you reporting needing to create mosquitto.conf made me sit up and repeat the words uttered by many an IT person the world over:

"but ... that can't be!"

😎

Another question that comes up from time to time in the Mosquitto context is why the service definition has:

volumes:
- ./volumes/mosquitto/config:/mosquitto/config
- ./volumes/mosquitto/data:/mosquitto/data
- ./volumes/mosquitto/log:/mosquitto/log
- ./volumes/mosquitto/pwfile:/mosquitto/pwfile

In theory, that should be reducible to just:

volumes:
- ./volumes/mosquitto:/mosquitto

The reason is because the base image for mosquitto (the one that comes down from DockerHub and is the starting point for the iotstack-mosquitto image) defines:

- ./volumes/mosquitto/data:/mosquitto/data
- ./volumes/mosquitto/log:/mosquitto/log

but leaves the other two undefined. To be compatible with that, we need to define the other two sub-directories explicitly.

Given that Mosquitto pretty much won't work without a config and empty password file, their omission from the base image is curious. I keep hoping that, one day, I'll learn enough about Docker to be able to do a forehead-slap and say "Ah! Of course! That's why the base image for Eclipse-Mosquitto is built that way."