LoginSignup
3
0

More than 1 year has passed since last update.

dockerでnginx+PHP+MySQL(+PHPMyAdmin+MailHog)の環境を作る

Last updated at Posted at 2021-08-26

こちらを主軸に色々な先輩方のサイトを参考にnginx+PHP+MySQLの環境を作ってみた。
参考にしたサイトはこの記事の一番下にまとめて書きます。
また、基本的にMacで作っていきますが、Windowsでもほぼ同じ手順で作れます。

取り敢えずDocker Desktop for Mac (for Windows)をインストール

上記のリンクからアカウント登録してパソコンに合うデスクトップアプリをインストール。


参考リンク

なんかdocker-composeが使えなかったので個別にインストール

上でインストールしたアプリにdocker-composeもついているはずなのに何故かdocker-composeコマンドが使えなかったので、ターミナルを開いて下記のコマンドを実行。

sudo curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

結局原因がわからなかったが、取り敢えずdocker-composeコマンドが使えるようになったのでよしとする。(よくない)
下記のコマンドを打ってバージョンがでたらOK。

$ docker -v
Docker version 20.10.8, build 3967b7d
$ docker-compose -v
docker-compose version 1.27.4, build 40524192

ここから本格的に作っていきます

ディレクトリを作っていく

mkdirtouchを使って、下記の構造のディレクトリを作っていく。*がついてるフォルダの名前はなんでもいい。

docker-nginx *
├── docker *
│   ├── php *
│   │   └── Dockerfile
│   ├── nginx *  
│   │   ├── Dockerfile
│   │   └── default.conf
│   └── mysql *
│       ├── Dockerfile
│       └── my.cnf
├── src *
├── .gitignore
├── .env
└── docker-compose.yml

docker-compose.ymlを書く

viコマンドまたはXcodeやVSCodeで上で作った空ファイルを開いてもいい。


viコマンドの使い方
$ vi [ファイル名]

下記の状態になったらiを押す。

~ 
~ 
~ 
~ 
~ 
~ 
~ 
"[ファイル名]" 0L, 0B

下記の状態になったら書き込む。

~ 
~ 
~ 
~ 
~ 
~ 
~ 
-- INSERT --

書き終わったらescを押し、:wqと打ってenterを押す。


完成形
version: '3.8'
# mysqlのテーブルやらなんやらを保存するやつ
volumes:
  mysql-volume: 
# 各コンテナの設定
services:
  # phpサーバー
  php:
    build: # Dockerfileで設定する
      context: .
      dockerfile: ./docker/php/Dockerfile
    volumes: # ./src/に入れたファイルが/usr/share/nginx/htmlに同期される。
      - ./src:/usr/share/nginx/html
  # nginxサーバー
  web:
    build: # Dockerfileで設定する
      context: .
      dockerfile: ./docker/nginx/Dockerfile
    ports: # ポートの設定(後で.envでする)
      - ${WEB_PORT}:80
    depends_on: # 先にphpサーバーを立ち上げる
      - php
    volumes: # ./src/に入れたファイルが/usr/share/nginx/htmlに同期される。
      - ./src/:/usr/share/nginx/html
  # データベースサーバー
  db:
    build: # Dockerfileで設定する
      context: .
      dockerfile: ./docker/mysql/Dockerfile
    ports: # ポートの設定(後で.envでする)
      - ${DB_PORT}:3306
    environment: # ユーザとかパスワードとかの設定(後で.envでする)
      MYSQL_DATABASE: ${DB_NAME}
      MYSQL_USER: ${DB_USER}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      TZ: 'Asia/Tokyo'
    volumes: # mysqlのテーブルやらなんやらを保存する
      - mysql-volume:/var/lib/mysql
  # PHPMyAdminサーバー
  phpmyadmin: # デフォルトのままで不都合ないのでDockerHubにあるイメージをそのまま使う
    image: phpmyadmin/phpmyadmin:latest
    environment:
      PMA_HOST: 'db' # ホストはデータベースサーバーのサービス名(26行目)
      PMA_USER: 'root' # デフォルトでログインしているユーザー(今回はルートユーザー)
      PMA_PASSWORD: ${DB_ROOT_PASSWORD} # 上記ユーザーのパスワード(今回はルートユーザーのパスワード)
    ports: # ポートの設定(後で.envでする)
    - ${PMA_PORT}:80
  # メール確認用サーバー
  # とりあえずメールがきちんと送信できたか見たいだけなので、簡単に導入できるMailHogを使っている。
  # 外部にメール送るにはIPアドレスの許可やらその他いろいろ面倒くさいので今回はやらない。
  mailhog:
    image: mailhog/mailhog
    ports: # ポートの設定(後で.envでする)
      - ${MAIL_PORT}:8025
      - "1025:1025"

.envと.gitignoreを書く

.envにポート番号やデータベースの設定を書く。(.がつく隠しファイルは基本的にviなどのコマンドを使う。VSCodeとかでもいい。)

.env
WEB_PORT=8080
DB_PORT=3690
PMA_PORT=8081
MAIL_PORT=8025

DB_NAME=db_mydb
DB_USER=db_user
DB_PASSWORD=password
DB_ROOT_PASSWORD=rootpass

上記はあくまで一例。ポートはwebは80、DBは3306がよく使われるが、他のアプリ等で使っていることも考慮して適当にズラしている。
データベース関連も取り敢えず簡単な名前を使っているので、特にパスワードはもっと複雑なのにしたほうがいい。

次は.gitignoreを書く

.envファイルをうっかりgithubとかに上げてしまうとやばいので、バージョン管理から外す。

.gitignore
.env

Dockerfileを書いていく

まずはPHPサーバー用のDockerfile

