Posted at

RailsのノリでDockerを使ってNginx+Laravelの環境を作ろうとしたらハマった話


概要

DockerでNginx + Laravelの環境を作ろうとしたらハマったのでまとめました。

仕組みを知るって大切ですね。


ハマった経緯

Railsで下記のような構成のアプリケーションを触っていたため、Nginx+Laravelでもいけるだろと思ったらハマった。


Railsの構成(成功)

rails-rp.png


Laravelの構成(失敗)

laravel-failed.png


何故ハマったかの結論

PumaはWebサーバであるが、PHP-FPMはWebサーバではないから静的ファイルを返さなかった!

当たり前の話なんでしょうけど、コピペで動けばいいやでやってるといずれハマるものですね・・・。


じゃあどうするのが正解?


前提


  • Dockerを利用した場合で考えるので、1コンテナ1プロセスとして設計する
    (Logを収集しやすかったりといろいろと利点がありますよね)

  • 本番環境はKubernetesを利用する


開発環境パターン1(ネット上でよく見るやつ)

NginxとLaravelでソースを共有して静的ファイルを返すパターン

今回ハマってなんで動くのかよく理解ができました・・・!

laravel-success1.png


開発環境パターン2(静的ファイルを分離)

静的ファイルを別サーバで返すようにするパターンです。

LaravelをAPI化してSPAと連携する場合などはこっちの方がよいと思います。(本番でFirebaseとかに投げれるし)

※ LocalではBackendとFrontendを別ディレクトリとしてmountする。

laravel-success2.png


本番環境パターン1(開発環境パターン1に近い形)

1Podに3コンテナはちょっと美しいとは言えないけどFrontとBackをわけていない場合はこれでいいと思います。

laravel-kubernetes1 (1).png


本番環境パターン2(開発環境パターン2に近い形)

開発環境パターン2のようにFrontとBackで分けている場合はこのような構成がいいと思います。

FrontendはFirebaseなどに投げるのもありだと思います。

あとは調査が足りてませんが、頑張ればingress-nginxでfastcgiの対応が可能かもしれません。

laravel-failed (1).png


まとめ


  • PHP-FPMはFastCGIで動作するミドルウェアであり、WebサーバではないためNginxと連携して静的ファイルを返す仕組みが必要になる

  • 上手く連携させるためには2パターンある(サーバを分離しないのも含めると3パターン)


    1. ソースを共有できる場所を用意してNginxでそちらを参照する

    2. 静的ファイルをPHP-FPMサーバから分離する


      • RPサーバに置く事も可能だが、役割を考えると専用にサーバを用意した方がよい






参考文献

Webサーバ、FastCGI、Unixドメインソケット、TCPソケットについて詳しく書かれています

https://qiita.com/kotarella1110/items/634f6fafeb33ae0f51dc