🔰はじめての方へ

【データベース×Docker】PHPサイトをローカルで動かす環境を作る方法| 各コード説明

Docker
記事内に広告が含まれています。
スポンサーリンク

はじめに

Web制作をしていると、こんな場面がありませんか?

  • コードを書いたけど、レンタルサーバーにアップロードしないと動作確認できない
  • データベースを使うページを作ったけど、ローカルで確認する方法がわからない
  • PHPファイルをブラウザで開いても、コードがそのまま表示されてしまう

これらの問題を解決してくれるのが Docker です。

この記事では、PHP + MySQL + phpMyAdmin の環境をDockerで構築する方法を、初心者向けに解説します。

Docker初心者の方は、 Docker Desktopを使うことをお勧めします。

私でも使えたので!

下記記事に詳しい設定方法を掲載しているのでご参照ください。

【初心者でもわかる】 Docker Desktopを導入してプロジェクトで使えるようにする方法
はじめにDockerを使うには、まず Docker Desktop というアプリをインストールする必要があります。この記事では、Docker Desktopのインストールから、プロジェクトで使い始めるまでの手順をまとめます。Dockerは奥…

Dockerとは?

Dockerは 「自分のパソコンの中に、小さなサーバーを作る道具」 です。

通常、PHPやデータベースを使うWebサイトを動かすには レンタルサーバー が必要です。

でも開発中に毎回リモートにFTPなどを使用してアップロード→確認するのは大変です。

Dockerを使うと、自分のパソコンの中に レンタルサーバーとほぼ同じ環境 を作って、ローカルで動作確認ができるようになります。


ファイル構成

今回作成するファイルの全体像です。

プロジェクト/
├── docker-compose.yml          ← 「監督」全体をまとめる指示書
├── docker/
│   ├── Dockerfile              ← Nginx(Webサーバー)の設計図
│   ├── nginx.conf              ← Nginxの設定ファイル
│   └── php/
│       └── Dockerfile          ← PHP の設計図
└── sample/
    └── public/                 ← 実際のWebサイトのファイル

なぜファイルの場所がバラバラなの?

docker-compose.ymlがルート(一番上)にある理由:
  全体の「監督」なので、プロジェクトの一番上に置くのがルールです。

Dockerfiledocker/フォルダの中にある理由:
  Dockerfileは各サーバーの「設計図」です。
  Docker関連のファイルとしてdocker/フォルダにまとめて、整理整頓しています。
  NginxとPHPで設計図が異なるので、PHPの設計図はさらにdocker/php/フォルダの中に入れています。


docker-compose.yml ― 全体の「監督」

docker-compose.yml「どのサーバーを何台立てるか」を書いた指示書 です。

映画の撮影に例えると:

docker-compose.yml = 映画の監督
  ├── web(Nginx)     = カメラマン(お客さんにページを見せる係)
  ├── php(PHP)        = 役者(PHPコードを実行する係)
  ├── db(MySQL)       = 台本(データを保存する係)
  └── phpmyadmin       = 台本エディタ(データを見たり編集する画面)

以下が全体のコードです。1つずつ解説していきます。

services:
  web:
    build:
      context: .
      dockerfile: docker/Dockerfile
    ports:
      - "80:80"
    volumes:
      - ./sample/public:/var/www/html/public
    depends_on:
      - php

  php:
    build:
      context: .
      dockerfile: docker/php/Dockerfile
    volumes:
      - ./sample/public:/var/www/html/public
    depends_on:
      - db

  db:
    image: mysql:8.0
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: my_database
      MYSQL_USER: my_user
      MYSQL_PASSWORD: my_password
    volumes:
      - db_data:/var/lib/mysql

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    ports:
      - "8080:80"
    environment:
      PMA_HOST: db
      PMA_USER: root
      PMA_PASSWORD: root
    depends_on:
      - db

volumes:
  db_data:

web(Nginx ― Webサーバー)

web:
  build:
    context: .
    dockerfile: docker/Dockerfile
  ports:
    - "80:80"
  volumes:
    - ./sample/public:/var/www/html/public
  depends_on:
    - php
設定意味
build: dockerfile:docker/Dockerfile を設計図として使ってサーバーを作る
ports: "80:80"ブラウザで localhost にアクセスするとこのサーバーにつながる
volumes:自分のPCの public/ フォルダをサーバーの中から見えるようにする
depends_on: phpPHPサーバーが先に起動してから、このサーバーを起動する

volumes とは?

自分のパソコンのフォルダと、Docker内のサーバーのフォルダを 同期 させる仕組みです。

自分のPC                           Docker内のサーバー
public/index.php     ←  同期  →    /var/www/html/public/index.php

