MacにDocker for Macをインストールし複数バージョンのPHP環境を構築する(1)


はじめに

Xamppなどを利用して、Macに対してPHP環境を構築するとPHPやmySQLのバージョン管理などが面倒です。
プロジェクト毎に利用するPHPのバージョンやデータベースの種類・バージョンが異なること多い方も多数いると思います。
Mac環境にDockerをインストールし、複数のPHP環境を構成し切り替える方法などを紹介します。
3部構成で紹介します。

(1) DockerのインストールからNginX環境構築(今回はここ)
(2) NginX+PHP環境の用意
(3) 複数のPHP環境を用意し利用する

動作環境

OS : Mac OS Catalina(10.15.4)

Docker : 19.03.8

※ Docker上に構築することで、実環境が汚れなくてすみますのでこちらをお勧めします。

Docker for Macをインストール

下記にアクセスし「Docker Desktop for Mac」をダウンロードします

Docker Documentation

ダウンロードが完了した後、Applicationフォルダ にドラックドロップします

Dockerアプリを起動します。Dockerアプリを起動すると下記のような画面が表示されます。
「Docker Desktopは管理者権限でのアクセスが必要です」とのこと。OKボタンを押します。
パスワードを聞かれますので、パスワードを入力します。

すると、下記のような画面が表示されます。

Docker IDとパスワードを入力しサインインします。
アカウントを作成していない場合は、アカウントのを作成してください。

これでインストールは完了です。
「ターミナル」を起動し、以下のコマンドを実行すると、インストールバージョンが確認できます

$ docker version

Dockerイメージをダウンロードする

今回はPHP+MySQLの環境を用意するため、以下のイメージをダウンロードします。
この環境をCentOS7の環境に載せます。

$ docker pull mysql
$ docker pull centos:7

Dockerイメージをみてみます。
pullしたものがダウンロードされたことを確認できました。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mysql               latest              8e8c6f8dc9df        3 days ago          546MB
centos              7                   5e35e350aded        5 months ago        203MB

コンテナの作成

まずは、DBサーバコンテナの作成を行います。

$ docker run -it --name mysql -e MYSQL_ROOT_PASSWORD=XXXXXX -d mysql:latest
引数 説明
-it 疑似 TTY(pseudo-TTY)をコンテナの標準入力に接続するよう、 Docker に対して命令します
-e 環境変数を指定します
-d コンテナをバックグラウンドで実行し、コンテナ ID を表示します

DBコンテナの作成が完了したかどうか確認を行ます

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                 NAMES
caf5daa0795a        mysql:latest        "docker-entrypoint.s…"   40 seconds ago      Up 40 seconds       3306/tcp, 33060/tcp   mysql

mysql:latestのコンテナが作成できていることを確認できました。

※ もし、次回起動時以降にコンテナが停止して居た場合は、以下のコマンドで起動できます。 (startの後ろはコンテナ名)

$ docker start mysql

次にCentOS7のコンテナの作成を行ます。
DBコンテナを作成した時を同じように、CentOSのコンテナを作成します。

$ docker run -it --name centos1 -d centos:7

次に CentOSにログインしNginXとMySQLクライアントをインストールします

$ docker exec -it centos1 bash

# ここから CnetOSコマンドで実行

# NginX最新リポジトリをインストール
$ rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm

# NginXインストール
$ yum install -y nginx 

# MySQLをインストール
$ yum install -y mysql

# インストールが完了したら、CentOSを閉じます
$ exit

インストールまで完了したら、ここまでインストールしたコンテナをDockerイメージとしてリポジトリにコミットします。

$ docker commit 645aecbd4669 admin/mycentos1:1.0

上記を実行後、以下ののようにイメージが作成されていることが確認できます。

$ docker images                                 
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
admin/mycentos1     1.0                 dc6c28eb57ac        4 seconds ago       410MB
mysql               latest              8e8c6f8dc9df        3 days ago          546MB
centos              7                   5e35e350aded        5 months ago        203MB

NginX コンテナとMySQLコンテナを接続し、新しいWebサーバコンテナを作成する

