🎉

Laravel Octane, OpenSwooleサーバ起動時に不明なエラーが出た件

2024/05/15に公開

原因と解決方法

原因: 非rootユーザーで実行する Alpine ベースのコンテナで80番ポートで立ち上げようとすると権限エラーとなる
対策法: 80番ポート以外のポートを利用する

利用しているOSSのIssueへ質問し、解決いたしました。

https://github.com/exaco/laravel-octane-dockerfile/issues/71

どうやって発見したか

最初はよく分からないエラーでした。

PHP Fatal error:  Uncaught Error: Class "Laravel\Octane\Octane" not found in /var/www/html/vendor/laravel/octane/src/Stream.php:56

Stack trace:
#0 /var/www/html/vendor/laravel/octane/bin/createSwooleServer.php(19): Laravel\Octane\Stream::shutdown()
#1 /var/www/html/vendor/laravel/octane/bin/swoole-server(35): require('...')
#2 {main}
  thrown in /var/www/html/vendor/laravel/octane/src/Stream.php on line 56
Fatal error: Uncaught Error: Class "Laravel\Octane\Octane" not found in /var/www/html/vendor/laravel/octane/src/Stream.php:56
2024-04-25 16:50:52,441 INFO exited: octane_00 (exit status 255; not expected)

Class "Laravel\Octane\Octane" not found in /var/www/html/vendor/laravel/octane/src/Stream.php:56

どうやら、Laravel Octaneの OpenSwooleサーバ起動時のエラーハンドリングが優しくない状態という事らしいです。

Laravel Octaneの該当場所を見つける

https://github.com/laravel/octane/blob/2.x/bin/createSwooleServer.php#L19

try {
    $host = $serverState['host'] ?? '127.0.0.1';

    $sock = filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ? SWOOLE_SOCK_TCP : SWOOLE_SOCK_TCP6;

    $server = new Swoole\Http\Server(
        $host,
        $serverState['port'] ?? 8000,
        $config['swoole']['mode'] ?? SWOOLE_PROCESS,
        ($config['swoole']['ssl'] ?? false)
            ? $sock | SWOOLE_SSL
            : $sock,
    );
} catch (Throwable $e) {
    Laravel\Octane\Stream::shutdown($e);

    exit(1);

該当場所を見つけました。
Octaneをローカルに持ってきて、該当場所を消してみた物を composer.jsonでローカル読込をしてみます。

エラーログが出る状態で起動する

PHP Fatal error:  Uncaught Swoole\Exception: failed to listen server port[0.0.0.0:80], Error: Permission denied[13] in /var/www/html/vendor/laravel/octane/bin/createSwooleServer.php:10                                                                                             
Stack trace:                                                                                                                                                                                                                                                                         
#0 /var/www/html/vendor/laravel/octane/bin/createSwooleServer.php(10): Swoole\Server->__construct()                                                                                                                                                                                  
#1 /var/www/html/vendor/laravel/octane/bin/swoole-server(35): require('...')                                                                                                                                                                                                         
#2 {main}                                                                                                                                                                                                                                                                            
  thrown in /var/www/html/vendor/laravel/octane/bin/createSwooleServer.php on line 10                                                                                                                                                                                                
Fatal error: Uncaught Swoole\Exception: failed to listen server port[0.0.0.0:80], Error: Permission denied[13] in /var/www/html/vendor/laravel/octane/bin/createSwooleServer.php:10

Error: Permission denied[13]

今回はしっかり出てくれました。

80番ポートはダメ

https://blog.kasei-san.com/entry/2020/11/19/181224

0〜1023 までのポートは well known port と呼ばれ、開放にroot権限が必要なため

ということでしたので、 8000 番ポートで試して見ます。

8000番で試す

2024-04-30 01:43:42,241 INFO success: octane_00 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)                                                                                                                                                        
                                                                                                                                                                                                                                                                                     
   INFO  Server running…                                                                                                                                                                                                                                                             
                                                                                                                                                                                                                                                                                     
  Local: http://0.0.0.0:8000                                                                                                                                                                                                                                                         
                                                                                                                                                                                                                                                                                     
  Press Ctrl+C to stop the server                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                     
  200    GET /health ........................................ 17.22 mb 62.77 ms                                                                                                                                                                                                      
  200    GET /health ......................................... 17.35 mb 3.90 ms

🎉 無事に起動しました

修正対応

https://github.com/exaco/laravel-octane-dockerfile/pull/73

修正対応しましたので、Laravel OctaneのDockerfileを利用する場合は最新版をご利用ください。

謝辞

https://github.com/exaco/laravel-octane-dockerfile

smortexa 様ありがとうございました。

GitHubで編集を提案

Discussion