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.sstatic.net/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.
curl http://localhost:9195 curl: (52) Empty reply from server
– Calif