skip to Main Content

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


  1. 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.

    docker run -it --rm -v $(pwd)/mosquitto/passwd:/etc/mosquitto/passwd eclipse-mosquitto:latest mosquitto_passwd -U /etc/mosquitto/passwd
    

    (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)

    Login or Signup to reply.
  2. 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 the command: in a container definition. Without changing anything, you should be able to run

    docker compose run mosquitto 
      mosquitto_passwd -U /etc/mosquitto/passwd
    

    and it will launch a temporary container, using the image: and volumes: from the Compose file, but run that alternate command. That will create the password file, persisted on the host, and then you can run docker 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 set container_name: or hostname: and removing these will slightly simplify the Compose setup as well.)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search