# Quick Start - 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](broken://pages/pjiNwtHXpLCGzglvG2xI) 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.&#x20;

## (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:

```sh
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](https://docs.docker.com/network/drivers/bridge/) 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:

```sh
docker network create foxmq
```

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

```sh
docker network inspect foxmq
```

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

```json
[
    {
        "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](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing), 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](https://docs.docker.com/network/drivers/bridge/#connection-limit-for-bridge-networks).

### 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](https://en.wikipedia.org/wiki/Private_network#Private_IPv4_addresses) 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):

```sh
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](broken://pages/pjiNwtHXpLCGzglvG2xI#step-2-generate-an-address-book) 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](#option-1-let-docker-pick-an-ip-range) 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](broken://pages/pjiNwtHXpLCGzglvG2xI#step-2-generate-an-address-book) 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\
&#x20;(`--rm`), and mount a volume for the `foxmq.d/` folder for the command to write into, so we can use it outside.

```sh
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](broken://pages/pjiNwtHXpLCGzglvG2xI#step-3-create-user-credentials), just adapted for Docker.&#x20;

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:

```sh
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:

```toml
[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:

```sh
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:

```sh
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:

```sh
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](/resources/foxmq/quick-start-direct.md#optional-enable-tls-mqtts) 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,\
&#x20;`-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](/resources/foxmq/quick-start-direct.md#optional-enable-websockets-ws) 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,\
&#x20;`-p 8080:8080` for the first node, `-p 8081:8080` for the second, etc.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.tashi.network/resources/foxmq/quick-start-docker.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
