The image maps environment variables to properties (KAFKA_NUM_PARTITIONS becomes num.partitions), and setting any of them replaces its whole default configuration, so a Compose file must supply the full KRaft minimum. This combined node has three listeners: DOCKER for containers on the l3-booknest network, CONTROLLER for the quorum, and HOST for programs on the workstation, published on port 33092.
# single.yaml: one combined broker and controller in KRaft mode (Kafka 4.3.1)
name: l3-kafka
services:
kafka:
image: apache/kafka:4.3.1
container_name: l3-kafka
ports: ["33092:9094"] # host clients use localhost:33092
environment:
CLUSTER_ID: BlU5rkQ7TciwZo42azfLxA
KAFKA_NODE_ID: 1
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@l3-kafka:9093
KAFKA_LISTENERS: DOCKER://:9092,CONTROLLER://:9093,HOST://:9094
KAFKA_ADVERTISED_LISTENERS: DOCKER://l3-kafka:9092,HOST://localhost:33092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: >-
DOCKER:PLAINTEXT,CONTROLLER:PLAINTEXT,HOST:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: DOCKER
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LOG_DIRS: /var/lib/kafka/data
KAFKA_NUM_PARTITIONS: 3
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 # one broker cannot hold
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 # three copies of the
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1 # internal topics
KAFKA_SHARE_COORDINATOR_STATE_TOPIC_REPLICATION_FACTOR: 1
KAFKA_SHARE_COORDINATOR_STATE_TOPIC_MIN_ISR: 1
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
KAFKA_HEAP_OPTS: "-Xms512m -Xmx512m"
volumes: ["kafka-data:/var/lib/kafka/data"]
healthcheck:
test: /opt/kafka/bin/kafka-broker-api-versions.sh --bootstrap-server l3-kafka:9092
interval: 5s
volumes: {kafka-data: {name: l3-kafka-data}}
networks: {default: {name: l3-booknest}}docker compose -f compose/single.yaml up -d --wait returns once the healthcheck passes. Clients connect to a bootstrap address, learn each broker's advertised address and reconnect there, so localhost:33092 works only from the host and l3-kafka:9092 only inside Docker 514 : the usual cause of "connected, then timed out". One broker also means one replica for the internal offsets, transaction and share-group topics.