Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker running ReactPHP http server script - not exposing the port

I am experimenting with building lightweight api server, that needs to handle many req/sec, using the following tech:

  • 7.1-cli-alpine (docker image) - small memory/disk footprint, no need for web server
  • ReactPHP - low-level library for event-driven programming (perfect for non-blocking I/O ops)

Here's how i've put everything together. P.S. this project is code-named flying-pony

Folder structure: https://i.stack.imgur.com/a2TPB.png

docker-compose.yml:

flying_pony_php_service:
  container_name: flying_pony_php_service
  build:
    context: ./service
    dockerfile: Dockerfile
  ports:
    - "9195:8080"
  volumes:
    - ./service:/app

service/Dockerfile:

FROM php:7.1-cli-alpine
ADD . /app
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT /entrypoint.sh

service/entrypoint.sh

#!/bin/sh
/app/service.php

service/service.php

#!/usr/local/bin/php
<?php

require __DIR__ . '/vendor/autoload.php';

$loop = React\EventLoop\Factory::create();

$server = new React\Http\Server(function (Psr\Http\Message\ServerRequestInterface $request) {

    $path = $request->getUri()->getPath();
    $method = $request->getMethod();

    if ($path === '/') {
        if ($method === 'GET') {
            return new React\Http\Response(200, array('Content-Type' => 'text/plain'), "Welcome to react-php version of flying pony api :)\n");
        }
    }

    return new React\Http\Response(404, ['Content-Type' => 'text/plain'],  'Not found');
});

$socket = new React\Socket\Server(8080, $loop);

$server->listen($socket);

$loop->run();

When the project is built and running, I confirmed using docker-compose ps and got the following:

➜  flying_pony_php git:(reactphp) docker-compose ps
         Name                        Command               State           Ports         
-----------------------------------------------------------------------------------------
flying_pony_php_service   /bin/sh -c /entrypoint.sh        Up      0.0.0.0:9195->8080/tcp
flying_pony_php_worker    /bin/sh -c /entrypoint.sh        Up                            
flying_pony_redis         docker-entrypoint.sh redis ...   Up      0.0.0.0:6379->6379/tcp

Since everything is built and running; I visited on my host computer: http://localhost:9195 and the page does not load (empty response error). However, if I ssh into my flying_pony_php_service container and run this command: curl http://localhost:8080 - it's working (i.e. the ReactPHP http server is responding and I get the welcome message I've defined above).

So, my question is, why does the port mapping not working as intended? or is this not port mapping related, somehow the response from container is not coming through?

As you can see everything is wired up correctly and the web server in ReactPHP is working internally, but its not accessible/working correctly externally?

I've not had any problem with port mapping if i use something like apache/nginx. Any ideas? P.S. Sorry for the long post; trying to give all details before people request them one by one.

like image 337
Latheesan Avatar asked Aug 04 '18 15:08

Latheesan


1 Answers

This is because ReactPHP's TCP socket listens on 127.0.0.1 (localhost) if no interface is provided explicitly (source). 127.0.0.1 is not accessibe from outside the container - you should listen on 0.0.0.0 (which means "all interfaces") instead.

Instead of

$socket = new React\Socket\Server(8080, $loop);

Use

$socket = new React\Socket\Server('0.0.0.0:8080', $loop);
like image 67
Pieter van den Ham Avatar answered Oct 07 '22 08:10

Pieter van den Ham