Dockerで環境構築（php-fpm+nginx）

# はじめに
初めまして！
エンジニアになって数年、今まで本を読むだけでしたが、もっとプライベートで楽しみながら成長したい！自分が学んだ足跡を残していきたい！と思い記事をかきました！
最終的には自在に開発できるようになりたいと思っています。:triumph:
いろいろな記事を参考にさせてもらっています。:bow_tone2:
その中でもこれってどういう意味？とかつまづいたところを念入りに書いていこうかと思います。:fist:

# 今回の目的
今回はこちらの記事で調べていた内容を実践してみたいと思い別の記事として作成しました！

https://qiita.com/mr_noppo/items/abe96bd0b7200c0cbc6e

「php:\<version>-apache」は初歩のチュートリアルで使っていたような気がするけど、「php:\<version>-fpm」というものは何ぞや、実際に動かせばなんかスッキリするかも？となったのが経緯です！

# 作成した環境

https://github.com/takizawa0548/sample-nginx-fpm

## 使用したものや事前準備
・Macbook Pro
・Docker
・Visual Studio Code
・PHP
・nginx

## 主に参考にさせていただいた記事

https://www.nginx.com/resources/wiki/start/topics/examples/phpfcgi/#connecting-nginx-to-php-fpm

他参考サイト含めて本文でも紹介します！:fist:

# FPMとnginxって？

実際に構築チャレンジしようにも、FPMとnginxって何を意味しているの？となったので自分なりに調べてみました。

### FPM
FastCGI Process Managerの略称です。


・FastCGIとは
「プロセスの起動/終了」を省略し、従来のCGIよりも高速化やCPU負荷の軽減で優れている。モジュール版PHPと速度は同等。

※モジュール版PHPとは・・・WebサーバーのプロセスのなかでPHPを実行するという意味で高速な反面セキュリティ面に不安がある

https://www.xserver.ne.jp/manual/man_server_php_fastcgi.php#:~:text=%E3%80%8CFastCGI%E3%80%8D%E3%81%A8%E3%81%AF%E3%80%81%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9,%E3%82%92%E6%8C%81%E3%81%A4%E5%8B%95%E4%BD%9C%E6%96%B9%E5%BC%8F%E3%81%A7%E3%81%99%E3%80%82

・CGIとは
動的なページ作成に必要な仕組み。従来のCGIには弱みがあり、リクエストのたびに新しいプロセスを起動するため、大規模環境では負荷が大きく性能向上の妨げとなっている。Apacheが標準でサポートしているが、nginxはサポートしていない。
nginxはサポートしていない代わりにFastCGIなどのプロトコルを使用して、バックエンドのプロセス（FastCGI）と通信し効率的に処理をする。

https://e-words.jp/w/CGI.html

### nginx
エンジンエックスと読みます。Apacheと同様、Webサーバーです。
2022年に一位だったApacheとシェアが逆転したようです。
単体なら静的なページを返すのに使います。（スタイルシートやJSなどブラウザにそのまま返すもの）
下記の記事が読みやすいので紹介程度で止めておきます。

https://cn.teldevice.co.jp/column/38275/

# コンテナ内探索
なんとなく概要がつかめたところで、php:\<version>-fpmとnginxのDockerイメージで環境構築をしていきます。
パパッとやってやるぜ〜って思いましたが、思ったより理解できていなかったので単体イメージで何を設定していくといいのかをみていきます。

### php:\<version>-fpm
あまり見るところはなかったですが、phpファイルを配置する場所を確認しておきましょう。
/var/www/htmlにphpファイルが配置されるようにするとよさそうですね。

```bash
docker container run -it --rm php:8.3-fpm-bookworm /bin/bash
```

ただここら辺ですが、フレームワーク入れたい時とか静的ファイルとか構成や配置どうなるの？というのが疑問点。
以下の記事が大変参考になりそうので興味ある方はこちらにどうぞ。:point_down:

https://qiita.com/khara_nasuo486/items/1aa40d26efb3eb9a5a04

### nginx
FastCGI設定が難しそうです。下記を参考に確認していきます。

https://www.nginx.com/resources/wiki/start/topics/examples/phpfcgi/#connecting-nginx-to-php-fpm

コンテナを立ち上げて中に入ります。
```bash
docker container run -it --rm nginx:1.25.4-bookworm /bin/bash
```

検証に必要なコマンドをインストールしておきます。
```bash
apt update
apt install -y vim
apt install -y tree
```
検証箇所へ移動し構成を確認をしましょう。
```bash
cd /etc/nginx/
tree /etc/nginx/
```
![スクリーンショット 2024-02-24 11.50.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/7762be6e-1381-0fce-708c-61090bac09d4.png)

今回は、default.confとfastcgi_paramsをマウントして対応していきます。
他のサイトを見ると、nginx.confを編集したりしていたりまだまだやらなくてはいけないことも多そうです。

