HiveMQ

Port 80 already in use at startup in docker container

Hi,

we hit a strange issue when using the official Docker Image from Docker Hub (version 4.5.1). When we run the image in a container on Ubuntu 16.04 with Docker 17.12.0-ce the broker complains on startup:
Could not start Websocket Listener on port 80 and address 0.0.0.0. Is it already in use?

When we run the same container on Ubuntu 20.04 with Docker 20.10.2 everything works as expected. Is this a known incompatibilty?

Dockerfile:

FROM hivemq/hivemq4:4.5.1

COPY conf conf
COPY extensions extensions

EXPOSE 80
EXPOSE 8080
EXPOSE 8000

config.xml

<?xml version="1.0"?>
<hivemq xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="hivemq-config.xsd">

    <control-center>
        <enabled>true</enabled>
        <listeners>
            <http>
                <port>8000</port>
                <bind-address>0.0.0.0</bind-address>
            </http>
        </listeners>
    </control-center>

    <listeners>
        <tcp-listener>
            <port>1883</port>
            <bind-address>0.0.0.0</bind-address>
        </tcp-listener>
        <websocket-listener>
            <port>80</port>
            <bind-address>0.0.0.0</bind-address>
            <path>/mqtt</path>
            <allow-extensions>true</allow-extensions>
        </websocket-listener>
    </listeners>

   <mqtt>
        <queued-messages>
            <max-queue-size>100000</max-queue-size>
            <strategy>discard-oldest</strategy>
        </queued-messages>
    </mqtt>

    <overload-protection>
       <enabled>false</enabled>
   </overload-protection>
</hivemq>

Hey mirko, I think the problem is that we use a concept called privilege step-down by default in the image. The idea is that if the image is started as root user (which is the default), we start HiveMQ itself as a less privileged hivemq user for increased security.

This means that HiveMQ cannot bind to privileged ports like 80 by default. You can disable it using this env.

However, it usually shouldn’t be necessary to bind to privileged ports within a container. If you plan on exposing the websocket listener on port 80 on the host, you don’t need to bind it on :80 in the container. You can just bind it to 8083 for example and then map the port to :80 on the host instead for example.

1 Like

Thank you simon_b!

Good to know about this mechanism. I´ll check out the ENV setting to see if it fixes the issue. Nevertheless you are right. There is actually no need to use Port 80 in the first place in our current container setting.

What I do not understand though is how the same setup seems to work on Ubuntu 20 with the latest Docker engine. We´ll have another look.

Regards,
Mirko