これにより、自分のPCでファイルを編集すると、Docker内のサーバーにも即座に反映されます。いちいちファイルをコピーする必要がありません。

depends_on とは?

サーバーの起動順序を指定します。Nginxが先に起動してしまうと、PHPサーバーがまだ動いていないのでエラーになります。depends_on: php と書くことで「PHPが先に起動してからNginxを起動してね」と伝えています。


php(PHP-FPM)

php:
  build:
    context: .
    dockerfile: docker/php/Dockerfile
  volumes:
    - ./sample/public:/var/www/html/public
  depends_on:
    - db

PHPコードを実行するためのサーバーです。NginxがPHPファイルへのリクエストを受け取ると、このPHPサーバーに転送して処理してもらいます。

depends_on: db と書いてあるので、データベースが起動してからPHPが起動します。

起動順序はこうなります:

db(MySQL)→ php(PHP)→ web(Nginx)

db(MySQL ― データベース)

db:
  image: mysql:8.0
  ports:
    - "3306:3306"
  environment:
    MYSQL_ROOT_PASSWORD: your_root_password
  MYSQL_DATABASE: sample_database
  MYSQL_USER: sample_user
  MYSQL_PASSWORD: your_password
  volumes:
    - db_data:/var/lib/mysql
設定意味
image: mysql:8.0MySQLの既製品をそのまま使う
ports: "3306:3306"3306番ポートでアクセスできる
environment:初回起動時にDB・ユーザー・パスワードを自動的に作成する
volumes: db_dataDockerを停止してもデータが消えないように保存する

buildimage の違い:

build:  → Dockerfileという設計図から自分でカスタムして作る
image:  → 既製品をそのまま使う(カスタム不要な時)

MySQLはそのまま使えるので image、PHPはDB接続用の拡張機能を追加する必要があるので build を使っています。

environmentとは?

サーバーに渡す 初期設定 です。MySQLの場合、初回起動時にここに書いた値でデータベースやユーザーが自動作成されます。

環境変数意味
MYSQL_ROOT_PASSWORD管理者(root)のパスワード
MYSQL_DATABASE自動で作成するデータベース名
MYSQL_USER自動で作成するユーザー名
MYSQL_PASSWORDそのユーザーのパスワード

phpmyadmin(DB管理画面)

phpmyadmin:
  image: phpmyadmin/phpmyadmin
  ports:
    - "8080:80"
  environment:
    PMA_HOST: db
    PMA_USER: root
    PMA_PASSWORD: your_root_password
  depends_on:
    - db

ブラウザで localhost:8080 にアクセスすると、phpMyAdminの画面が開きます。

設定意味
PMA_HOST: db上で定義した db サービスに接続する
PMA_USER: rootrootユーザーでログインする
PMA_PASSWORD: rootrootのパスワード

PMA_HOST: dbdb は、docker-compose.yml内で定義した サービス名 です。Docker内ではサービス名がそのままホスト名(接続先の名前)として使えます。


volumes(データ保存領域)

volumes:
  db_data:

db_data という名前のデータ保存領域を作ります。

これがないと、docker compose down でDockerを停止するたびに データベースの中身が全部消えてしまいますdb_data にデータが保存されるので、停止しても安心です。


Dockerfile ― 各サーバーの「設計図」

docker/Dockerfile(Nginx用)

FROM nginx:alpine

COPY ./docker/nginx.conf /etc/nginx/conf.d/default.conf

WORKDIR /var/www/html

COPY ./sample/public /var/www/html/public

RUN chown -R nginx:nginx /var/www/html && \
    chmod -R 755 /var/www/html

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]
命令意味
FROM nginx:alpineNginxの軽量版を土台にする(家を建てる時の「基礎」)
COPY ... nginx.conf自分で作ったNginxの設定ファイルをサーバーにコピーする
WORKDIR作業フォルダを設定する
COPY ... publicWebサイトのファイルをサーバーにコピーする
RUN chown ... chmodファイルの権限を設定する(セキュリティ対策)
EXPOSE 8080番ポートを開ける
CMD [...]Nginxを起動する

docker/php/Dockerfile(PHP用)

FROM php:7.4-fpm

RUN docker-php-ext-install pdo pdo_mysql mysqli

RUN apt-get update && apt-get install -y libonig-dev && docker-php-ext-install mbstring

WORKDIR /var/www/html
命令意味
FROM php:7.4-fpmPHP 7.4を土台にする
RUN ... pdo pdo_mysql mysqliMySQLに接続するための拡張機能を追加する
RUN ... mbstring日本語を扱う関数(mb_strlen等)を使えるようにする
WORKDIR作業フォルダを設定する

なぜPHPにだけRUNで追加インストールが必要なの?

