Dockerでlaravel9開発環境を構築(PHP8+nginx+Mysql8)
PHPのローカル開発環境構築で、そんなに困ったことは実はない。DBを立ち上げて、必要なPHPのバージョンを用意して、ビルトインサーバーで作業する。macは、その辺がやりやすくてありがたい。個人作業が多かったのも大きな点だ。
ただ、複数人で共通の環境を用意する際には、少し面倒なのでDockerのメモを用意しておく。
準備
とりあえず準備として、laravelのプロジェクトを作成します。バージョンは9、プロジェクト名は「supilog」としています。
$ composer create-project laravel/laravel:^9.0 supilog
今回使用するバージョン
laravel9はPHP8.0以上が必要です。今回は8.1を使用します。
laravel 9
PHP 8.1
MySQL 8.0.32
nginx
Docker用ファイルの作成
構成
laravelプロジェクト内は以下のような構成になっています。今回は、Docker用のファイルを以下のように配置していこうと思います。
dockerディレクトリ内の配置は以下のようになる予定です。
docker
├── mysql
│ └── my.cnf
├── nginx
│ └── conf.d
│ └── default.conf
└── php
├── Dockerfile
└── php.ini
docker-compose.yml
プロジェクト直下に配置します。
version: "3"
services:
mysql:
image: mysql:8.0.32
container_name: supilog_mysql
environment:
MYSQL_DATABASE: supilog
MYSQL_ROOT_PASSWORD: password
MYSQL_USER: supiloguser
MYSQL_PASSWORD: password
TZ: "Asia/Tokyo"
ports:
- 4306:3306
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
volumes:
- ./docker/mysql/data:/var/lib/mysql
- ./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf
php:
build: ./docker/php
container_name: supilog_php
volumes:
- ./:/var/www/html
- ./docker/php/php.ini:/usr/local/etc/php/conf.d/php.ini
depends_on:
- "mysql"
nginx:
image: nginx:latest
container_name: supilog_nginx
volumes:
- ./docker/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
- ./:/var/www/html
restart: always
ports:
- 8000:80
depends_on:
- "php"
container_nameはお好きな名前を
お好きな名前を付けてください。
mysql:
container_name: supilog_mysql
php:
container_name: supilog_php
nginx:
container_name: supilog_nginx
DB設定はローカル環境で実際に使用する設定を
この設定は、実際のユーザー名と使用予定のパスワードを記述しましょう。ローカル環境なので、簡単なパスワードでも問題はないでしょう。
environment:
MYSQL_DATABASE: supilog # データベース名
MYSQL_ROOT_PASSWORD: password # rootユーザーのパスワード→laravelでは使わないので適当に
MYSQL_USER: supiloguser # laravelで使用するユーザー
MYSQL_PASSWORD: password # laravelで使用するユーザーのパスワード
MySQLのポート設定は
左側はローカルPC内でのポート番号、右側はDockerコンテナ内でのポート番号。右側は特にいじらずにデフォルトポートで良いです。
左側は、ローカル環境によっては、3306番ポートを使用済みかもしれないので、ずらしています。当然4306も使用中であれば、他のポートを設定します。
ports:
- 4306:3306
nginxのポート設定は
右側の80番は修正の必要はないです。左側は8000番としていますが、こちらは最終的にすべてを立ち上げた後に、「http://localhost:8000」とアクセスするポート番号になります。使用されていないポートであれば、お好みで大丈夫です。
ports:
- 8000:80
docker/mysql/my.cnf
こちらは本番設定に近づけています。ここでは、あまり深く論じません。
[client]
port=3306
socket=/var/lib/mysql/mysql.sock
default-character-set = utf8
[mysql]
prompt = '[\d] mysql> '
default-character-set = utf8
[mysqld]
datadir=/var/lib/mysql
tmpdir = /tmp
port=3306
socket=/var/lib/mysql/mysql.sock
user=mysql
character-set-server=utf8
default-storage-engine=InnoDB
explicit_defaults_for_timestamp=1
default_password_lifetime=0
#lower-case-table-names=1
init-connect=SET NAMES utf8
collation-server=utf8_general_ci
pid-file=/var/run/mysqld/mysqld.pid
# connection
max_connections=64
table_open_cache=800
table_definition_cache=400
open_files_limit=1120
# timeout
wait_timeout=60
interactive_timeout=60
# buffer
key_buffer_size = 16M
innodb_buffer_pool_size = 256M
read_buffer_size = 256K
read_rnd_buffer_size = 512K
join_buffer_size = 256K
sort_buffer_size = 512K
# InnoDB
innodb_file_per_table
innodb_autoextend_increment = 64
innodb_log_files_in_group = 2
innodb_log_file_size = 64M
innodb_log_buffer_size = 16M
innodb_flush_log_at_trx_commit = 2
innodb_flush_neighbors=1
innodb_thread_concurrency = 4
innodb_commit_concurrency = 4
# log
log-error=/var/log/mysqld.log
general_log = 1
general_log_file = /var/lib/mysql/general.log
slow_query_log = 1
slow_query_log_file = /var/lib/mysql/slow_query.log
long_query_time = 1
# ngram
ngram_token_size = 2
symbolic-links=0
skip-character-set-client-handshake
[mysqldump]
quick
single-transaction
default-character-set=utf8
[client-server]
!includedir /etc/my.cnf.d
docker/nginx/conf.d/default.conf
nginxの設定です。動作目的の簡易的な設定です。
server {
listen 80;
server_name localhost;
root /var/www/html/public;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ [^/]\.php(/|$) {
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
docker/php/php.ini
[PHP]
engine = On
zend.exception_ignore_args = On
expose_php = On
max_execution_time = 30
upload_max_filesize = 2M
post_max_size = 8M
memory_limit = 128M
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors = Off
display_startup_errors = Off
log_errors = On
default_charset = "UTF-8"
[Date]
date.timezone = Asia/Tokyo
[mysqlnd]
mysqlnd.collect_memory_statistics = Off
[Assertion]
zend.assertions = -1
[mbstring]
mbstring.language = Japanese
docker/php/Dockerfile
FROM php:8.1.16-fpm
COPY php.ini /usr/local/etc/php/
RUN apt-get update \
&& apt-get install -y zlib1g-dev mariadb-client vim libzip-dev \
&& docker-php-ext-install zip pdo_mysql
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
RUN php composer-setup.php
RUN php -r "unlink('composer-setup.php');"
RUN mv composer.phar /usr/local/bin/composer
ENV COMPOSER_ALLOW_SUPERUSER 1
ENV COMPOSER_HOME /composer
ENV PATH $PATH:/composer/vendor/bin
コンテナを起動させてみる
プロジェクト直下で以下のコマンドを打ってみます。
$ docker-compose up -d
完了すると以下のような表示がでます。
Creating supilog_mysql ... done
Creating supilog_php ... done
Creating supilog_nginx ... done
起動確認
StateがすべてUpになっていれば無事に成功です。
$ docker-compose ps
---------------
Name Command State Ports
------------------------------------------------------------------------------------------
supilog_mysql docker-entrypoint.sh --cha ... Up 0.0.0.0:4306->3306/tcp, 33060/tcp
supilog_nginx /docker-entrypoint.sh ngin ... Up 0.0.0.0:8000->80/tcp
supilog_php docker-php-entrypoint php-fpm Up 9000/tcp
---------------
この時点でwelcomeページへのアクセスは可能になっているはずです。http://localhost:8000にアクセスしてみてください。(ポート番号を任意に変更した方は、そのポート番号で)
migrationを行う
.envの設定
environment:
MYSQL_DATABASE: supilog # ①データベース名
MYSQL_ROOT_PASSWORD: password # rootユーザーのパスワード → 使わない
MYSQL_USER: supiloguser # ②laravelで使用するユーザー
MYSQL_PASSWORD: password # ③laravelで使用するユーザーのパスワード
MySQLコンテナの設定時に、下記のように設定を入れたので、laravel側の設定ファイルを更新していきます。プロジェクト直下にある.envファイルを修正します。
DB_HOSTには、「127.0.0.1」ではなく、mysqlコンテナにつけた名前を記載してあげます。
DB_CONNECTION=mysql
DB_HOST=supilog_mysql
DB_PORT=3306
DB_DATABASE=supilog
DB_USERNAME=supiloguser
DB_PASSWORD=password
「あれ?さっき4306番ポートを設定しなかった?」と思ったアナタするどいですね。4306番はコンテナの外側の世界に向けたポートなので、外部ツールからmysqlコンテナのDBにアクセスしたい時には、4306を使います。
一方で、コンテナ内部でのやり取りは3306が使われるので、これでOK。
phpコンテナにアクセスして、migrationしてみる
下記コマンドで作成したphpコンテナに入り込みます。
$ docker-compose exec php bash
プロジェクト内にいると思うので、artisanコマンドを実行します。migrationが無事に動作したら、開発環境構築完了です。
設定が間違っていてmysqlコンテナに接続が出来ない場合には、下記コマンド実行時に「Connection refused」が発生すると思います。
$ php artisan migrate
---------------
WARN Migration table not found.
INFO Preparing database.
Creating migration table ....................................................... 45ms DONE
INFO Running migrations.
2014_10_12_000000_create_users_table ........................................... 49ms DONE
2014_10_12_100000_create_password_resets_table ................................. 81ms DONE
2019_08_19_000000_create_failed_jobs_table ..................................... 54ms DONE
2019_12_14_000001_create_personal_access_tokens_table .......................... 74ms DONE
---------------
まとめ
わざわざ最後まで読んでくださりありがとうございます。
個人的な手順としてまとめたものですが、どなたかの参考になれば幸いです。
一度設定しておけば、どの環境でも共通の状態を作れるというのは強みですね。
それでは!