DockerでLaravelの開発環境を構築

今回はLaravelの開発環境を作ってみました。
使うのはdocker-composeです。
Laravel側で「Laravel Sail」というDockerベースの開発環境が付属しているみたいなのですが、あえて独自で構築しました。
作成する構成としては以下です。
合計7つのコンテナをつなぎ合わせて使用します。
- webサーバー
- PHPサーバー
- DBサーバー
- DBサーバー(テスト用)
- seleniumサーバー(DuskでのE2Eテストで使用)
- phpMyAdmin用サーバー
- phpMyAdmin用サーバー(テスト用)
今回の構成を構築するにあたっての前提条件は以下です。
- AppleチップのMacを用意(ここではM1のMacBookPro使用)
- docker desktopをインストール済み
1. docker-compose実行
用意ができたら、プロジェクトルートに以下を用意します。
/
|-- docker-compose.yml
|-- /app-name/
|-- /dev/
|-- /docker/
|-- /db/
|-- conf.d
|-- my.cnf
|-- mysql_data
|-- mysql_init
|-- phpmyadmin
|-- sessions
|-- test_conf.d
|-- test_mysql_data
|-- test_mysql_int
|-- /nginx/
|-- default.conf
|-- php
|-- Dockerfile
|-- php.ini
中身はこんな感じ。
version: '3'
services:
web:
container_name: web
image: nginx
platform: 'linux/arm64'
volumes:
- ./app-name/:/var/www/html
- ./dev/docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
ports:
- 11061:80
working_dir: /var/www/html
depends_on:
- php
- db
- dbtest
environment:
- SERVER_NAME=localhost
networks:
- local
php:
container_name: php
build: ./dev/docker/php
volumes:
- ./app-name/:/var/www/html
networks:
- local
db:
container_name: db
image: mariadb:11.3
platform: 'linux/arm64'
volumes:
# ディレクトリ共有
- ./:/usr/local/src
# 初期データを投入するSQLが格納されているdir
- ./dev/docker/db/mysql_init:/docker-entrypoint-initdb.d
# 永続化するときにマウントするdir
- ./dev/docker/db/mysql_data:/var/lib/mysql
# 設定ファイル
- ./dev/docker/db/conf.d:/etc/mysql/conf.d
ports:
- 11062:3306
environment:
MYSQL_DATABASE: primary
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
MYSQL_ROOT_PASSWORD: password
MYSQL_USER: root
networks:
- local
dbtest:
container_name: dbtest
image: mariadb:11.3
platform: 'linux/arm64'
volumes:
# ディレクトリ共有
- ./:/usr/local/src
# 初期データを投入するSQLが格納されているdir
- ./dev/docker/db/testt_mysql_init:/docker-entrypoint-initdb.d
# 永続化するときにマウントするdir
- ./dev/docker/db/test_mysql_data:/var/lib/mysql
# 設定ファイル
- ./dev/docker/db/test_conf.d:/etc/mysql/conf.d
ports:
- 11063:3306
environment:
MYSQL_DATABASE: test_primary
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
MYSQL_ROOT_PASSWORD: password
MYSQL_USER: root
networks:
- local
selenium:
container_name: selenium
image: seleniarm/standalone-chromium
platform: 'linux/arm64'
shm_size: '2gb'
ports:
- 11064:4444
- 11065:5900
depends_on:
- web
links:
- web
networks:
- local
privileged: true
phpmyadmin:
container_name: phpmyadmin
image: arm64v8/phpmyadmin
platform: 'linux/arm64'
environment:
- PMA_ARBITRARY=1
- PMA_HOST=db
- PMA_USER=root
- PMA_PASSWORD=password
links:
- db
ports:
- 11066:80
volumes:
- ./dev/docker/db/phpmyadmin/sessions:/sessions
networks:
- local
phpmyadmintest:
container_name: phpmyadmintest
image: arm64v8/phpmyadmin
platform: 'linux/arm64'
environment:
- PMA_ARBITRARY=1
- PMA_HOST=dbtest
- PMA_USER=root
- PMA_PASSWORD=password
links:
- dbtest
ports:
- 11067:80
volumes:
- ./dev/docker/db/phpmyadmin/sessions:/sessions
networks:
- local
networks:
local:
# mysqlサーバーの設定
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_bin
init-connect=SET NAMES utf8mb4
# クライアントツールの設定
[client]
default-character-set=utf8mb4
[mysqldump]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
server {
listen 80;
index index.php index.html;
root /var/www/html/public;
client_max_body_size 100M;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.css\.gz$ {
add_header Content-Encoding gzip;
gzip off;
types {
text/css gz;
}
}
location ~ \.js\.gz$ {
add_header Content-Encoding gzip;
gzip off;
types {
application/x-javascript gz;
}
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
FROM php:8.3-fpm
COPY php.ini /usr/local/etc/php/
RUN apt-get update \
&& apt-get install -y libzip-dev libxrender-dev libfontconfig1 libfontconfig1-dev fontconfig libjpeg62-turbo-dev libxext6 xfonts-75dpi xfonts-base libjpeg62-turbo-dev libfreetype6-dev zlib1g-dev libpng-dev libssl-dev fonts-ipafont mariadb-client vim \
&& docker-php-ext-install zip pdo_mysql
# 画像関係
RUN docker-php-ext-configure gd --with-freetype --with-jpeg
RUN docker-php-ext-install -j$(nproc) gd
#Composer install
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
# PDF関係
ADD https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.bookworm_arm64.deb /usr/local/src/
RUN dpkg -i /usr/local/src/wkhtmltox_0.12.6.1-3.bookworm_arm64.deb
ENV COMPOSER_ALLOW_SUPERUSER 1
ENV COMPOSER_HOME /composer
ENV PATH $PATH:/composer/vendor/bin
WORKDIR /var/www/html
[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
internal_encoding = "UTF-8"
mbstring.language = "Japanese"
準備できたらdockerを構築しましょう。
docker-compose up -d
一定時間を経て構築が完了します。
2. Laravelインストール
さてdocker-composeの準備が完了したら、次はlaravelをインストールしていきます。
この時に、dockerのPHPコンテナを通して実行します。
というのも、LaravelインストールはPHPで実行するのですが、PHPはPHPコンテナにしか入っていないからです。
コマンドはこんな感じ。場合によっては古いものが入る可能性もあるので、11を明示的に指定します。
docker-compose exec -T php sh -c "composer create-project laravel/laravel=11.* ./"
ちなみにlaravelのアプリファイルはすべて「app-name」に入れることにします。
そのため、docker-compose.ymlの要所要所で「app-name」と入っています。この名前は自由です。
また、もしインストールが失敗して、原因が「not empty」だった場合、「app-name」が空じゃないからかもしれません。ファイルが何もないのにそのエラーがでる場合、不可視ファイルの「.DS_Store」が邪魔している可能性があります。ターミナルから確認して削除しましょう。
composerのインストールが終わったら、ブラウザでアクセスしてみましょう。
http://localhost:11061/

こんな感じの画面がでてきたら、無事インストール完了です。
ちなみにこれはLaravel11のデフォルト画面みたいですね。
3. DB調整
Laravel11のDBはsqliteがデフォルトになっています。mariadbに切り替える場合は「.env」のDB部分を以下のように変更します。
#DB_CONNECTION=sqlite
#DB_HOST=127.0.0.1
#DB_PORT=3306
#DB_DATABASE=laravel
#DB_USERNAME=root
#DB_PASSWORD=
DB_CONNECTION=mariadb
DB_HOST=db
DB_PORT=3306
DB_DATABASE=primary
DB_USERNAME=root
DB_PASSWORD=password
DB_CHARSE=utf8mb4
DB_COLLATION=utf8mb4_bin
セッションドライバがエラーになる場合は、とりあえずfileに切り替えればOK。
SESSION_DRIVER=database
↓
SESSION_DRIVER=file
DBを調整する場合は「phpMyAdmin」から行います。ブラウザで「http://localhost:11066」とやればアクセスできます。

まずはこれで開発環境が動くところまできました。
開発をスタートするまでが長いですね。
今回は以上です!