PHPの公式Dockerイメージには、データベース接続機能が最初から入っていません。pdo_mysql を追加しないと、db_file.phpnew PDO(...) が「そんな機能ありません」とエラーになります。

同様に mbstring を追加しないと、data.phpmb_strlen() が使えません。


nginx.conf ― Nginxの設定ファイル

server {
    listen 80;
    server_name localhost;
    root /var/www/html/public;
    index index.php index.html;

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

    location ~ \.php$ {
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}
設定意味
listen 8080番ポートで待ち受ける
root /var/www/html/publicWebサイトのファイルがある場所
index index.php index.htmlURLにファイル名がない時、最初に開くファイル
location ~ \.php$.php で終わるファイルへのリクエストの場合…
fastcgi_pass php:9000PHPサーバーに処理を転送する

fastcgi_pass php:9000php は、docker-compose.ymlのPHPサービス名です。Nginxは自分ではPHPを実行できないので、PHPファイルへのリクエストが来たら、PHPサーバーに「代わりに処理してね」と転送しています。


4つのサーバーの連携図

ブラウザで localhost にアクセス
        │
        ▼
┌─────────────────┐
│   web (Nginx)   │  HTMLや画像 → そのまま返す
│   ポート: 80     │  PHPファイル → phpサーバーに転送
└────────┬────────┘
         │ .phpファイルの場合
         ▼
┌─────────────────┐
│   php (PHP-FPM) │  PHPコードを実行する
│   ポート: 9000   │  DBが必要ならdbに問い合わせる
└────────┬────────┘
         │ データが必要な場合
         ▼
┌─────────────────┐
│   db (MySQL)    │  データを保存・返す
│   ポート: 3306   │
└─────────────────┘
         ▲
         │ ブラウザからアクセスして管理
┌────────┴────────┐
│  phpmyadmin     │  DBの中身を見たり編集する管理画面
│  ポート: 8080    │
└─────────────────┘

基本的な使い方

起動する

docker compose up --build

--build をつけると、Dockerfileの変更が反映されます。初回や設定を変更した後は必ずつけましょう。

ブラウザで確認

URL何が見えるか
http://localhostWebサイト
http://localhost:8080phpMyAdmin(DB管理画面)

停止する

docker compose down

データベースの中身は db_data に保存されているので、停止しても消えません。

データも含めて全部消したい場合

docker compose down -v

-v をつけると保存領域(db_data)も削除されます。次回起動時にデータベースが空の状態に戻ります。


リモートのデータをローカルに持ってくる方法

リモートサーバー(本番)とローカル(Docker)のデータベースは 完全に別物 です。リモートでphpMyAdminにデータを入れても、ローカルには自動的に反映されません。

リモートのデータをローカルで使いたい場合は、エクスポート(書き出し)→ インポート(読み込み) を行います。

手順

STEP 1: リモートのphpMyAdminでエクスポート

  1. リモートサーバーのphpMyAdminにログイン
  2. コピーしたいテーブル(例:maker)を選択
  3. 上部メニューの「エクスポート」をクリック
  4. 「実行」をクリック → .sql ファイルがダウンロードされる

STEP 2: ローカルのphpMyAdminでインポート

  1. docker compose up でDockerを起動
  2. ブラウザで localhost:8080 にアクセス
  3. 上部メニューの「インポート」をクリック
  4. 「ファイルを選択」でSTEP 1でダウンロードした .sql ファイルを選ぶ
  5. 「実行」をクリック → データが読み込まれる
リモートのphpMyAdmin
  → エクスポート → .sql ファイルを保存
                        ↓
ローカルのphpMyAdmin (localhost:8080)
  → インポート → .sql ファイルを読み込む

db_file_key.php のホスト名について

PHPからデータベースに接続する際、本番環境とDocker環境では 接続先のホスト名が異なります

// 本番(リモートサーバー)の場合
$db_host = 'localhost';

// Docker(ローカル開発)の場合
$db_host = 'db';

Docker環境では、データベースの接続先は localhost ではなく db です。これはdocker-compose.ymlで定義したサービス名がそのままホスト名になるためです。

環境を切り替える時は、db_file_key.php$db_host を変更する必要があります。


まとめ

ファイル役割一言で言うと
docker-compose.yml全体の指示書「この4つのサーバーを立ててね」
docker/DockerfileNginxの設計図「Webサーバーはこう作ってね」
docker/php/DockerfilePHPの設計図「PHPにDB接続機能を追加してね」
docker/nginx.confNginxの設定「PHPファイルはPHPサーバーに転送してね」

Dockerを使えば、本番環境とほぼ同じ環境を手元で再現でき、コードの修正 → 即確認という快適な開発サイクルが実現できます。