We will start a Docker Compose cluster with Kafka, KNEP, confluent-schema-registry
and a Kafka UI.
First, we need to create a docker-compose.yaml
file. This file will define the services we want to run in our local environment:
cat <<EOF > docker-compose.yaml
services:
kafka:
image: apache/kafka:3.9.0
container_name: kafka
ports:
- "9092:19092"
environment:
KAFKA_NODE_ID: 1
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LISTENERS: INTERNAL://kafka:9092,CONTROLLER://kafka:9093,EXTERNAL://0.0.0.0:19092
KAFKA_ADVERTISED_LISTENERS: INTERNAL://kafka:9092,EXTERNAL://localhost:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093
KAFKA_CLUSTER_ID: 'abcdefghijklmnopqrstuv'
KAFKA_LOG_DIRS: /tmp/kraft-combined-logs
schema-registry:
image: confluentinc/cp-schema-registry:latest
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
healthcheck:
test: curl -f http://localhost:8081/subjects
interval: 10s
timeout: 5s
retries: 5
knep:
image: kong/kong-native-event-proxy:latest
container_name: knep
ports:
- "8080:8080"
- "19092:19092"
env_file: "knep.env"
environment:
KONNECT_API_TOKEN: ${KONNECT_TOKEN}
KONNECT_API_HOSTNAME: us.api.konghq.com
KONNECT_CONTROL_PLANE_ID: ${KONNECT_CONTROL_PLANE_ID}
KNEP__RUNTIME__DRAIN_DURATION: 1s # makes shutdown quicker, not recommended to be set like this in production
# KNEP__OBSERVABILITY__LOG_FLAGS: "info,knep=debug" # Uncomment for debug logging
healthcheck:
test: curl -f http://localhost:8080/health/probes/liveness
interval: 10s
timeout: 5s
retries: 5
kafka-ui:
image: provectuslabs/kafka-ui:latest
container_name: kafka-ui
environment:
# First cluster configuration (direct Kafka connection)
KAFKA_CLUSTERS_0_NAME: "direct-kafka-cluster"
KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: "kafka:9092"
KAFKA_CLUSTERS_0_SCHEMAREGISTRY: "http://schema-registry:8081"
# Second cluster configuration (KNEP proxy connection)
KAFKA_CLUSTERS_1_NAME: "knep-proxy-cluster"
KAFKA_CLUSTERS_1_BOOTSTRAPSERVERS: "knep:9092"
KAFKA_CLUSTERS_1_SCHEMAREGISTRY: "http://schema-registry:8081"
SERVER_PORT: 8082
ports:
- "8082:8082"
EOF
Note that the above config publishes the following ports to the host:
-
kafka:9092
for plaintext auth
-
kafka:9094
for SASL username/password auth
-
kafka-ui:8082
for access to the Kafka UI
-
schema-registry:8081
for access to the schema registry
-
knep:9192
to knep:9292
for access to the KNEP proxy (the port range is wide to allow many virtual clusters to be created)
-
knep:8080
for probes and metrics access to KNEP
The KNEP container will use environment variables from knep.env
file. Let’s create it:
cat <<EOF > knep.env
KONNECT_API_TOKEN=\${KONNECT_TOKEN}
KONNECT_API_HOSTNAME=us.api.konghq.com
KONNECT_CONTROL_PLANE_ID=\${KONNECT_CONTROL_PLANE_ID}
EOF
Now let’s start the local setup:
Let’s look at the logs of the KNEP container to see if it started correctly:
You should see something like this:
knep | 2025-04-30T08:59:58.004076Z WARN tokio-runtime-worker ThreadId(09) add_task{task_id="konnect_watch_config"}:task_run:check_dataplane_config{cp_config_url="/v2/control-planes/c6d325ec-0bd6-4fbc-b2c1-6a56c0a3edb0/declarative-config/native-event-proxy"}: knep::konnect: src/konnect/mod.rs:218: Konnect API returned 404, is the control plane ID correct?
This is expected, as we haven’t configured the Control Plane yet. We’ll do this in the next step.