./docker/php/Dockerfile
FROM php:7.2-fpm
# タイムゾーン(東京)
ENV TZ Asia/Tokyo
# 色々パッケージとか追加(パッケージの操作管理などに使うツール類?とmysqliパッケージ)
RUN apt-get update \
&& apt-get install -y \
git \
zip \
unzip \
vim \
libpq-dev \
&& docker-php-ext-install pdo_mysql pdo_pgsql mysqli
# メール受信用のやつのSMTPサーバーとかポートなどいろいろ設定
RUN curl -sSLO https://github.com/mailhog/mhsendmail/releases/download/v0.2.0/mhsendmail_linux_amd64 \
&& chmod +x mhsendmail_linux_amd64 \
&& mv mhsendmail_linux_amd64 /usr/local/bin/mhsendmail \
&& echo 'sendmail_path = "/usr/local/bin/mhsendmail --smtp-addr=mailhog:1025"' > /usr/local/etc/php/conf.d/sendmail.ini

次はnginx用

./docker/nginx/Dockerfile
FROM nginx:1.18-alpine
# タイムゾーン(東京)
ENV TZ Asia/Tokyo

# nginxのconfigファイル(default.conf)をコピー
COPY ./docker/nginx/*.conf /etc/nginx/conf.d/
# このコンテナに入った時のカレントディレクトリ
WORKDIR /usr/share/nginx/html

最後にデータベース用

./docker/mysql/Dockerfile
FROM mysql:8.0
# 言語設定を変えるためにパッケージをインストール
RUN apt-get update
RUN apt-get -y install locales-all
# MySQLを日本語に対応させる
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8
# タイムゾーン(東京)
ENV TZ Asia/Tokyo
# MySQLのconfigファイル(my.cnf)をコピー
COPY ./docker/mysql/my.cnf /etc/my.cnf

nginxとMySQLの設定ファイルを書く

まずはnginxのdefault.conf

これに関してはちゃんと説明できないので詳しくは各自で調べてみて下さい

./docker/nginx/default.conf
server {
    index index.php index.html; # ここでトップページに表示するファイルを指定(先に書いた方が優先度が高い)
    server_name localhost;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /usr/share/nginx/html;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

次はMySQLのmy.cnf

設定できる項目はたくさんあるので適宜調べて書き足して下さい。

./docker/nginx/my.cnf
[mysqld]
user=mysql
character_set_server = utf8mb4
collation_server = utf8mb4_0900_ai_ci
# MySQL8.0の認証方式にPHP側では対応していないので従来の認証方式に変える
default_authentication_plugin=mysql_native_password

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

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

# Slow Query Log
slow_query_log = 1
slow_query_log_file = mysql-slow.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


認証方式についてうまくいかなかった時

上記の6行目default_authentication_plugin=mysql_native_passwordを書いたにも関わらずWarning: mysqli_connect(): The server requested authentication method unknown to the client [caching_sha2_password]が出る時。

ファイルを書いている途中でdocker-composeで起動してみた場合などに、
docker-compose.ymlの3,4行目に書いたmysql-volume:にデータが残っているからmy.cnfを変えただけでは変更できないと思われる。

対処法1:mysql-volume:を一度削除する

コンテナを稼働している場合は一度止めて、docker-nginxディレクトリで下記のコマンドを実行する。

ボリューム一覧表示

docker volume ls

指定のボリューム削除

docker volume rm mysql-volume:

全部消すとき

docker volume ls -qf dangling=true | xargs -r docker volume rm

この方法だと既にこのデータベースに作成してあるテーブルとかが全部消えるので注意。

対処法2:MySQLのコンテナに入ってユーザごとに認証方式を変える

稼働しているMySQLのコンテナに入って下記のコマンドを実行する。

docker-composeで起動しいる状態で
docker-nginxディレクトリでコマンドを実行してMySQLのコンテナに入る。

docker compose exec db bash

下記のコマンドを順番に実行する。

$ mysql -u root -p
[Enter password: 
~~略~~
# 現状の確認
[mysql> SELECT user, host, plugin FROM mysql.user;
+------------------+-----------+-----------------------+
| user             | host      | plugin                |
+------------------+-----------+-----------------------+
| db_mydb          | %         | caching_sha2_password |
| root             | %         | caching_sha2_password |
| mysql.infoschema | localhost | caching_sha2_password |
| mysql.session    | localhost | caching_sha2_password |
| mysql.sys        | localhost | caching_sha2_password |
| root             | localhost | caching_sha2_password |
+------------------+-----------+-----------------------+
6 rows in set (0.01 sec)
# rootユーザの認証方式を変える
mysql> ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root';
Query OK, 0 rows affected (0.01 sec)


コンテナを起動

ここまでで一通り設定は終わったので、下記のindex.phpsrcフォルダに突っ込む。

index.php
<?php echo phpinfo(); ?>

コンテナを起動

docker-nginxディレクトリで下記コマンドを実行してビルドする。

docker compose build 

特に問題が起きなければ下記コマンドで起動

docker compose up -d 

ブラウザを起動してhttp://localhost:8080/と打ち込むと、
PHPのバージョンとかの情報ページが表示される。(スクショの埋め込み方がわからない)


あとはsrcフォルダにcssやらjsやら色々突っ込んでいけば装飾とか色々反映される。

各コンテナに入って作業するとき

コンテナに入って作業するとき(MySQLに初期データ追加したり、サーバーの設定をいじったりとか)は下記のコマンドをdocker-nginxディレクトリで実行。

# PHPのサーバ
$ docker compose exec php bash
# nginxのサーバ
$ docker compose exec web ash
# データベースサーバ
$ docker compose exec db bash

コンテナを停止

下記コマンドで停止(MySQLのデータはmysql-volume:に残る)。

docker compose -f docker-compose.yml down

参考資料

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0