Kafka Docker Installation¶
Deploy Apache Kafka using Docker containers for development, testing, and lightweight production environments.
Docker Images¶
| Image | Maintainer | Use Case |
|---|---|---|
apache/kafka |
Apache | Official image, KRaft mode |
confluentinc/cp-kafka |
Confluent | Enterprise features |
bitnami/kafka |
Bitnami | Easy configuration |
Single Node (KRaft)¶
Docker Compose¶
# docker-compose.yml
version: '3.8'
services:
kafka:
image: apache/kafka:3.6.0
hostname: kafka
container_name: kafka
ports:
- "9092:9092"
environment:
KAFKA_NODE_ID: 1
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
KAFKA_LOG_DIRS: /tmp/kraft-combined-logs
CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk
volumes:
- kafka-data:/tmp/kraft-combined-logs
volumes:
kafka-data:
Start¶
docker-compose up -d
Verify¶
# Check container
docker-compose ps
# Create topic
docker exec kafka /opt/kafka/bin/kafka-topics.sh \
--create --topic test \
--bootstrap-server localhost:9092
# List topics
docker exec kafka /opt/kafka/bin/kafka-topics.sh \
--list --bootstrap-server localhost:9092
Multi-Broker Cluster¶
Three-Node Configuration¶
# docker-compose-cluster.yml
version: '3.8'
services:
kafka1:
image: apache/kafka:3.6.0
hostname: kafka1
container_name: kafka1
ports:
- "9092:9092"
environment:
KAFKA_NODE_ID: 1
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka1:9092
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 3
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 2
KAFKA_LOG_DIRS: /tmp/kraft-combined-logs
CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk
volumes:
- kafka1-data:/tmp/kraft-combined-logs
networks:
- kafka-net
kafka2:
image: apache/kafka:3.6.0
hostname: kafka2
container_name: kafka2
ports:
- "9093:9092"
environment:
KAFKA_NODE_ID: 2
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka2:9092
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 3
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 2
KAFKA_LOG_DIRS: /tmp/kraft-combined-logs
CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk
volumes:
- kafka2-data:/tmp/kraft-combined-logs
networks:
- kafka-net
kafka3:
image: apache/kafka:3.6.0
hostname: kafka3
container_name: kafka3
ports:
- "9094:9092"
environment:
KAFKA_NODE_ID: 3
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka3:9092
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 3
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 2
KAFKA_LOG_DIRS: /tmp/kraft-combined-logs
CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk
volumes:
- kafka3-data:/tmp/kraft-combined-logs
networks:
- kafka-net
volumes:
kafka1-data:
kafka2-data:
kafka3-data:
networks:
kafka-net:
driver: bridge
With Schema Registry¶
# docker-compose-full.yml
version: '3.8'
services:
kafka:
image: apache/kafka:3.6.0
hostname: kafka
container_name: kafka
ports:
- "9092:9092"
environment:
KAFKA_NODE_ID: 1
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_LOG_DIRS: /tmp/kraft-combined-logs
CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk
volumes:
- kafka-data:/tmp/kraft-combined-logs
networks:
- kafka-net
schema-registry:
image: confluentinc/cp-schema-registry:7.5.0
hostname: schema-registry
container_name: schema-registry
depends_on:
- kafka
ports:
- "8081:8081"
environment:
SCHEMA_REGISTRY_HOST_NAME: schema-registry
SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: kafka:9092
SCHEMA_REGISTRY_LISTENERS: http://0.0.0.0:8081
networks:
- kafka-net
kafka-connect:
image: confluentinc/cp-kafka-connect:7.5.0
hostname: kafka-connect
container_name: kafka-connect
depends_on:
- kafka
- schema-registry
ports:
- "8083:8083"
environment:
CONNECT_BOOTSTRAP_SERVERS: kafka:9092
CONNECT_REST_PORT: 8083
CONNECT_GROUP_ID: connect-cluster
CONNECT_CONFIG_STORAGE_TOPIC: connect-configs
CONNECT_OFFSET_STORAGE_TOPIC: connect-offsets
CONNECT_STATUS_STORAGE_TOPIC: connect-status
CONNECT_CONFIG_STORAGE_REPLICATION_FACTOR: 1
CONNECT_OFFSET_STORAGE_REPLICATION_FACTOR: 1
CONNECT_STATUS_STORAGE_REPLICATION_FACTOR: 1
CONNECT_KEY_CONVERTER: org.apache.kafka.connect.storage.StringConverter
CONNECT_VALUE_CONVERTER: io.confluent.connect.avro.AvroConverter
CONNECT_VALUE_CONVERTER_SCHEMA_REGISTRY_URL: http://schema-registry:8081
CONNECT_REST_ADVERTISED_HOST_NAME: kafka-connect
CONNECT_PLUGIN_PATH: /usr/share/java,/usr/share/confluent-hub-components
networks:
- kafka-net
volumes:
kafka-data:
networks:
kafka-net:
driver: bridge
External Access¶
For accessing Kafka from outside Docker network:
services:
kafka:
image: apache/kafka:3.6.0
ports:
- "9092:9092"
- "9094:9094"
environment:
KAFKA_NODE_ID: 1
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://:9094
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,EXTERNAL://localhost:9094
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093
CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk
Connect from host using localhost:9094.
Resource Limits¶
services:
kafka:
image: apache/kafka:3.6.0
deploy:
resources:
limits:
cpus: '2'
memory: 4G
reservations:
cpus: '1'
memory: 2G
environment:
KAFKA_HEAP_OPTS: "-Xmx2g -Xms2g"
Health Checks¶
services:
kafka:
image: apache/kafka:3.6.0
healthcheck:
test: ["CMD", "/opt/kafka/bin/kafka-broker-api-versions.sh", "--bootstrap-server", "localhost:9092"]
interval: 30s
timeout: 10s
retries: 5
start_period: 60s
Useful Commands¶
# Start cluster
docker-compose up -d
# View logs
docker-compose logs -f kafka
# Stop cluster
docker-compose down
# Stop and remove volumes
docker-compose down -v
# Execute Kafka commands
docker exec -it kafka /bin/bash
# Create topic
docker exec kafka /opt/kafka/bin/kafka-topics.sh \
--create --topic my-topic \
--partitions 3 \
--replication-factor 1 \
--bootstrap-server localhost:9092
# Produce messages
docker exec -it kafka /opt/kafka/bin/kafka-console-producer.sh \
--topic my-topic \
--bootstrap-server localhost:9092
# Consume messages
docker exec -it kafka /opt/kafka/bin/kafka-console-consumer.sh \
--topic my-topic \
--from-beginning \
--bootstrap-server localhost:9092
Troubleshooting¶
| Issue | Cause | Solution |
|---|---|---|
| Container exits immediately | Storage format issue | Check CLUSTER_ID, format storage |
| Cannot connect from host | Advertised listeners | Configure EXTERNAL listener |
| Out of memory | Heap too large | Adjust KAFKA_HEAP_OPTS |
| Slow startup | Controller election | Wait for quorum, check logs |
Related Documentation¶
- Installation Overview - All installation methods
- Kubernetes - Kubernetes deployment
- Configuration - Configuration reference