fastcgi_paramsは、参考サイトの方が設定値多いのでとりあえずそちらを使います。
```bash
cat /etc/nginx/fastcgi_params 
```

default.confは、参考サイトのほかに、listenやrootは最低限、必要そうです。
```
cat /etc/nginx/conf.d/default.conf
```

またnginxはmainlineとstableがあります。
stableはサポート終了後にmainlineへ取り込まれるので、なるべくmainlineのバージョンを選択しましょう。

https://nginx.org/

# Dockerで環境構築
作業PCのディレクトリ構成はこんな感じ。先ほどの内容をこちらに反映させます。

![スクリーンショット 2024-02-24 17.50.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/d0ae5756-79a5-35a6-7888-e572bb221b96.png)


### test.php
参考サイトのまま使いましょう。index.phpは自由です。

### compose.yml
nginxのポートを開いて、経由でapiコンテナのphpファイルを返却します。
networksを設定してコンテナ間の通信のみに制限しています。コンテナが増えてきたらそれぞれで制限をかけていきたい。

```yml
version: '3'
services:
  nginx:
    image: nginx:1.25.4-bookworm
    ports:
      - 8080:80
    volumes:
      - ./nginx/fastcgi_params:/etc/nginx/fastcgi_params
      - ./nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - app
    networks:
      - app-network
  app:
    image: php:8.3-fpm-bookworm
    volumes:
      - ./app:/var/www/html
    networks:
      - app-network 

networks:
  app-network:
    driver: bridge
```

### default.conf
rootをphp:\<version>-fpmコンテナに対応させています。
【api:9000;】のような記述は、左が「compose.ymlに記載しているサービス名（コンテナ名）」になります。DBコンテナに接続する時にも使うので覚えておきたいです。

```conf
server {
    listen       80;
    server_name  localhost;
    root /var/www/html;
    location / {
       fastcgi_param HTTP_PROXY "";
       fastcgi_pass api:9000;
       fastcgi_index index.php;
       include fastcgi_params;
    }
    location ~ [^/]\.php(/|$) {
       fastcgi_param HTTP_PROXY "";
       fastcgi_pass api:9000;
       include fastcgi_params;
    }
}
```

### fastcgi_params
参考サイトと同様です。

```conf
fastcgi_param   QUERY_STRING            $query_string;
fastcgi_param   REQUEST_METHOD          $request_method;
fastcgi_param   CONTENT_TYPE            $content_type;
fastcgi_param   CONTENT_LENGTH          $content_length;

fastcgi_param   SCRIPT_FILENAME         $document_root$fastcgi_script_name;
fastcgi_param   SCRIPT_NAME             $fastcgi_script_name;
fastcgi_param   PATH_INFO               $fastcgi_path_info;
fastcgi_param   PATH_TRANSLATED         $document_root$fastcgi_path_info;
fastcgi_param   REQUEST_URI             $request_uri;
fastcgi_param   DOCUMENT_URI            $document_uri;
fastcgi_param   DOCUMENT_ROOT           $document_root;
fastcgi_param   SERVER_PROTOCOL         $server_protocol;

fastcgi_param   GATEWAY_INTERFACE       CGI/1.1;
fastcgi_param   SERVER_SOFTWARE         nginx/$nginx_version;

fastcgi_param   REMOTE_ADDR             $remote_addr;
fastcgi_param   REMOTE_PORT             $remote_port;
fastcgi_param   SERVER_ADDR             $server_addr;
fastcgi_param   SERVER_PORT             $server_port;
fastcgi_param   SERVER_NAME             $server_name;

fastcgi_param   HTTPS                   $https;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param   REDIRECT_STATUS         200;
```

# コンテナ起動＆アクセス
```
docker compose up -d
```

起動したらアクセスしてみましょう。
http://localhost:8080/test.php

下記の画像のような情報が改行なしで表示されたら成功です！

![スクリーンショット 2024-02-24 18.47.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/8e284f46-86ee-3ec3-b709-e2f924adac41.png)

## 最後に
今回はなんとか動くレベルまでいけました。途中でnginxからphp呼べなくて数時間、頭の中を猫ミームが流れていました・・・。
参考にしたサイトも多いので、上で紹介できていないサイトを書けるだけ書いておきます！ぜひご参考ください！

## 参考

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

https://qiita.com/shir01earn/items/f236c8280bb745dd6fb4#docker-composeyml-%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E4%BD%9C%E6%88%90

https://qiita.com/hinako_n/items/f15646ea548bcdc8ac6c#%E8%A8%AD%E5%AE%9A%E3%83%95%E3%82%A1%E3%82%A4%E3%83%ABdefaultconf

https://qiita.com/morrr/items/7c97f0d2e46f7a8ec967

https://qiita.com/khara_nasuo486/items/1aa40d26efb3eb9a5a04

## おまけ
より広く構築してみました

https://qiita.com/mr_noppo/items/1643652347ecfd836889