DockerでPHP環境作成(+ MySQL + PHPMyAdmin)

今更ながら、Dockerの勉強もしています。
というか、勉強しないといいかげんヤバい…。
先日、少々詰まりながらも、なんとかPHPの環境を作ってみました。

自分のDocker経験 #

Dockerの知識があるのが当たり前くらいのご時世のなか、まだまだ勉強途中です。

先日、こちらの講座を受講して大まかな仕組みやコマンドは学びましたが、まだ自分で進んで環境作れるような状態ではありません。参考書も買って勉強した方がいいのかな…。

とはいえ、勉強もかねて今回環境を作ってみました。

余談ですが、先日からWSLのUbuntuの調子が悪く、Gitが使えない状態になってしまっています…。調べながらもエラーが解消しなかったため、もうDockerで環境作ろ…となったのでした。

前提 #

  • Docker導入済み
  • docker-composeコマンドが使用できる

PHPのDocker環境 #

作成 #

DockerによるPHP開発環境構築(PHP + MySQL + Nginx)
今回は、こちらの方の記事をベースに進めました。

作成後のフォルダ構成は以下のようになります。

ルート
 ├── mysql
  |   ├── mysql_conf
  |    |   ├── custom.conf
  |   ├── mysql_init
  |    |   ├── init.sql
  |   ├── Dockerfile
 ├── nginx
  |   ├── nginx.conf
 ├── php
  |   ├── Dockerfile
  |   ├── php.ini
 ├── www
  |   ├── html
  |      ├── index.php
 ├── docker-compose.yml

以下、ファイルの簡単な解説です。

custom.conf #

[mysqld]
default_authentication_plugin=mysql_native_password
character-set-server=utf8mb4

[client]
default-character-set=utf8mb4

MySQLの設定ファイルです。
デフォルトの認証方式と文字コードの設定を定義しています。

認証方式については、MySQL8.0.4以降からcaching_sha2_passwordがデフォルトに変更になっています。そのため、従来の方式ではアクセスできなくなってしまう(PHPのMySQL接続ライブラリが対応していない模様)ので、従来の認証方式であるmysql_native_passwordに変更します。

文字コードは文字化け対策です。

init.sql #

CREATE DATABASE test;

USE test;

CREATE TABLE user (
    id int AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    email VARCHAR(255)
);

INSERT INTO user (name, email) VALUES
    ('taro', 'taro@example.com'),
    ('jiro', 'jiro@example.com');

データベースの初期化のSQLです。
あとで、PDOの接続テストもしたかったので、簡単なSQLを書いています。

Dockerfile(MySQL) #

FROM mysql:8.0

ADD ./mysql_conf/custom.cnf /etc/mysql/conf.d/.

CMD ["mysqld"]

CMD ["client"]

明示的にMySQLの設定ファイルを、Docker環境内にADDしています。

こちらについては、ボリュームマウントでも対応可能らしいのですが、自分の場合ボリュームマウントするよりも先(認証方式を修正するより前)にMySQLの初期ユーザが作られてしまったために、アクセスできなくなる状態になってしまったので、ADDするようにしました。

nginx.conf #

server {
    listen 80;
    server_name _;

    root  /var/www/html;
    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;
        fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include       fastcgi_params;
    }
}

Nginxの設定ファイルです。

Dockerfile(PHP) #

FROM php:7.2-fpm

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

RUN apt-get update && \
  # PHPのExtensionをインストール
  docker-php-ext-install pdo_mysql mysqli

PDOの接続テストをしたかったので、追加でインストールしています。

php.ini #

date.timezone = "Asia/Tokyo"

PHPの設定ファイルです。

index.php #

<?php
phpinfo();

最初の動作確認で、PHPのインフォメーションを表示するようにしておきます。

docker-compose.yml #

version: '3'
services:
  nginx:
    image: nginx:latest
    ports:
      - 8080:80
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
      - ./www/html:/var/www/html
    depends_on:
      - php

  php:
    build: ./php
    volumes:
      - ./www/html:/var/www/html
    depends_on:
      - db

  db:
    build: ./mysql
    ports:
      - 13306:3306
    volumes:
      # DB data persistence
      - ./mysql/data:/var/lib/mysql
      # DB initialize data
      - ./mysql/mysql_init:/docker-entrypoint-initdb.d
    environment:
      MYSQL_ROOT_PASSWORD: secret
    command: --innodb-use-native-aio=0

  phpmyadmin:
    image: phpmyadmin/phpmyadmin:latest
    ports:
      - 8888:80
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=db
      - PMA_USER=root
      - PMA_PASSWORD=secret
    depends_on:
      - db

dbの

# DB data persistence
- ./mysql/data:/var/lib/mysql

は、データの永続化。

# DB initialize data
- ./mysql/mysql_init:/docker-entrypoint-initdb.d

は初期化SQLのマウントです。データベースの初期化時に/docker-entrypoint-initdb.d以下にある
SQLを実行してくれるようになっているそうです。

command: --innodb-use-native-aio=0

はエラー対応でいれてます。

phpmyadminの

    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=db
      - PMA_USER=root
      - PMA_PASSWORD=secret

は環境変数でMySQLへのアクセス情報を記載しています。

ちなみにyml内のコメントが英語なのは、日本語で書くとなぜかエラーになってしまったからです(なんでや…)

動作確認 #

docker-compose up -dでコンテナを立ち上げます。

PHP + Nginx #

localhost:8080でPHPのインフォメーション画面が表示されればOKです。
※DockerToolBoxを使用している場合は(DockerホストのIP):8080
PHPインフォメーション画面

PHPMyAdmin #

localhost:8888で次のような画面が表示されればOKです。
docker-compose.ymlで記載した環境変数が正しければ、ログインしている状態になると思います。
PHPMyAdmin画面

PDO #

PDOを使用して、データベースにアクセスできるかも確認したいと思います。

index.phpを修正します。

<?php
try {
    $dsn = "mysql:host=db;dbname=test;";
    $db = new PDO($dsn, 'root', 'secret');
    $sql = "SELECT * FROM user";
    $stmt = $db->prepare($sql);
    $stmt->execute();
    $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
    var_dump($result);
} catch (PDOException $e) {
    echo $e->getMessage();
    exit;
}

localhost:8080にアクセスして、以下のようにデータベースから情報が取得できていればOKです。無事DBにアクセスできています。
DBからのデータ表示画面


たくさんの記事を参考にさせていただきましたが、なんとかPHP環境を作ることができました。
実はLaradockを使って、Laravel環境を作ったりもしているのですが、それはまた別の記事で書こうと思いますー。

参考リンクまとめ #