Docker 一年生なので、雰囲気で作っています。
構成
/-- docker-compose.yml |- /web | |- /html … web root |- /mysql | |- Dockerfile | |- my.conf | |- /init | |- 1_dd.sql … DB 初期化 |- /nginx | |- nginx.conf | |- /log | |- access.log | |- error.log |- /php | |- Dockerfile | |- php.ini |- /redis
docker-compose.yml
version: '3' services: nginx: image: nginx:latest ports: - 8080:80 volumes: - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf - ./nginx/log/access.log:/var/log/nginx/access.log - ./nginx/log/error.log:/var/log/nginx/error.log - ./web:/var/www depends_on: - web web: build: context: ./php dockerfile: Dockerfile volumes: - ./web:/var/www depends_on: - db - redis tty: true db: build: context: ./mysql dockerfile: Dockerfile 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: # root ユーザーのパスワードを root に設定 MYSQL_ROOT_PASSWORD: root command: mysqld --character-set-server=utf8 --collation-server=utf8_general_ci phpmyadmin: image: phpmyadmin/phpmyadmin:latest ports: - 8888:80 depends_on: - db redis: image: redis:latest volumes: - ./redis/data:/data ports: - 6379:6379 command: redis-server
PHP composer, PDO, Redis
/php/Dockerfile
FROM php:7.4-fpm RUN apt-get update RUN apt-get install -y vim RUN apt-get install -y zip unzip git RUN git clone https://github.com/phpredis/phpredis.git /usr/src/php/ext/redis RUN docker-php-ext-install pdo_mysql redis COPY php.ini /usr/local/etc/php/ COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
/php/php.ini
date.timezone = "Asia/Tokyo"
nginx.conf
/nginx/conf
server { listen 80; server_name localhost; root /var/www/html; index index.php index.html; underscores_in_headers on; 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 web:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
underscores_in_headers on;
の設定をしておくと Authorization
や _
(アンダースコア)を含むカスタムヘッダーを PHP の $_SERVER
で取得できるようになる。
カスタムヘッダーなどが取得できない時はこの設定を追加してみると良いかも。
cf. PHP - Get Custom Headers when Using Nginx with php-fpm - Stack Overflow
MySQL
/mysql/Dockerfile
FROM mysql:5.7 COPY init/* /docker-entrypoint-initdb.d/ CMD ["mysqld"]
/mysql/my.conf
[mysqld] character-set-server=utf8 collation-server=utf8_general_ci [client] default-character-set=utf8
/mysql/init/
… このディレクトリ内にあるスクリプトが順番に実行される。database, table を初期化時に作成したりデータを入れたりする sql ファイルを置いておく
e.g. _dd.sql
CREATE DATABASE IF NOT EXISTS test; CREATE TABLE IF NOT EXISTS test.users (...); INSERT INTO test.users …;
build・動作確認
$ docker-compose build $ docker-compose up
エラーにならず build と 起動ができればOK
/web/html
内に test.php
を作成して PDO での MySQL への接続と Redis が使えることを確かめます。
<?php // /web/html/test.php // MySQL with PDO $dns = 'mysql:dbname=' . DB_NAME . ';host=db;charset=utf8;'; $options = [ // カラム型に合わない値がINSERTされようとしたときSQLエラーとする PDO::MYSQL_ATTR_INIT_COMMAND => "SET SESSION sql_mode='TRADITIONAL'", // SQLエラー発生時にPDOExceptionをスローさせる PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, ]; try { $pdo = new PDO($dns, DB_USER, DB_PASSWORD, $options); var_dump($pdo); } catch (PDOException $e) { echo $e->getMessage(); } // Redis $redis = new Redis(); // connect の第一引数は docker-compose.yml のイメージ名を指定する $redis->connect('redis', 6379); var_dump($redis->ping()); // => true phpinfo();
localhost:8080/test.php
にアクセスして MySQL / Redis への接続・phpinfo の表示がされていれば OK
フロントは別に create-react-app
とかして proxy
を設定すれば docker 外からアクセス可能なので、APIとして利用することもできます。
おわり。
[参考]
- Dockerfile のベストプラクティス — Docker-docs-ja 1.9.0b ドキュメント
- PHP - Get Custom Headers when Using Nginx with php-fpm - Stack Overflow
- Docker Hub
- Docker Compose で PHP 7.0 の開発環境を構築する - Qiita
- PHPオフィシャル Dockerコンテナに redis exension を追加するメモ - Qiita
- Docker + Laravel6 + Redis エラー: Please remove or rename the Redis facade alias in your "app" configuration file in order to avoid collision with the PHP Redis extension. - Qiita
- PHPのオフィシャルDockerイメージにredis exensionを追加する方法 - Qiita
- GitHub - phpredis/phpredis: A PHP extension for Redis
- phpredis チートシート - Qiita
👆ぶっちゃげただの木だけど手首痛くならななくなったので良い買い物だった