Docker ComposeでNginx+PHP+MySQL+Redis環境を構築
2021年現在最新のNginx+PHP+MySQL+Redis環境を構築しました
各サービス項目の説明まで
##Docker構成
コンテナ | ミドルウェア |
---|---|
Web | Nginx |
PHP | PHP8 |
DB | MySQL |
Redis | Redis |
ディレクトリ構成
docker_lamp/
|-- mysql
| |-- dump
| | `-- setup.sql
| |-- logs
| |-- mount
| `-- settings
| `-- my.cnf
|-- php
| |-- logs
| |-- settings
| | |-- php.dev.ini
| | |-- php.prod.ini
| | |-- www.dev.conf
| | `-- www.prod.conf
| `-- Dockerfile
|-- project
| `-- html
| `-- public
| `-- index.php
|-- redis
| `-- mount
|-- web
| |-- logs
| `-- settings
| |-- default.conf
| `-- nginx.conf
`-- docker-compose.yml
docker-compose.yaml
PHPはDockerfileを使って自分でイメージを作成
他は公式イメージを利用
一旦全体
version: '3'
services:
web:
image: nginx:alpine
volumes:
- "./web/settings/default.conf:/etc/nginx/conf.d/default.conf"
- "./web/settings/nginx.conf:/etc/nginx/nginx.conf"
- "./project/html:/var/www/html"
- "./web/logs:/var/log/nginx"
ports:
- "8080:80"
restart: always
depends_on:
- php
- mysql
- redis
php:
build: ./php
volumes:
- "./project/html:/var/www/html"
restart: always
mysql:
image: mysql:8.0
ports:
- "13306:3306"
environment:
MYSQL_ROOT_PASSWORD: p@ssw0rd
MYSQL_DATABASE: test
MYSQL_USER: dev
MYSQL_PASSWORD: dev
TZ: Asia/Tokyo
volumes:
- "./mysql/mount:/var/lib/mysql"
- "./mysql/settings/my.cnf:/etc/mysql/conf.d/my.cnf"
- "./mysql/dump/setup.sql:/docker-entrypoint-initdb.d/dump.sql"
- "./mysql/logs:/var/log/mysql"
restart: always
redis:
image: redis:alpine
ports:
- "16379:6379"
volumes:
- "./redis/mount:/data"
各項目説明
Nginx
- 外部アクセス用に8080ポートを公開
- 設定ファイル、プロジェクト、ログはvolumesで同期
※ 設定ファイルは後半に紹介
web:
image: nginx:alpine
volumes:
- "./web/settings/default.conf:/etc/nginx/conf.d/default.conf"
- "./web/settings/nginx.conf:/etc/nginx/nginx.conf"
- "./project/html:/var/www/html"
- "./web/logs:/var/log/nginx"
ports:
- "8080:80"
restart: always
depends_on:
- php
- mysql
- redis
PHP
プロジェクトはvolumesで同期
php:
build: ./php
volumes:
- "./project/html:/var/www/html"
Dockerfile
- PHP用イメージ
- Redis、MySQLを利用するためdocker-php-ext-installを使いPHP拡張をインストール
- 設定ファイルをCOPYを使い反映
※ 設定ファイルは後半に紹介
FROM php:8.0-fpm
RUN apt-get update && apt-get install -y git
RUN git clone https://github.com/phpredis/phpredis.git /usr/src/php/ext/redis
RUN docker-php-ext-install mysqli redis
COPY settings/php.dev.ini /usr/local/etc/php/conf.d/php.ini
COPY settings/www.dev.conf /usr/local/etc/php-fpm.d/www.conf
MySQL
- 外部アクセス用に13306ポートを公開
- environmentの設定を行うとコンテナ作成時に自動でパスワード作成、データベース作成などが自動で実行(今回はルートパスワード設定、データベース、ユーザー、タイムゾーンを設定)
- リソースはvolumesを使いmount以下に同期(Dockerを停止してもデータを残す)
- 設定ファイル、ログはvolumesで同期
- 作成時に実行させたいSQLはvolumesで
/docker-entrypoint-initdb.d/dump.sql
に同期すると自動で実行
mysql:
image: mysql:8.0
ports:
- "13306:3306"
environment:
MYSQL_ROOT_PASSWORD: p@ssw0rd
MYSQL_DATABASE: test
MYSQL_USER: dev
MYSQL_PASSWORD: dev
TZ: Asia/Tokyo
volumes:
- "./mysql/mount:/var/lib/mysql"
- "./mysql/settings/my.cnf:/etc/mysql/conf.d/my.cnf"
- "./mysql/dump/setup.sql:/docker-entrypoint-initdb.d/dump.sql"
- "./mysql/logs:/var/log/mysql"
restart: always
Redis
- 外部アクセス用に16379ポートを公開
- リソースはvolumesを使いmount以下に同期(Dockerを停止してもデータを残す)
redis:
image: redis:alpine
ports:
- "16379:6379"
volumes:
- "./redis/mount:/data"
設定ファイル
デフォルトで動かしてもいいですが、ECS運用も考慮して設定ファイルを用意
Nginx
default.conf
※ 構築時にCodeigniter, FuelPHP環境の構築を考えていたのでこの形になった
ポイントは fastcgi_pass php:9000;
ホストをdocker-composeのサービス名(php)に変更
server {
listen 80 default;
server_name localhost;
charset utf-8;
root /var/www/html/public;
index index.php index.html index.htm;
location / {
index index.php index.html index.htm;
try_files $uri $uri/ /index.php$is_args$args;
}
location /admin {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
index index.php index.html index.htm;
try_files $uri $uri/ /index.php$is_args$args;
}
location /reploxy {
internal;
resolver 8.8.8.8;
set $reproxy $upstream_http_x_reproxy_url;
proxy_pass $reproxy;
proxy_set_header Authorization "";
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param FUEL_ENV "development";
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
include fastcgi_params;
}
}
nginx.conf
ログの場所など指定
user nginx nginx;
worker_processes 2;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
sendfile off;
tcp_nopush on;
tcp_nodelay off;
keepalive_timeout 30;
send_timeout 60;
gzip on;
gzip_http_version 1.0;
gzip_comp_level 6;
gzip_proxied any;
gzip_min_length 10000;
gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
gzip_disable "MSIE [1-6] \.";
include /etc/nginx/conf.d/*.conf;
}
PHP
php.ini、www.conf設定ファイルは以下サイトを参考にさせていただきました
MySQL
my.cnf
文字コード、ログの場所など指定
[mysqld]
# 文字コード/照合順序の設定
character-set-server = utf8mb4
collation-server = utf8mb4_bin
# タイムゾーンの設定
default-time-zone = SYSTEM
log_timestamps = SYSTEM
# デフォルト認証プラグインの設定
default-authentication-plugin = mysql_native_password
# エラーログの設定
log-error = /var/log/mysql/mysql-error.log
# スロークエリログの設定
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 5.0
log_queries_not_using_indexes = 0
# 実行ログの設定
general_log = 1
general_log_file = /var/log/mysql/mysql-query.log
[mysql]
default-character-set = utf8mb4
[client]
default-character-set = utf8mb4
実行ファイル
PHP
index.php
サンプルでMySQLとRedisを使う
ポイントは接続ホストにDockerのサービス名を使うmysql
redis
<?php
// MySQLテスト
echo "MySQLテスト<br />";
$mysqli = mysqli_connect("mysql", "dev", "dev", "test");
$query = "SELECT * FROM `user`";
$result = $mysqli->query($query);
$rows = array();
while ($row = $result->fetch_assoc()) {
$rows[] = $row;
}
var_dump($rows);
echo "<hr />";
// Redisテスト
echo "Redisテスト<br />";
$redis = new Redis();
$redis->connect("redis", 6379);
$redis->set('key', 'value');
echo $redis->get('key');
MySQL
setup.sql
サンプル用のSQL "./mysql/dump/setup.sql:/docker-entrypoint-initdb.d/dump.sql"
の設定でコンテナ作成時にクエリ実行
use test;
DROP TABLE IF EXISTS `test`;
CREATE TABLE `user` (
`name` VARCHAR(255) NOT NULL COMMENT 'Name',
`age` INT(10) unsigned NOT NULL COMMENT 'Age',
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='テスト用';
INSERT INTO `user` VALUES ("TAKASHI", 34, "0000-01-01", "9999-12-31");
docker-compose 実行
ビルドして実行
$ docker-compose up --build
確認
http://127.0.0.1:8080/
にアクセス、表示を確認
次回はこの環境下にComposer、Xdebug、PHPフレームワーク(Codeigniter予定)、UnitTest等を使えるようしていきます。
いいね!と思ったら フォロー、LGTM お願いします
【PR】プログラミング新聞リリースしました! → https://pronichi.com
【PR】週末ハッカソンというイベントやってます! → https://weekend-hackathon.toyscreation.jp/about/