Run one broker.
Docker listens on 18001 for HTTP admin and 9092 for Kafka PLAINTEXT, then forms a one-node group. Clients use 127.0.0.1:9092.
From a built image
Build the image from this repo, then publish the two ports. With no arguments, the entrypoint starts node 1, stores data in /data, and allows plaintext off loopback because the process is inside a container. It then posts /admin/init to itself so the single node becomes a group.
docker build -t camus .
docker run --rm -p 18001:18001 -p 9092:9092 camus
If you pass arguments, the entrypoint runs the broker with those flags and does not initialize the group, unless CAMUS_AUTO_INIT=1. The compose file uses that shape: the command is flags only, not the binary name.
From a checkout
The same shape, on loopback, with different ports so it does not collide with anything already bound to 9092. --dev-plaintext turns off TLS for a local listener. It is refused on a non-loopback address unless you also pass --allow-non-loopback. A checkout bound to 127.0.0.1 does not need that second flag. The Docker image sets it for you.
cargo run -p camus-broker -- \
--node-id 1 \
--http-addr 127.0.0.1:18080 \
--kafka-addr 127.0.0.1:19092 \
--data-dir /tmp/camus \
--dev-plaintext
curl -sf -X POST http://127.0.0.1:18080/admin/init \
-H 'content-type: application/json' \
-d '[{"id":1,"addr":"127.0.0.1:18080"}]'
The init body is the group: each member's id and the address the others use to reach its HTTP admin port. For one node, that address is the host and port you just bound. Do not point it at the Kafka port.
Know that it is up
GET /admin/metrics returns JSON. Before you produce, current_leader and wal_leader should both be 1 on this one-node group. GET /metrics is the same process in Prometheus text. The address in the init body is the HTTP admin port the other brokers dial, not the Kafka port.
The bucket is separate
The process will start without MinIO. A wal produce can be acknowledged after the disk quorum, and the later upload will fail if there is no bucket. Create the bucket before you care about the sealed log. The defaults and the container caveat are on the bucket page.