Docker初心者がAmazon Linux2を前提にNginxとPHP-FPMの開発環境を整えてみた

# 前提
前提として下記のような環境を整えた際の備忘録となります。
・Amazon Linux2
・Nginx
・PHP-FPM

作成したコンテナとしては、NginxとPHP-FPMになります。
ハマりポイントとしては、NginxとPHP-FPMの連携部分です。

## ディレクトリ構成
ディレクトリ構成としては下記のようにしました。
application/
     　├app/
     　    　└application/
     　└docer-image/
     　     　├nginx/
     　     　     　├Dockerfile
     　     　     　├nginx.conf
     　     　     　└default.conf
     　     　└php/
     　     　     　├Dockerfile
     　     　     　├php.ini
     　     　     　└www.conf
　　docker-compose.yml

## Nginxコンテナの作成
```Dockerfile:Dockerfile
FROM amazonlinux:2

RUN yum -y update

# install nginx
RUN amazon-linux-extras install nginx1.12

# automatic start
ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"]

COPY ./default.conf /etc/nginx/conf.d/default.conf
COPY ./nginx.conf /etc/nginx/nginx.conf
```
ポイントとしてはyumではなくamazon-linux-extrasでインストール（※yumでもインストールできますが「yum install nginx」だとnginxが提供されていないらしくエラーになるのでリポジトリのURLを指定して下さい）。

```default.conf
server {
    listen 80;
    server_name localhost 127.0.0.1;

    root /usr/share/nginx/html/app/public;
    index index.php index.html;

    access_log /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        fastcgi_pass                  php:9000;
        fastcgi_index                 /index.php;
        include                       /etc/nginx/fastcgi_params;
        fastcgi_split_path_info       ^(.+\.php)(/.+)$;
        fastcgi_param PATH_INFO       $fastcgi_path_info;
        fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        # Security
        add_header X-Content-Type-Options "nosniff";
        add_header X-XSS-Protection "1; mode=block";
        
        add_header Access-Control-Allow-Origin '*';
        add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE';
        add_header Access-Control-Allow-Headers 'Origin, Authorization, Accept, Content-Type';
    }
}
```
Securityについては適時変更してください。
rootについてはpublic/にindex.phpがある想定です。
ポイントはfastcgi_passです。ここにphp:9000とありますが、「php」はdocker-composeで指定するアプリケーションのサービス名です。dockerで構築している場合はサービス名がホスト名になるので今回は「php」を指定しました。9000についてはPHP-FPMは9000ポート（デフォルト）で待ち受けするのでこちらを指定しています。

```nginx.conf
user nginx;
worker_processes auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    server_tokens           off;
    sendfile                on;
    tcp_nopush              on;
    keepalive_timeout       10;
    fastcgi_read_timeout    300;

    include /etc/nginx/conf.d/*.conf;
}
```
userをnginxにします。

## PHP-FPMコンテナの作成
```Dockerfile:Dockerfile
FROM amazonlinux:2

RUN yum -y update

# install php7.3
RUN amazon-linux-extras install php7.3 -y

# use php-fpm default tcp
EXPOSE 9000

# run php-fpm in the foreground
ENTRYPOINT /usr/sbin/php-fpm -F

COPY ./www.conf /etc/php-fpm.d/www.conf
COPY ./php.ini /usr/local/etc/php/php.ini
```
ポイントとしてはEXPOSE 9000にするところです。ここはホストと連携する必要はありません。docker psコマンドで確認を行うとTCP9000で通信しているのが分かります。
また、PHP-FPMコンテナはフォアグラウンドで実行です。（https://qiita.com/yasumon/items/93f7bd975aae1c7b54ed）

```www.conf
listen = 9000

listen.owner = nginx
listen.group = nginx
listen.mode = 0666

user = nginx
group = nginx

以下略
```
ポイントとしてはlistenを9000にするところです。（https://teratail.com/questions/153148）
また、その他の設定部分で127.0.0.1の記述があればNginxと連携できずエラーになるので気をつけましょう。

php.iniについては省略します。

## docker-compose.yml
```docker-compose.yml
version: '3'

services:
  nginx:
    container_name: nginx
    build:
      context: ./docker-image/nginx/
    ports:
      - '8000:80'
    volumes:
      - ./:/usr/share/nginx/html
      - ./log/nginx:/var/log/nginx/
    depends_on:
      - php
    networks:
      - common

  php:
    container_name: php
    build:
      context: ./docker-image/php/
    volumes:
      - ./:/usr/share/nginx/html
      - ./log/php:/var/log/php-fpm
    networks:
      - common

  networks:
    common:
      driver: bridge
```

これらの設定でlocalhost:8000でブラウザで確認できるかと思います。

## まとめ
amazonlinuxにnginxとphp-fpmでそれぞれコンテナ作成して連携する参考があまりなかったので備忘録を兼ねてまとめました。間違い等あればご指摘ください。

以上