Quick Start - Docker

Quick start running FoxMQ in Docker

In addition to providing binaries for direct download (see previous page), we also provide FoxMQ as a Docker image for Linux on x86-64 (AMD64).

You can use this image in a similar manner to set up and start FoxMQ.

We recommend reading the Quick Start - Direct page to get a better understanding of what we'll be doing here. The steps can almost directly be transposed to Docker commands as you'll see shortly.

All commands in this article are written to be agnostic of the shell you're using.

(Optional) Step 1: Pull the Image

You can speed up later steps and ensure you're using the very latest image by pulling it first:

docker pull ghcr.io/tashigg/foxmq:latest

Step 2: Create a Bridge Network

To make container IPs easier to predict, which is important for generating the address book, we'll create a new bridge network in Docker for our FoxMQ containers.

You can use the default bridge network instead, but the starting IP address for new containers may be different depending on how many containers you already have running, so creating a fresh network is recommended.

Option 1: Let Docker pick an IP range

If you create a bridge network without specifying an IP range, Docker will pick an unused range for you:

docker network create foxmq

To get the IP address range, we can run the following command:

docker network inspect foxmq

The command will spit out a JSON blob that looks something like this:

[
    {
        "Name": "foxmq",
        "Id": "296c1dda0ee69719713a99ab4094f626fa37ea15d285492b8c6c6ca0b4f8f5a5",
        "Created": "2024-04-08T19:11:52.164859661-07:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

It's the Subnet key we're interested in. This tells us, in CIDR notation, what our IP address range is. /16 means the last two segments of the address are variable. (Tip: the /N is how many leading bits of the address are not variable. This is usually a multiple of 8, corresponding to the number of written segments, but doesn't have to be.)

Given that xx.xx.0.1 is reserved for the gateway by default, this tells us that, in this case, our IP address range will start at 172.18.0.2 and increment from there, wrapping at .255 to .2.0. This effectively gives us 65,535 possible IP addresses, though Docker recommends connecting fewer than 1000 containers to a bridge network at once.

Option 2: Choose an IP range

If, for whatever reason, you prefer to specify the IP range yourself, you may do so.

In this case, we recommend choosing a range from among the IPv4 address blocks reserved for private use to ensure you don't accidentally choose an address range that is routable on the public Internet.

For example, to create a network in the range 10.123.123.0 - 10.123.123.255 (256 possible addresses, minus one for the gateway):

docker network create --driver=bridge --subnet=10.123.123.0/24 --gateway=10.123.123.1 foxmq

Container IPs for this network will thus start at 10.123.123.2 and increment from there.

Step 3: Generate an Address Book

This step is identical to its counterpart in Quick Start - Direct but adapted for Docker, so instead of explaining the options again, we'll skip straight to showing how to use it to generate an address book for our created network from Option 1 above.

We'll assume that we're going to start 3 nodes (though 4 or more is recommended for high availability; see the corresponding section in Quick Start - Direct for further advice).

With the IP range we found from running docker network inspect foxmq as shown above, and FoxMQ's default cluster port of 19793, we can predict the following addresses for our nodes:

  • 172.18.0.2:19793

  • 172.18.0.3:19793

  • 172.18.0.4:19793

We can feed this list to foxmq address-book from-list to generate our address book.(Important: replace 172.18.0. with the IP prefix you determined in the previous step!)

Since we're running the command inside of a Docker container, we'll want to mark it as ephemeral (--rm), and mount a volume for the foxmq.d/ folder for the command to write into, so we can use it outside.

docker run --rm -v ./foxmq.d/:/foxmq.d/ ghcr.io/tashigg/foxmq:latest address-book from-list 172.18.0.2:19793 172.18.0.3:19793 172.18.0.4:19793

After this command exits, you should have a foxmq.d/ subdirectory containing your address book and keys.

Step 4: Create User Credentials

This step is also identical to its counterpart in Quick Start - Direct, just adapted for Docker.

We'll run the command just like the previous one, using an ephemeral container and mounting our foxmq.d/ directory as a volume, but we'll add -it to run the container in interactive mode with a pseudo-TTY so we can respond to the prompts:

docker run --rm -it -v ./foxmq.d/:/foxmq.d/ ghcr.io/tashigg/foxmq:latest user add

After this command returns, it should have created foxmq.d/users.toml. Run the command again to create more users.

Alternatively, to allow anonymous logins by default you can create foxmq.d/users.toml with the following contents:

[auth]
allow-anonymous-login = true

Step 5: Run FoxMQ

This time, we'll run the container in detached mode (-d) so it continues running in the background and give it a name so we can easily refer to it later.

Additionally, if we want to be able to talk to any node in the cluster from our MQTT client, we'll need to map the MQTT ports to unused ports on the host machine.

For example, if we decided on three nodes, we can use 1883 for the first node, 1884 for the second, 1885 for the third.

First node:

docker run -d --name=foxmq-0 --network=foxmq -p 1883:1883 -v ./foxmq.d/:/foxmq.d/ ghcr.io/tashigg/foxmq:latest run --secret-key-file=/foxmq.d/key_0.pem

Second node:

docker run -d --name=foxmq-1 --network=foxmq -p 1884:1883 -v ./foxmq.d/:/foxmq.d/ ghcr.io/tashigg/foxmq:latest run --secret-key-file=/foxmq.d/key_1.pem

Third node:

docker run -d --name=foxmq-2 --network=foxmq -p 1885:1883 -v ./foxmq.d/:/foxmq.d/ ghcr.io/tashigg/foxmq:latest run --secret-key-file=/foxmq.d/key_2.pem

You should now be able to connect an MQTT client to any of the forwarded ports.

Optional: Enable TLS (mqtts)

See the corresponding section in Quick Start - Direct for details. You can pass the same flags at the end of the above commands.

To use TLS from Docker, you'll want to forward port 8883 from the container as well. For example, -p 8883:8883 for the first node, -p 8884:8883 for the second, etc.

Optional: Enable Websockets (ws)

See the corresponding section in Quick Start - Direct for details. You can pass the same flags at the end of the above commands.

To use TLS from Docker, you'll want to forward port 8080 from the container as well. For example, -p 8080:8080 for the first node, -p 8081:8080 for the second, etc.

Last updated