WebアプリコンテナからDBコンテナにアクセスする際の方法として、ホストネットワークIPへバインディングせずに、docker runサブコマンドのlinkオプションを活用する方法があります。

linkオプションをりようして、WebアプリコンテナからDBコンテナに接続します。

$ docker run -it --name work_space1 --link mysql:mysql myuser/mycentos1:1.0 bash

–link 連携したいコンテナ名:エイリアス名

こちらでも起動可能です。
外部から指定したポートをコンテナ内部のポートに転送する指定を行います。

$ docker run -it --name work_space1 --link mysql:mysql -d -p 8080:80 myuser/mycentos1:1.0 
$ docker exec -it work_space1 bash

-p ポートフォワーディングの指定

コンテナを起動後、CentOSログイン後に環境変数にMySQL情報が登録されていることを確認する

$ env
HOSTNAME=2550e687a7d1
MYSQL_ENV_MYSQL_ROOT_PASSWORD=password
TERM=xterm
MYSQL_PORT_33060_TCP=tcp://172.17.0.2:33060
MYSQL_PORT_33060_TCP_PORT=33060
MYSQL_ENV_GOSU_VERSION=1.12
MYSQL_PORT_33060_TCP_PROTO=tcp
MYSQL_PORT_3306_TCP_PORT=3306
MYSQL_PORT_3306_TCP=tcp://172.17.0.2:3306
・・・
MYSQL_NAME=/work_space1/mysql
MYSQL_PORT_3306_TCP_PROTO=tcp
MYSQL_PORT_3306_TCP_ADDR=172.17.0.2
MYSQL_PORT_33060_TCP_ADDR=172.17.0.2
MYSQL_ENV_MYSQL_MAJOR=8.0
MYSQL_PORT=tcp://172.17.0.2:3306
_=/usr/bin/env

無事、work_space1のmysqlへの接続設定が登録されていました。
早速MySQLに接続しようと、以下のコマンドを実行すると

mysql -u root -p -h $MYSQL_PORT_3306_TCP_ADDR
Enter password: 
ERROR 2059 (HY000): Authentication plugin 'caching_sha2_password' cannot be loaded: /usr/lib64/mysql/plugin/caching_sha2_password.so: cannot open shared object file: No such file or directory

認証エラーが発生しました。
認証プラグインに caching_sha2_password を設定している場合は、接続に使用するクライアント又はコネクタ側でも caching_sha2_password をサポートしている必要があり、サポートされていない場合は、認証エラーが返されます。

では、クライアント/コネクタ側のどちらにもデフォルトの認証プラグインを変更します。
まずは、sqlコンテナ側のMySQLの設定を確認し、caching_sha2_password に設定されている場合は mysql_native_passwordにrootユーザを変更します。

mysql> SHOW VARIABLES LIKE 'default_authentication_plugin';
+-------------------------------+-----------------------+
| Variable_name                 | Value                 |
+-------------------------------+-----------------------+
| default_authentication_plugin | caching_sha2_password |
+-------------------------------+-----------------------+
1 row in set (0.00 sec)

mysql> ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'password';
Query OK, 0 rows affected (0.02 sec)

mysql> SELECT user, host, plugin FROM mysql.user;
+------------------+-----------+-----------------------+
| user             | host      | plugin                |
+------------------+-----------+-----------------------+
| root             | %         | mysql_native_password |
| mysql.infoschema | localhost | caching_sha2_password |
| mysql.session    | localhost | caching_sha2_password |
| mysql.sys        | localhost | caching_sha2_password |
| root             | localhost | caching_sha2_password |
+------------------+-----------+-----------------------+
5 rows in set (0.00 sec)

mysql> exit
Bye

$ exit

$ docker restart mysql

さて、再度、Webアプリケーション側のコンテナに戻って mysqlにアクセスできるか確認してみましょう

$ mysql -u root -p -h $MYSQL_PORT_3306_TCP_ADDR
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.19 MySQL Community Server - GPL

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> exit
Bye

無事 MySQLにも接続できる様になりました。
(はまった。。。)

最後に

とりあえず、NginX + mySQL環境の構築を完了しました。
次回は、NginX環境にPHPをインストールするところを紹介します。