Docker で Nginx 1.19 + PHP 7.4 + MariaDB 10.5 環境を構築

はじめに

今日は Docker で Nginx 1.19 + PHP 7.4 + MariaDB 10.5 + phpMyAdmin 環境を構築する方法を紹介します。

Docker
19.03.1
Docker Compose
1.24.1
目次
  1. 下準備
  2. 構築方法
  3. Nginx コンテナ
  4. PHP-FPM コンテナ
  5. MariaDB コンテナ
  6. phpMyAdmin コンテナ
  7. おわりに

1. 下準備

今回は下記のようなファイル構成にします。

/path/to/your-dir/
  ├ docker/
  │  ├ initdb/
  │  │  └ articles.sql
  │  │
  │  ├ myapp-php/
  │  │  └ Dockerfile
  │  │
  │  ├ nginx-templates/
  │  │  └ default.conf.template
  │  │
  │  └ docker-compose.yml
  │
  └ html/
      └ index.php

initdb/articles.sql は、データベースに articles テーブルを作成するためのファイルです。MariaDB コンテナ生成後に自動的にインポートします。

myapp-php/Dockerfile には、PHP-FPM コンテナを作る際に pdo_mysql 拡張をインストールする処理を書きます。

nginx-templates/default.conf.template は Nginx の設定ファイルで、今回はドキュメントルート変更と PHP 使用のために使います。

html フォルダは Nginx と PHP-FPM コンテナにマウントして、動作確認として index.php を動かします。

動作確認で使用したデータベースと index.php は以下の通りです。

/docker/initdb/articles.sql
SET CHARACTER_SET_CLIENT = utf8mb4;
SET CHARACTER_SET_CONNECTION = utf8mb4;

