Search code examples
phpdockerdocker-composedockerfilereactphp

Why can't I get response from my Docker/ReactPHP app outside the container?


I have faced with the problem! Can't get the response from browser or postman in my Docker/ReactPHP app.

This is my code:

docker-compose.yaml

version: '3.8'

services:
  react_php_service2:
    container_name: react_php_service2
    build:
      context: .
      dockerfile: ./.docker/php/Dockerfile
    ports:
      - "8000:8000"
    extra_hosts:
      - "host.docker.internal:host-gateway"
    volumes:
      - ./reactphp:/app

Dockerfile

FROM php:8.0-alpine

COPY ./reactphp /app
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

COPY ./.docker/php/entrypoint.sh /entrypoint.sh

RUN ["chmod", "+x", "/entrypoint.sh"]

ENTRYPOINT /entrypoint.sh

CMD [ "php", "./app/server.php"]

entrypoint.sh

#!/bin/sh

cd app/
composer install
php server.php

server.php

require 'vendor/autoload.php';

use Psr\Http\Message\ServerRequestInterface;

$loop = React\EventLoop\Loop::get();

$server = new React\Http\HttpServer(function (ServerRequestInterface $request) {
    echo date('Y-m-d H:i:s') . ' ' . $request->getMethod() . ' ' . $request->getUri() . PHP_EOL;
    //return React\Http\Message\Response::plaintext("Hello World!\n");
    return new React\Http\Message\Response(200, ['Content-Type' => 'text/plain'], 'Hello, World!');
});

$socket = new React\Socket\SocketServer('127.0.0.1:8000', [], $loop);
$server->listen($socket);

echo 'Listening on ' . str_replace('tcp:', 'http:', $socket->getAddress()) . "\n";

$loop->run();

So in docker container it works fine: Send request Get response.

But it doesn't work in the browser or Postman - anywhere outside container: Browser result.


Solution

  • ReactPHP core developer here. You're making the socket server listen on your local loop back interface (127.0.0.1), which normally is your local machine. However with Docker that becomes your local Docker container only. If you listen on all interfaces (0.0.0.0) instead you can reach it with the port mapping in the compose file. Note that this not just applies to ReactPHP by also tools like Redis when they default to listening to 127.0.0.1.