运行ReactPHP http服务器脚本的Docker容器 - 端口未公开

7

我正在尝试使用以下技术构建轻量级API服务器,需要处理许多请求/秒:

  • 7.1-cli-alpine(docker镜像)-占用内存/磁盘空间小,无需Web服务器
  • ReactPHP - 用于事件驱动编程的低级库(非阻塞I/O操作的完美选择)

这是我如何将所有内容组合在一起的。附注:此项目的代号为flying-pony

文件夹结构:https://istack.dev59.com/a2TPB.webp

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();

当项目构建和运行时,我使用docker-compose ps进行确认,结果如下:

➜  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

自从所有的东西都已搭建且运行后,我在我的主机上访问了http://localhost:9195,然而页面无法加载(出现empty response错误)。但是,如果我通过ssh进入我的flying_pony_php_service容器并运行以下命令:curl http://localhost:8080,它就能正常工作(即ReactPHP http服务器响应,并且我收到了我上面定义的欢迎消息)。
所以,我的问题是,为什么端口映射没有按照预期工作?或者这与端口映射无关,某种程度上来说,容器的响应没有传递过来?
正如您所看到的,一切都正确连接,ReactPHP中的Web服务器内部正在工作,但在外部不可访问/不能正常工作?如果我使用类似apache/nginx的东西,我没有任何端口映射问题。有任何想法吗?P.S.对于这篇长文非常抱歉;试图在人们逐个请求细节之前提供所有细节。

如果我尝试从主机机器使用curl访问服务器,我会得到这个错误:curl http://localhost:9195 curl: (52) Empty reply from server - Latheesan
1个回答

10
这是因为如果没有明确提供接口(source),ReactPHP的TCP套接字会监听127.0.0.1(本地主机)。从容器外部无法访问127.0.0.1,您应该改为监听0.0.0.0(表示“所有接口”)。

与其使用

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

使用

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接