CREATE TABLE articles (
  id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  body varchar(255) NOT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO articles (id, body) VALUES
(1, 'テスト1'),
(2, 'テスト2');
/html/index.php
<?php
// ユーザー名やパスワードなどは、
// 後ほど紹介する docker-compose.yml と併せて適宜変更してください
$dsn = 'mysql:dbname=sampledb;host=myapp-db';
$db = new PDO($dsn, 'sample-user', 'hi2mi4i6');

$sql = 'SELECT * FROM articles';
echo '<pre>';
foreach ($db->query($sql) as $row) {
  var_dump($row);
}
echo '</pre>';

2. 構築方法

下記3つのファイルを作成して docker-compose コマンドを実行し、コンテナをビルド&起動します。

/docker/docker-compose.yml
version: "3"

services:
  # Nginx
  myapp-web:
    container_name: myapp-web
    image: nginx:1.19
    depends_on:
      - myapp-php
      - myapp-db
    ports:
      - "80:80"
    volumes:
      - "./nginx-templates:/etc/nginx/templates"
      - "../html:/var/www/html"

  # PHP-FPM
  myapp-php:
    container_name: myapp-php
    build:
      context: ./myapp-php
      dockerfile: Dockerfile
    volumes:
      - "../html:/var/www/html"

  # MariaDB
  myapp-db:
    container_name: myapp-db
    image: mariadb:10.5
    volumes:
      - "./initdb:/docker-entrypoint-initdb.d"
    environment:
      MYSQL_DATABASE: sampledb
      MYSQL_USER: sample-user
      MYSQL_PASSWORD: hi2mi4i6
      MYSQL_ROOT_PASSWORD: mu7ya9to

  # phpMyAdmin
  myapp-pma:
    container_name: myapp-pma
    image: phpmyadmin/phpmyadmin:5.0
    depends_on:
      - myapp-db
    ports:
      - "8080:80"
    environment:
      PMA_HOST: myapp-db
      PMA_USER: sample-user
      PMA_PASSWORD: hi2mi4i6
/docker/nginx-templates/default.conf.template
server {
    root  /var/www/html;

    location / {
        index  index.html index.php;
    }

    location ~ \.php$ {
       fastcgi_pass   myapp-php:9000;
       fastcgi_param  SCRIPT_FILENAME  $document_root/$fastcgi_script_name;
       include        fastcgi_params;
    }
}
/docker/myapp-php/Dockerfile
FROM php:7.4-fpm

RUN docker-php-ext-install pdo_mysql
$ cd /path/to/your-dir/docker
$ docker-compose up -d

コンテナの起動が完了したら、確認のためにブラウザで Nginx のコンテナにアクセスしてください。
(URL は http://localhost/ や http://192.168.99.100/ など Docker の環境によります)

前述のサンプルをご使用の場合は下記のようなダンプ結果が出れば OK です。

起動直後にアクセスするとデータベースに接続できないエラーが発生するかもしれません。
その際は少し待ってから、ブラウザの再読み込みを試してください。

array(4) {
  ["id"]=>
  string(1) "1"
  [0]=>
  string(1) "1"
  ["body"]=>
  string(10) "テスト1"
  [1]=>
  string(10) "テスト1"
}
array(4) {
  ["id"]=>
  string(1) "2"
  [0]=>
  string(1) "2"
  ["body"]=>
  string(10) "テスト2"
  [1]=>
  string(10) "テスト2"
}

phpMyAdmin は 8080 ポートでアクセスできます。
(http://localhost:8080 など)

次に各コンテナの docker-compose.yml の内容について解説します。

3. Nginx コンテナ

/docker/docker-compose.yml
myapp-web:
  container_name: myapp-web
  image: nginx:1.19
  depends_on:
    - myapp-php
    - myapp-db
  ports:
    - "80:80"
  volumes:
    - "./nginx-templates:/etc/nginx/templates"
    - "../html:/var/www/html"

depends_on オプションを指定すると、myapp-web コンテナを起動する前に myapp-php、myapp-db コンテナが起動するようになります。

次に volumes ですが、Nginx の公式イメージではコンテナ内で /etc/nginx/templates/*.template に該当するファイルが/etc/nginx/conf.d の中にコピーされます。
(その際、ファイル名末尾の .template は削除されます。)

この機能を使って独自の設定ファイルを使用するために、 ローカルの /docker/nginx-templates を コンテナの /etc/nginx/templates/ にマウントしています。

設定ファイルのフォルダや、ファイル名のサフィックス(末尾の.template)は environment オプションで変更できるようです。詳しくは下記 Docker Hub の Nginx のページに書いてありますのでご確認ください。

4. PHP-FPM コンテナ

/docker/docker-compose.yml
myapp-php:
  container_name: myapp-php
  build:
    context: ./myapp-php
    dockerfile: Dockerfile
  volumes:
    - "../html:/var/www/html"

pdo_mysql 拡張を導入するため build オプション と Dockerfile を使っています。build オプションにつきましては、先日投稿した「Docker Compose で Dockerfile を直接指定してコンテナ作成」でも紹介していますので、よろしければご覧ください。

5. MariaDB コンテナ

/docker/docker-compose.yml
myapp-db:
  container_name: myapp-db
  image: mariadb:10.5
  volumes:
    - "./initdb:/docker-entrypoint-initdb.d"
  environment:
    MYSQL_DATABASE: sampledb
    MYSQL_USER: sample-user
    MYSQL_PASSWORD: hi2mi4i6
    MYSQL_ROOT_PASSWORD: mu7ya9to

MariaDB の公式イメージでは、コンテナがはじめて起動した際に /docker-entrypoint-initdb.d 内の SQL が実行されます。initdb/articles.sql の先頭にある utf8mb4 の指定は、文字化け防止用です。

使用できる environment についても、下記 Docker Hub のページに説明があります。

6. phpMyAdmin コンテナ

/docker/docker-compose.yml
myapp-pma:
  container_name: myapp-pma
  image: phpmyadmin/phpmyadmin:5.0
  depends_on:
    - myapp-db
  ports:
    - "8080:80"
  environment:
    PMA_HOST: myapp-db
    PMA_USER: sample-user
    PMA_PASSWORD: hi2mi4i6

Nginx と同様に depends_on オプションで MariaDB の後に立ち上がるようにしています。

ports オプションで 8080 ポートでアクセスするように設定していますが、お好みで変更して差し支えありません。

environment については、他と同様に Docker Hub に説明があります。

7. おわりに

Docker Compose を用いた Nginx の環境構築は、以前「Docker で PHP 7.4 と MariaDB 10.5 の LAMP + phpMyAdmin 環境を構築する方法」でご紹介した LAMP 環境の時とは手順が少し違っていますね。

現時点では PHP + Nginx な公式イメージが見当たらなかったので、それぞれのコンテナを作りました。LAMP の時と比べて少し手間は増えていますが、一度出来てしまえばあまり負担にはならないかな、という印象です。

Docker Compose を使用する際には公式サイトや、Docker Hub の各イメージのドキュメントは参考になると思います。英語なので敷居が高いかもしれませんが、是非読んでみてください。