パーフェクトPHPをDocker環境で

# 概要
パーフェクトPHPで環境構築をローカルでやりたくなかったので、Dockerで環境構築しました。
自分と同じこと考える方もいるかもしれないので記事にしました。

# 前提知識
Dockerを軽く触れる人向けです。
自分はほとんど触れません。

# 内容
パーフェクトPHPではサーバーとしてApacheを使っていますが、自分が使い慣れているのでnginxにしてあります。

## ディレクトリ構成

```
.
├── docker 
│   ├── db
│   │   ├── Dockerfile
│   │   └── my.cnf
│   ├── php
│   │   ├── Dockerfile
│   │   └── php.ini
│   └── nginx
│       └── default.conf
├── server 
│   └── study.localhost <= phpファイルを置く場所(ドキュメントルート)
│       └── index.php   <= 'study.localhost'にアクセスした時に実行されるPHPファイル。(/etc/hosts で設定が必要)
└── docker-compose.yml
```



```yaml:docker-compose.yml
version: "3.9"
services:
  php:
    build:
      context: ./docker/php # 後述
      dockerfile: Dockerfile
    volumes:
      - ./server:/var/www

  nginx:
    image: nginx:1.20-alpine
    ports:
      - 80:80
    volumes:
      - ./server:/var/www
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    working_dir: /var/www

  db:
    build:
      context: ./docker/db #後述
      dockerfile: Dockerfile
    volumes:
      - db-store:/var/lib/mysql
      - ./docker/db/log:/var/log/mysql
    ports:
      - 3306:3306

volumes:
  db-store: null
```

```Dockerfile:docker/db/Dockerfile
FROM mysql:8.0

ENV MYSQL_DATABASE=database \
    MYSQL_USER=docker \
    MYSQL_PASSWORD=docker \
    MYSQL_ROOT_PASSWORD=root \
    TZ=Asia/Tokyo

COPY ./my.cnf /etc/mysql/conf.d/my.cnf

RUN mkdir /var/lib/mysql-files && \
    chmod 644 /etc/mysql/conf.d/my.cnf && \
    chmod 644 /var/lib/mysql-files
```

```conf:docker/db/my.cnf
[mysqld]
# default
skip-host-cache
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
secure-file-priv=/var/lib/mysql-files
user=mysql

pid-file=/var/run/mysqld/mysqld.pid

# character set / collation
character_set_server = utf8mb4
collation_server = utf8mb4_ja_0900_as_cs_ks

# timezone
default-time-zone = SYSTEM
log_timestamps = SYSTEM

# Error Log
log-error = /var/log/mysql/error.log

# Slow Query Log
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow-query.log
long_query_time = 1.0
log_queries_not_using_indexes = 0

# General Log
general_log = 1
general_log_file = mysql-general.log

[mysql]
default-character-set = utf8mb4

[client]
default-character-set = utf8mb4
```

```conf:docker/nginx/default.conf

   
server {
    listen 80;
    server_name study.localhost;
    root /var/www/study.localhost;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    index index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_pass php:9000;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}
# バーチャルホスト設定は以下に追加するとできます。
server {
   listen 80;
   server_name study2.localhost; # server_nameを追加するホスト名に設定する。
   # 以下省略(上記 serverディレクティブの内容と同じで大丈夫なはず)
}
```

```Dockerfile:docker/php/Dockerfile
FROM php:8.0-fpm-buster
SHELL ["/bin/bash","-oeux","pipefail","-c"]

RUN docker-php-ext-install pdo_mysql

COPY ./php.ini /usr/local/etc/php/php.ini

WORKDIR /var/www
```

```ini:php.ini
zend.exception_ignore_args = off
expose_php = on
max_execution_time = 30
max_input_vars = 1000
upload_max_filesize = 64M
post_max_size = 128M
memory_limit = 256M
error_reporting = E_ALL
display_errors = on
display_startup_errors = on
log_errors = on
error_log = /var/log/php/php-error.log
default_charset = UTF-8

[Date]
date.timezone = Asia/Tokyo

[mysqlnd]
mysqlnd.collect_memory_statistics = on

[Assertion]
zend.assertions = 1

[mbstring]
mbstring.language = Japanese
```



# まとめ
以上のファイルを１つのディレクトリに入れて、`docker compose up`すれば動くはず。
パーフェクトPHPを進めながら動かなくなったり、設定足りなければ随時修正予定。