インフラ知識皆無なので Docker は雰囲気で使っています。
構成
/ |- docker-compose.yml |- /api |- /frontend | |- Dockerfile |- /mysql | |- /data | |- /init | | |- 1_ddl.sql | |- Dockerfile | |- my.cnf |- /nginx | |- nginx.conf |- /php |- Dockerfile |- php.ini
docker-compose.yml
version: '3' services: nginx: image: nginx:latest ports: - 3000:3000 volumes: - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf - ./api:/var/www/html depends_on: - api api: build: context: ./php dockerfile: Dockerfile volumes: - ./api:/var/www/html depends_on: - db db: build: context: ./mysql dockerfile: Dockerfile command: mysqld --character-set-server=utf8 --collation-server=utf8_general_ci ports: - 13306:3306 volumes: - ./mysql/data:/var/lib/mysql - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf - ./mysql/init:/docker-entrypoint-initdb.d environment: MYSQL_ROOT_PASSWORD: root phpmyadmin: image: phpmyadmin/phpmyadmin:latest ports: - 8888:80 depends_on: - db frontend: build: context: ./frontend dockerfile: Dockerfile volumes: - ./frontend:/app - ./frontend/yarn.lock:/app/yarn.lock - ./frontend/node_modules:/app/node_modules ports: - 8000:3000 depends_on: - api tty: true working_dir: "/app" command: bash -c "yarn start"
nginx
services: nginx: image: nginx:latest ports: - 3000:3000 volumes: # 設定ファイルを nginx の /etc/nginx/conf.d/default.conf にマウント - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf # ./api を /var/www/html にマウント - ./api:/var/www/html depends_on: - api
nginx は PHP を API として動かすので Host Port : Contaner Port
を 3000:3000
に設定。コンテナ内から port 3000 でアクセスできる
./nginx/nginx.conf
server { listen 3000; server_name localhost; 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 api:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
listen
するポートを docker-compose.yml
のポートと合わせる
PHP (api)
services: api: build: context: ./php dockerfile: Dockerfile volumes: - ./api:/var/www/html depends_on: - db
./php
ディレクトリにある Dockerfile
を元に php をbuildする
./php/Dockerfile
FROM php:7.4-fpm # PDO を使えるようにする設定 RUN apt-get update RUN apt-get install -y vim RUN docker-php-ext-install pdo_mysql # php.ini をコンテナにコピー COPY php.ini /usr/local/etc/php/
./php/php.ini
date.timezone = "Asia/Tokyo"
timezone だけ設定
MySQL
services: db: build: context: ./mysql dockerfile: Dockerfile # 作成する database のデフォルトの文字エンコードを指定 command: mysqld --character-set-server=utf8 --collation-server=utf8_general_ci ports: - 13306:3306 volumes: # 実際のデータを ./mysql/data に入れる - ./mysql/data:/var/lib/mysql # 設定ファイルの指定 - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf # 初期データを作成するための設定 - ./mysql/init:/docker-entrypoint-initdb.d environment: # mysql root ユーザーのパスワード MYSQL_ROOT_PASSWORD: root # phpmyadmin phpmyadmin: image: phpmyadmin/phpmyadmin:latest ports: - 8888:80 depends_on: - db
./mysql/Dockerfile
FROM mysql:5.7 # init ディレクトリ内のファイルを初期化時に実行させる COPY init/* /docker-entrypoint-initdb.d/ CMD ["mysqld"]
docker-compose.yml
の volumes
にある - ./mysql/init:/docker-entrypoint-initdb.d
との違いが判ってないい
./mysql/my.cnf
エンコードの指定をしておく
[mysqld] character-set-server=utf8 collation-server=utf8_general_ci [client] default-character-set=utf8
docker-compose.yml
の command: mysqld --character-set-server=utf8 --collation-server=utf8_general_ci
と設定が被ってる気がするけど、片方だけでよいのか判ってない
初期データを作成する
docker の MySQL image では /docker-entrypoint-initdb.d
というディレクトリ内にあるスクリプトを昇順で実行する仕組みがあるようなので、テーブルの作成やデータの流し込みするファイルを置いておくことで DB の初期化ができる
./mysql/init
を /docker-entrypoint-initdb.d
にマウントしているので、./mysql/init
内にスクリプトファイルを作成する
e.g. ./mysql/init/1_ddl.sql
database / table が無ければ作成する
CREATE DATABASE IF NOT EXISTS samle_db; CREATE TABLE IF NOT EXISTS samle_db.table(...);
MySQL の設定が反映されない場合
./mysql/data
内にファイルが残っている状態だと image を再ビルドしても反映されない場合があるので、MySQL の設定を変更する際は ./mysql/data
を削除してから build するのがよい。
Frontend
services: frontend: build: context: ./frontend dockerfile: Dockerfile volumes: - ./frontend:/app - ./frontend/yarn.lock:/app/yarn.lock - ./frontend/node_modules:/app/node_modules ports: # api と通信するので Contaner Port を 3000 に指定 - 8000:3000 depends_on: - api tty: true working_dir: "/app" command: bash -c "yarn start"
create-react-app
で作成する場合は、作業ディレクトリ内で次のコマンドを作成
$ npx create-react-app frontend
./frontend
ディレクトリに react アプリが作成されるので、Dockerfile を作成する
$ touch frontend/Dockerfile
Dockerfile
FROM node:12.18.0 WORKDIR /app
build する
$ docker-compose up -d
問題がなければ localhost:8000
で react が動作しており、localhost:3000
で PHP が動作している状態になっている筈です。
所感
参考サイトを見ながら見様見真似で docker-compose や Docker ファイルを作成しましたが、なんとか動いているSPA開発環境を作成することができました。
この設定だとフロントのアプリも docker 内で動いているのですが Mac だと IO が遅くてビルドが遅いので、実は docker 内に作成せずに yarn run start
とかで動作させて axios で 3000 ポートを指定してリクエスト投げれば問題ないのでは?と思い始めているので、フロントを docker から下ろす方法を模索してみたいと思います。
設定については理解が浅いので、少しつづキャッチアップしていきたいです。
[参考]
- DockerによるPHP開発環境構築(PHP + MySQL + Nginx) - Qiita
- PHP PDO
- MySQL
- MySQL 初期データの反映
- MySQL の設定が反映されない場合
プログラマのためのDocker教科書 第2版 インフラの基礎知識&コードによる環境構築の自動化
- 作者:WINGSプロジェクト阿佐 志保
- 発売日: 2018/04/11
- メディア: Kindle版