はじめに
最近LaravelのDocker環境を考える機会がありました。
その時の知見を活かして、昔考えたDocker PHP環境をアップグレードしたいと思います。
今回の構成の特徴はhealthcheck
です。 depends_on
で実行順序を保証するだけではなく、対象のコンテナの準備が完了(healthcheckに合格)してから依存するコンテナが構築を開始するようにしています。
適宜コメントを入れているので、参考にしてください。
私は学生エンジニアですあと2ヶ月くらい...。
至らない点もあるかもしれません。
その点ご了承ください。
前提条件
Docker, Docker Composeの知識
ファイル構成
docker/
db/
conf.d/
- my.cnf
init/
- init.sql
.env
php/
- .env
- Dockerfile
- php.ini
nginx/
- default.conf
app/
src/
- index.php
vendor/
- composer.json
- composer.lock
data/
.dockerignore
.docker-ignore
docker-compose.yml
各種ファイルの詳細
docker/db/conf.d/my.cnf
[mysql]
default-character-set=utf8mb4
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_bin
[client]
default-character-set=utf8mb4
docker/db/init/init.sql
# 実行したいsqlを記述
# volumeのマウント先の*.sqlはentrypointにimportされて全て実行される仕組み
docker/db/.env
MYSQL_ROOT_PASSWORD=root
MYSQL_DATABASE=test
MYSQL_USER=test
MYSQL_PASSWORD=test
docker/nginx/default.conf
server {
listen 80;
listen [::]:80;
server_name localhost;
# DocumentRoot (default: "/usr/share/nginx/html")
root /usr/src/myapp/src; # rootのページがある場所に指定する
# "/"の時に返却するファイルを指定
index index.html index.htm index.php;
# 特定のURIやパターンに対するサーバーの動作を指定する
location / {
# 左から順に評価
# 存在しなければ最後の指定に従ってindex.phpを返す
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
# php-fpmのservice名:9000
fastcgi_pass php:9000; # (Dockerのservice名を使用していることに注意) (php-pfmはwebサーバを9000で受け付けている)
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
include fastcgi_params;
}
# status pageの設定
location /status {
access_log off;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass php:9000; # (Dockerのservice名を使用していることに注意) (php-pfmはwebサーバを9000で受け付けている)
fastcgi_index status.html;
}
}
docker/php/Dockerfile
FROM php:8.3.2-fpm-bullseye
WORKDIR /usr/src/myapp
# rootでのcomposer installを許可する環境変数
ENV COMPOSER_ALLOW_SUPERUSER=1
COPY ./app/composer.json ./app/composer.lock /usr/src/myapp/
# composer use git zip
# apt may change the interface. apt-get would be better now.
# docker-phpext-install pdo_mysql provide driver of mysql
RUN apt-get update && apt-get install -y git zip zlib1g-dev lsof \
&& docker-php-ext-install pdo_mysql
# enable status code page
RUN echo pm.status_path = /status >> /usr/local/etc/php-fpm.d/www.conf
# Composer Install
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# package install
RUN composer install
COPY ./app /usr/src/myapp/
docker/php/.env
# 指定したい環境変数(外部にされしたくない)があればここで指定する
docker/php/php.ini
[Date]
date.timezone = "Asia/Tokyo"
[opcache]
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable_cli=1
docker-compose.yml
version: "3.8"
services:
php: # phpコンテナはnginxが実行できないphpの処理をするために存在する # webサーバーからのリクエストは9000で受け付ける
build:
context: .
dockerfile: ./docker/php/Dockerfile
env_file: ./docker/php/.env
tty: true
healthcheck:
test: ["CMD", "lsof", "-i:9000"]
start_period: 5s
timeout: 20s
retries: 10
depends_on:
db: # dbコンテナの状態がhealthyになるまで待つ (dbコンテナの準備が完全に終了するまで)
condition: service_healthy
volumes:
- ./app/:/usr/src/myapp
- ./docker/php/php.ini:/usr/local/etc/php/php.ini
environment:
- TZ=Asia/Tokyo
nginx:
image: nginx:latest
depends_on: # nginxはdbとphpコンテナがhealthyになるまで待つ
db:
condition: service_healthy
php:
condition: service_healthy
ports:
- 8080:80
volumes:
- ./app/:/usr/src/myapp
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf # 設定ファイルをnginxの指定位置にマウント
db:
image: mysql:8.0.31
platform: linux/amd64
env_file: ./docker/db/.env
command: --default-authentication-plugin=mysql_native_password
restart: always
volumes:
- ./data:/var/lib/mysql
- ./docker/db/conf.d/my.cnf:/etc/mysql/conf.d/my.cnf
- ./docker/db/init:/docker-entrypoint-initdb.d # 初回コンテナ起動時に実行したいsql
healthcheck: # コンテナの構築が完了したことをチェック
test:
["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-proot"]
start_period: 5s
timeout: 20s
retries: 10
ports:
- 3306:3306
environment:
TZ: Asia/Tokyo
phpmyadmin:
image: phpmyadmin/phpmyadmin
platform: linux/amd64
environment:
- PMA_ARBITRARY=1
- PMA_HOST=db
depends_on: # phpmyadminはdbが準備できればコンテナの構築を始めて良い
db:
condition: service_healthy
ports:
- 8000:80
.dockerignore
**/vender
data
.gitignore
data
vendor
.DS_Store
.env
おわりに
Dockerの環境づくりは何度かやったことがあるのですがhealthcheckを利用したの初めてでした(存在は知ってた)
今回腰を据えて環境構築をすることになったので、healthcheckは絶対に導入したいと考えていました。Laravelでだけどね
慣れないうちはDockerで環境構築をするに当たり様々な試行錯誤と調査が必要で大変ですが、完成した時の達成感は大きなものがありました。
この記事を作成するにあたり多くの有益な情報源を頼らせていただきました。
ありがとうございます。
参考URLを貼っておきますので確認してください。
参考