Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Larvel Octane を AWS Fargate で動かしてみる

tutida
July 04, 2024

Larvel Octane を AWS Fargate で動かしてみる

2026.07.02 : Fusic Tech Live Vol.20 ~PHPer Connect~ での資料

PHPのアプリケーションサーバとLaravelの統合をサポートするLaravel Octane。
今回は、Laravel Octane をAWS Fargateで動かすまでのご紹介です。

tutida

July 04, 2024
Tweet

More Decks by tutida

Other Decks in Technology

Transcript

  1. ©Fusic Co., Ltd. 0 Larvel Octane を AWS Fargate で動かしてみる

    2024.07.02 内田 大順 Github : @tutida Fusic Tech Live Vol.20 ~PHPer Connect~
  2. ©Fusic Co., Ltd. 1 内田 大順 Uchida Tomoyuki : Github

    @tutida ・主な担当業務 AWS を使った Webアプリケーション開発 プロダクト管理・運用 ・PHPer 的なこと PHPカンファレンス福岡 2023 Laravel x Inertia.js 「現代のモノリス方式」によるお手軽SPA開発 ・最近のこと 明日 朝9時から引っ越し…(なにも終わってない… 自己紹介 株式会社Fusic プリンシパルエンジニア
  3. ©Fusic Co., Ltd. 2 CONTENTS - お話しすること o これまで :

    Laravel on AWS(Fargate) o Laravel Octane とは o これから? : Laravel on AWS(Fargate) - お話ししないこと o 各アプリケーションサーバの詳細 ※ 勉強不足
  4. ©Fusic Co., Ltd. 4 開発環境の構築はとっても甘やかし簡単 これまで:Laravel on AWS(Fargate) # Docker起動

    $ cp .env.example .env $ ./vendor/bin/sail up –d # セットアップ $ ./vendor/bin/sail artisan key:generate $ ./vendor/bin/sail artisan migrate $ ./vendor/bin/sail artisan db:seed # アセットのビルド $ ./vendor/bin/sail npm install $ ./vendor/bin/sail npm run dev
  5. ©Fusic Co., Ltd. 9 よくある構成 これまで:Laravel on AWS(Fargate) - Fargateのタスクの中で2つのコンテナを実行

    o Nginx : Webサーバ, ポート 80で待ち受け o PHP-FPM : PHPプロセス, FastCGIプロセス, 9000でリッスン
  6. ©Fusic Co., Ltd. 10 弊社でよくある構成 これまで:Laravel on AWS(Fargate) - メリット

    o Webサーバ / PHP のログが分離できる o 静的コンテンツ配信をWebサーバで出来る - デメリット o イメージ・設定を2つ管理する必要がある → つまり、面倒くさい ※ 既存の資産がなければなおさら
  7. ©Fusic Co., Ltd. 11 ALBから 9000番 でそのまま流せない? これまで:Laravel on AWS(Fargate)

    - PHP-FPM … PHP FastCGI Process Manager o PHPを実行するためのFastCGIプロセスを管理するための仕組 o FastCGIプロトコルで待ち受けている - ALB o (Webサーバではないので...)FastCGIプロトコルでバックエンド に通信を流すことは出来ない
  8. ©Fusic Co., Ltd. 13 (余談)なんで開発環境は簡単に作れるのか これまで:Laravel on AWS(Fargate) - Laravel

    Sail のPHP実行環境はUbuntuベースのイメージ o コンテナのENTRYPOINTは supervisord(デーモナイズツール) o PHPのビルドインサーバ(シングルスレッド)が動いている # supervisord.conf [supervisord] nodaemon=true user=root logfile=/var/log/supervisor/supervisord.log pidfile=/var/run/supervisord.pid [program:php] command=%(ENV_SUPERVISOR_PHP_COMMAND)s user=%(ENV_SUPERVISOR_PHP_USER)s environment=LARAVEL_SAIL="1" stdout_logfile=/dev/stdout stdout_logfile_maxbytes=0 stderr_logfile=/dev/stderr stderr_logfile_maxbytes=0 # Dockerfile FROM ubuntu:22.04 … ENV SUPERVISOR_PHP_COMMAND="/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve -- host=0.0.0.0 --port=80" … EXPOSE 8000 ENTRYPOINT ["start-container"]
  9. ©Fusic Co., Ltd. 14 結論 これまで:Laravel on AWS(Fargate) Laravel を

    AWS にコンテナでデプロイするのは面倒くさい 初めてPHP触る人とか大変だと思う...
  10. ©Fusic Co., Ltd. 16 Laravel Octane とは Laravel Octane https://github.com/laravel/octane

    - PHPにもHTTPを喋れるアプリケーションサーバがある! o FrankenPHP, Swoole, Roadrunner など - Laravelアプリとアプリケーションサーバとの統合をサポート
  11. ©Fusic Co., Ltd. 17 ローカルでの導入方法 : FrankenPHPの場合 Laravel Octane -

    https://laravel.com/docs/11.x/octane o ドキュメント通りでサクサク導入が可能 # Octane と アプリケーションサーバのインストール # FrannkenPHPの場合は、FrankenPHPのバイナリをDLしてくる ./vendor/bin/sail composer require laravel/octane ./vendor/bin/sail artisan octane:install --server=frankenphp # docker-compose.ymlの変更 services: laravel.test: environment: SUPERVISOR_PHP_COMMAND: "/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan octane:start --server=frankenphp --host=0.0.0.0 --admin-port=2019 --port=80" XDG_CONFIG_HOME: /var/www/html/config XDG_DATA_HOME: /var/www/html/data
  12. ©Fusic Co., Ltd. 18 使えるアプリケーションサーバについてざっくり Laravel Octane Swoole C/C++で書かれたPHP拡張の1つ。 イベント駆動の非同期ノンブロッキングI/Oモデルを使用する。

    Roadrunner GoによるPHPのアプリケーションサーバ・プロセスマネージャ Spiral Scount という会社が開発 FrankenPHP GoによるPHPのアプリケーションサーバ Caddy(Goのサーバ)上でPHPをモジュールとして実行 Laravelのドキュメントも一番充実している
  13. ©Fusic Co., Ltd. 24 いままで : Nginx + PHP-FPM これから?

    : Laravel on AWS(Fargate) FROM node:20 AS build-node ADD . /work WORKDIR /work RUN npm i && npm run build && rm -rf node_modules FROM nginx:mainline-alpine WORKDIR /var/www/html COPY ./deploy/nginx/default.conf /etc/nginx/conf.d/default.conf COPY --from=build-node /work/public /var/www/html/public EXPOSE 80 NginxのDockerfile … location ~ ¥.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; fastcgi_hide_header X-Powered-By; } … Nginxのdefault.conf - /public 以下にビルドしたアセットを nginxのrootに配置 - default.conf では 9000で待ち受けて いる php-fpm に渡す
  14. ©Fusic Co., Ltd. 25 いままで : Nginx + PHP-FPM これから?

    : Laravel on AWS(Fargate) FROM node:20 AS build-node ADD . /work WORKDIR /work RUN npm i && npm run build && rm -rf node_modules FROM php:8.3-fpm-bullseye COPY --from=build-node /work /var/www/html RUN apt-get update ¥ && apt-get install -y zip unzip git ¥ && docker-php-ext-install pdo pdo_mysql RUN chmod 777 -R /var/www/html/storage /var/www/html/bootstrap/cache WORKDIR /var/www/html ENV COMPOSER_ALLOW_SUPERUSER=1 COPY --from=composer /usr/bin/composer /usr/bin/composer RUN composer install --no-dev COPY ./deploy/php/.env.aws /var/www/html/.env php-fpm の Dockerfile - ビルドしたアセットごとソースコードを php-fpm のイメージにCOPY - 必要なライブラリとextensionをインス トール : docker-php-ext-install - composer で vendor 以下をインストール
  15. ©Fusic Co., Ltd. 26 いままで : Nginx + PHP-FPM これから?

    : Laravel on AWS(Fargate) { "containerDefinitions": [ { "name": "nginx", "image": "xxxxxxx", "cpu": 128, "memoryReservation": 256, "portMappings": [ { "containerPort": 80, "hostPort": 80, "protocol": "tcp" } ], ... }, { "name": "php", "image": "xxxxxxx", "cpu": 128, "memoryReservation": 256, "portMappings": [], ... } ], ... "cpu": "256", "memory": "512", ... } Fargate の タスク定義 - タスクの中で、nginxとphpのコンテナを 動かすように定義 - 外部ポートを開けるのは nginx側(80番) - タスクのCPU, メモリを各コンテナにどう 割り当てるのか定義する
  16. ©Fusic Co., Ltd. 27 いままで : Nginx + PHP-FPM これから?

    : Laravel on AWS(Fargate) ALB経由でアクセス
  17. ©Fusic Co., Ltd. 30 やってみる これから? : Laravel on AWS(Fargate)

    - Swoole on AWS(Fargate) - Roadrunner on AWS(Fargate) - FrankenPHP on AWS(Fargate)
  18. ©Fusic Co., Ltd. 31 やってみる これから? : Laravel on AWS(Fargate)

    - Swoole on AWS(Fargate) - Roadrunner on AWS(Fargate) - FrankenPHP on AWS(Fargate)
  19. ©Fusic Co., Ltd. 32 Laravel Octane - Swoole これから? :

    Laravel on AWS(Fargate) FROM node:20 AS build-node ADD . /work WORKDIR /work RUN npm i && npm run build && rm -rf node_modules FROM php:8.3 COPY --from=build-node /work /app RUN apt-get update ¥ && apt-get install -y zip unzip git libbrotli-dev ¥ && pecl install swoole ¥ && docker-php-ext-install pcntl pdo pdo_mysql ¥ && docker-php-ext-enable swoole WORKDIR /app ENV COMPOSER_ALLOW_SUPERUSER=1 COPY --from=composer /usr/bin/composer /usr/bin/composer RUN composer install --no-dev RUN php artisan octane:install --server swoole -n COPY ./deploy/php/.env.aws /app/.env ENTRYPOINT ["php", "artisan", "octane:start", "--host", "0.0.0.0", "--port", "80"] php の Dockerfile - ビルドしたアセットごとソースコードを php のイメージにCOPY(一緒) - 必要なライブラリとextensionをインス トール : docker-php-ext-install - pcntl が追加 - pecl で swoole をイントール - ontane:install を実行 - ontane:start で 80番でサーバを起動
  20. ©Fusic Co., Ltd. 33 Laravel Octane - Swoole これから? :

    Laravel on AWS(Fargate) { "containerDefinitions": [ { "name": "php", "image": "xxxxx", "cpu": 256, "memoryReservation": 512, "portMappings": [ { "containerPort": 80, "hostPort": 80, "protocol": "tcp" } ], ... } ], ... "cpu": "256", "memory": "512", ... } Fargate の タスク定義 - タスクではphpのコンテナのみを定義 - シンプル… - PHPで80番をリッスン - タスクのCPUとメモリを全振りでOK
  21. ©Fusic Co., Ltd. 34 Laravel Octane - Swoole これから? :

    Laravel on AWS(Fargate) ALB経由でアクセス ※ 変わり映えしない…
  22. ©Fusic Co., Ltd. 35 やってみる これから? : Laravel on AWS(Fargate)

    - Swoole on AWS(Fargate) - Roadrunner on AWS(Fargate) - FrankenPHP on AWS(Fargate)
  23. ©Fusic Co., Ltd. 36 Laravel Octane - Roadrunner これから? :

    Laravel on AWS(Fargate) FROM node:20 AS build-node ADD . /work WORKDIR /work RUN npm i && npm run build && rm -rf node_modules FROM php:8.3 COPY --from=build-node /work /app RUN apt-get update ¥ && apt-get install -y zip unzip git ¥ && docker-php-ext-install pcntl sockets pdo pdo_mysql WORKDIR /app ENV COMPOSER_ALLOW_SUPERUSER=1 COPY --from=composer /usr/bin/composer /usr/bin/composer RUN composer install --no-dev RUN php artisan octane:install --server roadrunner -n RUN php ./vendor/bin/rr get-binary -n COPY ./deploy/php/.env.aws /app/.env ENTRYPOINT ["php", "artisan", "octane:start", "--host", "0.0.0.0", "--port", "80", "--rpc-port", "6001"] php の Dockerfile - ビルドしたアセットごとソースコードを php のイメージにCOPY(一緒) - 必要なライブラリとextensionをインス トール : docker-php-ext-install - pcntl, sockets が追加 - ontane:install を実行 - Roadrunnerの最新バイナリをDL - ontane:start で 80番でサーバを起動 - well-kwonポートじゃなければ、rpcポートの指 定はなしでOK
  24. ©Fusic Co., Ltd. 37 Laravel Octane - Roadrunner これから? :

    Laravel on AWS(Fargate) { "containerDefinitions": [ { "name": "php", "image": "xxxxx", "cpu": 256, "memoryReservation": 512, "portMappings": [ { "containerPort": 80, "hostPort": 80, "protocol": "tcp" } ], ... } ], ... "cpu": "256", "memory": "512", ... } Fargate の タスク定義 - swoole と変わらず
  25. ©Fusic Co., Ltd. 38 Laravel Octane - Roadrunner これから? :

    Laravel on AWS(Fargate) ALB経由でアクセス ※ あと、一回でます
  26. ©Fusic Co., Ltd. 39 やってみる これから? : Laravel on AWS(Fargate)

    - Swoole on AWS(Fargate) - Roadrunner on AWS(Fargate) - FrankenPHP on AWS(Fargate)
  27. ©Fusic Co., Ltd. 40 Laravel Octane - FrankenPHP これから? :

    Laravel on AWS(Fargate) FROM node:20 AS build-node ADD . /work WORKDIR /work RUN npm i && npm run build && rm -rf node_modules FROM dunglas/frankenphp COPY --from=build-node /work /app RUN apt-get update ¥ && apt-get install -y zip unzip git ¥ && install-php-extensions pcntl pdo pdo_mysql WORKDIR /app ENV COMPOSER_ALLOW_SUPERUSER=1 COPY --from=composer /usr/bin/composer /usr/bin/composer RUN composer install --no-dev RUN php artisan octane:install --server frankenphp -n COPY ./deploy/php/.env.aws /app/.env ENTRYPOINT ["php", "artisan", "octane:start", "--host", "0.0.0.0", "--port", "80", "--admin-port", "2019"] php の Dockerfile - ビルドしたアセットごとソースコードを php のイメージにCOPY(一緒) - FrankenPHPが提供するイメージを使用 - 必要なライブラリとextensionをインス トール : docker-php-ext-install - pcntl が追加 - ontane:install を実行 - FrankenPHPのバイナリがDLされる - ontane:start で 80番でサーバを起動 - well-kwonポートじゃなければ、adminポート の指定はなしでOK
  28. ©Fusic Co., Ltd. 41 Laravel Octane - FrankenPHP これから? :

    Laravel on AWS(Fargate) { "containerDefinitions": [ { "name": "php", "image": "xxxxx", "cpu": 256, "memoryReservation": 512, "portMappings": [ { "containerPort": 80, "hostPort": 80, "protocol": "tcp" } ], ... } ], ... "cpu": "256", "memory": "512", ... } Fargate の タスク定義 - swoole と変わらず
  29. ©Fusic Co., Ltd. 42 Laravel Octane - FrankenPHP これから? :

    Laravel on AWS(Fargate) ALB経由でアクセス ※ 最後です
  30. ©Fusic Co., Ltd. 43 やってみる これから? : Laravel on AWS(Fargate)

    - Swoole on AWS(Fargate) - Roadrunner on AWS(Fargate) - FrankenPHP on AWS(Fargate)
  31. ©Fusic Co., Ltd. 44 やさしい世界 これから? : Laravel on AWS(Fargate)

    全てのパターンでシンプルに 1イメージでFagateにデプロイできた!
  32. ©Fusic Co., Ltd. 45 気にした方がよさそうなこと これから? : Laravel on AWS(Fargate)

    - 従来の仕組の違い - 1つのタスクの中に、1つのコンテナ - PHP-FPM : リクエストの度にPHPファイルを読み込む - Laravel Octane : ワーカー起動時にメモリにコードを読み込む ワーカーが再起動しない限りコードは一緒
  33. ©Fusic Co., Ltd. 46 気にした方がよさそうなこと① これから? : Laravel on AWS(Fargate)

    - ログの分割 - アクセスログ と PHPのエラーログなどが混ざるようになる - コンテナが分かれているときは、コンテナごとにロググループを分けれた - 標準出力に投げるだけなので、基本的には分けれない(はず) - 解決案① : ログを見る時に、filter する - 解決案② : ログを “awsfirelens(fluentbit)” に投げる 200 GET / .............................................. 21.35 mb 53.06 ms 200 GET /login ......................................... 21.83 mb 11.78 ms INFO [2024-07-01 10:12:51] local.DEBUG: log dayo 200 GET /register ...................................... 21.79 mb 38.91 ms 200 GET /login ......................................... 21.90 mb 10.59 ms INFO [2024-07-01 10:13:08] local.DEBUG: log dayo 200 GET /register ...................................... 22.00 mb 13.13 ms
  34. ©Fusic Co., Ltd. 47 気にした方がよさそうなこと② これから? : Laravel on AWS(Fargate)

    - 依存性注入(DI) - Octaneを利用すると、アプリのコードをメモリで保持する - register, boot などはワーカが起動してから1度だけ - singleton にしてるサービスクラスは要注意 - リクエストをまたいで同じ情報を取得してしまう - 必要なければ、都度解決する bind にしたほうがよい
  35. ©Fusic Co., Ltd. 48 気にした方がよさそうなこと③ これから? : Laravel on AWS(Fargate)

    - メモリリーク - (再)Octaneを利用すると、アプリのコードをメモリで保持する - 静的な配列にずっと追加をしていると、メモリリークする - 実装時に静的で可変な変数の取り扱いに注意するのと、 メモリをローカル, クラウド側で監視するようにしておく
  36. ©Fusic Co., Ltd. 49 気にした方がよさそうなこと④ これから? : Laravel on AWS(Fargate)

    - 本当にWebサーバいらないの? - 静的ファイルの配信や、SSLターミネイトで必要と書いてある
  37. ©Fusic Co., Ltd. 50 気にした方がよさそうなこと④ これから? : Laravel on AWS(Fargate)

    - 本当にWebサーバいらないの? - 静的ファイルの配信や、SSLターミネイトで必要と書いてある - SSLはALBで、静的ファイルはCloudFrontでキャッシュできる - アプリに到達させたくないリクエストやメンテページはWAF
  38. ©Fusic Co., Ltd. 51 気にした方がよさそうなこと④ これから? : Laravel on AWS(Fargate)

    - 本当にWebサーバいらないの? - 静的ファイルの配信や、SSLターミネイトで必要と書いてある - SSLはALBで、静的ファイルはCloudFrontでキャッシュできる - アプリに到達させたくないリクエストやメンテページはWAF
  39. ©Fusic Co., Ltd. 53 まとめ - Laravel を AWS の

    Fargate で動かすのは面倒 - Nginx(Webサーバ)とPHP-FPM(実行プロセス)が必要 - Laravel Octane でPHPのアプリケーションサーバと統合が簡単にできる - Swoole, Roadrunner, FrankenPHP - 1イメージでFargate上で動かせる - パフォーマンスの向上も期待できるが、実装上の注意はいくつかある。 - 今後検証したいこと - Opcahe, JIT との組み合わせ - 負荷試験 - アプリケーションサーバごとの強みと使いどころの考察
  40. ©Fusic Co., Ltd. 54 Thank You We are Hiring! https://recruit.fusic.co.jp/

    ご清聴いただきありがとうございました