├── docker ├── nginx │ ├── Dockerfile │ └── rootfs │ │ └── etc │ │ └── nginx │ │ └── conf.d │ │ └── default.conf └── php │ └── Dockerfile ├── public ├── consumer.php └── index.php ├── docker-compose.yml └── README.md /docker/nginx/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:1.13.7 2 | 3 | COPY rootfs / 4 | 5 | EXPOSE 80 6 | -------------------------------------------------------------------------------- /public/consumer.php: -------------------------------------------------------------------------------- 1 | set('log_level', (string) LOG_DEBUG); 5 | $consumer = new \RdKafka\Consumer($conf); 6 | 7 | $consumer->addBrokers("kafka:9092"); 8 | 9 | $topic = $consumer->newTopic("test"); 10 | 11 | $topic->consumeStart(0, RD_KAFKA_OFFSET_BEGINNING); 12 | 13 | echo "consumer started" . PHP_EOL; 14 | while (true) { 15 | $msg = $topic->consume(0, 1000); 16 | if (isset($msg->payload)) { 17 | echo $msg->payload . PHP_EOL; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | set('log_level', (string) LOG_DEBUG); 5 | $producer = new \RdKafka\Producer($conf); 6 | 7 | if ($producer->addBrokers("kafka:9092") < 1) { 8 | echo "Failed adding brokers\n"; 9 | exit; 10 | } 11 | 12 | $topic = $producer->newTopic("test"); 13 | 14 | if (!$producer->getMetadata(false, $topic, 2000)) { 15 | echo "Failed to get metadata, is broker down?\n"; 16 | exit; 17 | } 18 | 19 | $topic->produce(RD_KAFKA_PARTITION_UA, 0, $_SERVER['QUERY_STRING']); 20 | 21 | echo "Message published\n"; 22 | -------------------------------------------------------------------------------- /docker/php/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:8.2-fpm 2 | 3 | RUN apt-get update --fix-missing \ 4 | && apt-get install -y curl wget zip unzip git \ 5 | && rm -rf /var/lib/apt/lists/* 6 | 7 | # DEPENDENCIES 8 | RUN apt-get update --fix-missing \ 9 | && apt-get install -y python3 \ 10 | && rm -rf /var/lib/apt/lists/* \ 11 | && ln -s /usr/bin/python3 /usr/bin/python 12 | 13 | # KAFKA 14 | RUN git clone --depth 1 --branch v0.11.1 https://github.com/edenhill/librdkafka.git \ 15 | && ( \ 16 | cd librdkafka \ 17 | && ./configure \ 18 | && make \ 19 | && make install \ 20 | ) \ 21 | && pecl install rdkafka \ 22 | && echo "extension=rdkafka.so" > /usr/local/etc/php/conf.d/rdkafka.ini 23 | -------------------------------------------------------------------------------- /docker/nginx/rootfs/etc/nginx/conf.d/default.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80 default_server; 3 | 4 | root /usr/share/nginx/www/public; 5 | index index.php; 6 | 7 | access_log /var/log/nginx/access.log main; 8 | error_log /var/log/nginx/error.log; 9 | add_header 'Access-Control-Allow-Origin' '*' always; 10 | 11 | gzip on; 12 | gzip_types *; 13 | 14 | location / { 15 | try_files $uri $uri/ /index.php$is_args$args; 16 | } 17 | 18 | location ~ \.php$ { 19 | try_files $uri =404; 20 | fastcgi_pass php:9000; 21 | fastcgi_index index.php; 22 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 23 | include fastcgi_params; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | php: 4 | build: ./docker/php 5 | volumes: 6 | - ./:/usr/share/nginx/www 7 | working_dir: /usr/share/nginx/www 8 | 9 | nginx: 10 | build: ./docker/nginx 11 | links: 12 | - php 13 | volumes_from: 14 | - php 15 | ports: 16 | - 80:80 17 | 18 | zookeeper: 19 | image: wurstmeister/zookeeper 20 | ports: 21 | - 2181:2181 22 | 23 | kafka: 24 | image: wurstmeister/kafka 25 | ports: 26 | - 9092:9092 27 | environment: 28 | KAFKA_ADVERTISED_HOST_NAME: kafka 29 | KAFKA_CREATE_TOPICS: "test:1:1" 30 | KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 31 | volumes: 32 | - /var/run/docker.sock:/var/run/docker.sock 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Php-Kafka demo 2 | 3 | Example docker environment where php can write and read from kafka. 4 | 5 | ## Requirements 6 | 7 | On your own machine you should have: 8 | 9 | - docker 10 | - docker-compose 11 | 12 | ## Run the demo 13 | 14 | ``` 15 | docker-compose up -d 16 | ``` 17 | 18 | Send your message in the querystring by visiting `http://localhost?hello`. 19 | 20 | ``` 21 | docker-compose exec php php /usr/share/nginx/www/public/consumer.php 22 | ``` 23 | 24 | The line above should print the messages in the shell 25 | 26 | ## Documentation 27 | 28 | - Docker images for [kafka](https://hub.docker.com/r/wurstmeister/kafka/) and [zookeeper](https://hub.docker.com/r/wurstmeister/zookeeper/) 29 | - [librdkafka](https://github.com/edenhill/librdkafka), a C implementation of the kafka protocol 30 | - [php-rdkafka](https://github.com/arnaud-lb/php-rdkafka), a kafka client for php 31 | --------------------------------------------------------------------------------