I am trying to create a broker server with eclipse-mosquitto with a docker compose file. The problem I’m facing that I cannot set users and passwords when starting the containers. I can set them after with docker exec
. Then I have to restart the whole container to see the effect. But this is inconvenient. Why do I have to restart the container to add a new user?
I’m explaining the problem in details here.
Here is the compose.yml
version: "3.7"
services:
mosquitto:
image: eclipse-mosquitto:latest
hostname: mosquitto
container_name: mosquitto
restart: on-failure
ports:
- "1883:1883"
- "9001:9001"
volumes:
- ./mosquitto:/etc/mosquitto
- ./mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf
- ./mosquitto/passwd:/etc/mosquitto/passwd
In the mosquitto
directory there is the mosquitto.conf
file.
listener 1883
persistence false
allow_anonymous false
password_file /etc/mosquitto/passwd
In the mosquitto
directory there is the passwd
file.
admin:admin
So when I start the container with:
docker compose up
In the log it will say:
mosquitto | 1717741186: Error: Invalid password hash type for user admin, removing entry.
This is understandable. Password should be hashed. So to fix this we can update the passwords file.Here is the way to pass the command.
docker exec mosquitto mosquitto_passwd -U /etc/mosquitto/passwd
After executing the command above the we will see the expected change in the passwd
file as following.
admin:$7$101$2XqvPb0X9ZyNy07v$/Dn0tnZ/yKX2IOVWxarHAc63ipjFw4ga/pRJaTOuQeyXxNPq3obtG60Wno3k+HGEOKVoGmfmquVsrYXycfGowQ==
But I cannot login now. But if I restart the container then I can login.
To update the passwd
file I added the command in compose file. But in that case it fails to up the compose file.
version: "3.7"
services:
mosquitto:
image: eclipse-mosquitto:latest
hostname: mosquitto
container_name: mosquitto
restart: on-failure
ports:
- "1883:1883"
- "9001:9001"
volumes:
- ./mosquitto:/etc/mosquitto
- ./mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf
- ./mosquitto/passwd:/etc/mosquitto/passwd
command: mosquitto_passwd -U /etc/mosquitto/passwd
This change will say:
mosquitto exited with code 0
However, it will update the passwd
file.
What am I missing? Kindly point me to the best practice of dockerization.
2
Answers
You need to run
mosquitto_passwd
manually before starting the service.You can’t modify the container or it’s startup command to always run
mosquitto_passwd -U /etc/mosquitto/passwd
, because that command can only be run once, running it twice on the same file uses the password hash as the input for the second hash which makes it useless.If you don’t have the mosquitto tools installed on the host machine you can do the following, which will mount the file into the container, generate the hashes and exit.
(the
$(pwd)
is because you can’t use relative paths for volume mounts on the command line unless you are using Docker v23 or newer docs)Because of your
volumes:
setup, the password file should be persisted on the host. If you delete and recreate the container (docker compose down; docker compose up -d
) it should keep the changed password. That means the one major problem is generating the password the first time.There is a
docker compose run
command that can run a one-off command, replacing thecommand:
in a container definition. Without changing anything, you should be able to runand it will launch a temporary container, using the
image:
andvolumes:
from the Compose file, but run that alternate command. That will create the password file, persisted on the host, and then you can rundocker compose up
normally.(Mounting the parent
/etc/mosquitto
directory will bring the passwd file in too, and it’s possible the separate/etc/mosquitto/passwd
mount causes problems, particularly on first startup. You don’t usually need to setcontainer_name:
orhostname:
and removing these will slightly simplify the Compose setup as well.)