Laravel sailを使った環境のカスタマイズの個人覚書
はじめに
curl -s "https://laravel.build/example-app?with=mysql,mailpit" | bash
で、Laravel sailでアプリの環境が作れる。
https://laravel.com/docs/11.x/installation
に、乗ってる
2026/02/02 時点で実行すると、Laravel Framework 12.49.0 でアプリが構成される。
$ sail artisan --version
Laravel Framework 12.49.0
example-app のところを自分の好きなアプリ名に変更して使う
example-app のフォルダが作成され、その中で環境ができる。
ただ、このままでは使いにくいため。
いくつか、カスタマイズしたため、それを記憶に残すことにした
compose.yaml
変更点その1

変更前)
laravel.test:
build:
context: './vendor/laravel/sail/runtimes/8.5'
dockerfile: Dockerfile
変更後)
services:
app:
build:
#** context: './vendor/laravel/sail/runtimes/8.5'
context: './Docker'
dockerfile: Dockerfile
プロジェクトルートに、
Dockerのフォルダを作成し、
vendor/laravel/sail/runtimes/8.5
の中身の
Dockerfile
php.ini
start-container
supervisord.conf
をコピーする。
変更点その2

変更前)
volumes:
- 'sail-mysql:/var/lib/mysql'
- './vendor/laravel/sail/database/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh'
変更後)
volumes:
#- 'sail-mysql:/var/lib/mysql'
- './DB/volume:/var/lib/mysql'
- './DB/conf.d/mysql.cnf:/etc/mysql/conf.d/mysql.cnf'
- './DB/conf.d/mysqldump.cnf:/etc/mysql/conf.d/mysqldump.cnf'
- './vendor/laravel/sail/database/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh'
名前付きボリューム の sail-mysql を使うのは取り回しが効きにくい
./DB/volumeにバインドマウントしたほうが取り回ししやすい
コンテナ内部の /etc/mysql/conf.d
をそのまま、ホスト側の./DB配下にもってきて
中身の mysql.cnf、mysqldump.cnf をバインドマウントしたほうが設定値の変更がしやすい
変更点その3

phpmyadmin:
image: phpmyadmin/phpmyadmin
depends_on:
- mysql
ports:
- '${PHPMYADMIN_PORT:-8888}:80'
environment:
PMA_USER: '${DB_USERNAME}'
PMA_PASSWORD: '${DB_PASSWORD}'
PMA_HOST: mysql
networks:
- sail
.env ( 代わりに.env.example の変更点で掲載 )
変更点その1

変更前)
APP_LOCALE=en
変更後)
# sailはデフォルトでlaravel.testのコンテナ名で
# sail artisan ...が動くがそれを変更したいとき必要
APP_SERVICE=app
APP_PORT=8081
VITE_PORT=5174
FORWARD_DB_PORT=3307
PHPMYADMIN_PORT=8889
APP_LOCALE=ja
変更点その2

追加) Rancher Desktopの場合
SAIL_XDEBUG_MODE=debug
SAIL_XDEBUG_CONFIG=client_host=host.rancher-desktop.internal
追加) Docker Desktopの場合
SAIL_XDEBUG_MODE=debug
SAIL_XDEBUG_CONFIG="client_host=host.docker.internal"
php.ini
変更点

追加)
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host="host.docker.internal"
xdebug.client_port=9101
xdebug.log=/tmp/xdebug.log
.vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Listen for Xdebug",
"type": "php",
"request": "launch",
// ミラーモードでないWSL2は必要だが
// ミラーモードのWSL2なら不要。
// 他、WSL2以外も不要。
// "hostname": "0.0.0.0",
"port": 9101,
"pathMappings": {
"/var/www/html": "${workspaceFolder}"
}
}
]
}
.vscode/settings.json
{
"LaravelExtraIntellisense.phpCommand": "docker compose exec -T -w /var/www/html app php -r \"{code}\"",
"LaravelExtraIntellisense.basePath": ".",
"LaravelExtraIntellisense.basePathForCode": "/var/www/html",
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"[php]": {
"editor.defaultFormatter": "laravel.vscode-laravel"
},
}
.gitignore への追加
# DB の実データは全部無視
/DB/volume/**
# ただし .gitkeep だけは残す
!/DB/volume/.gitkeep
/_ide_helper_models.php
/_ide_helper.php
/.phpstorm.meta.php
.vscode/launch.json
.vscode/settings.json
最後に、
curl -s "https://laravel.build/example-app?with=mysql,mailpit" | bash
について、/tmp にて、
curl -s "https://laravel.build/example-app?with=mysql,mailpit" > example-app.sh
を実行し、example-app.sh を得た
2026/02/02時点では、下記の出力を得た。
docker info > /dev/null 2>&1
# Ensure that Docker is running...
if [ $? -ne 0 ]; then
echo "Docker is not running."
exit 1
fi
docker run --rm \
--pull=always \
-v "$(pwd)":/opt \
-w /opt \
laravelsail/php84-composer:latest \
bash -c "laravel new example-app --no-interaction && cd example-app && php ./artisan sail:install --with=mysql,mailpit "
cd example-app
# Allow build with no additional services..
if [ "mysql mailpit" == "none" ]; then
./vendor/bin/sail build
else
./vendor/bin/sail pull mysql mailpit
./vendor/bin/sail build
fi
CYAN='\033[0;36m'
LIGHT_CYAN='\033[1;36m'
BOLD='\033[1m'
NC='\033[0m'
echo ""
if command -v doas &>/dev/null; then
SUDO="doas"
elif command -v sudo &>/dev/null; then
SUDO="sudo"
else
echo "Neither sudo nor doas is available. Exiting."
exit 1
fi
if $SUDO -n true 2>/dev/null; then
$SUDO chown -R $USER: .
echo -e "${BOLD}Get started with:${NC} cd example-app && ./vendor/bin/sail up"
else
echo -e "${BOLD}Please provide your password so we can make some final adjustments to your application's permissions.${NC}"
echo ""
$SUDO chown -R $USER: .
echo ""
echo -e "${BOLD}Thank you! We hope you build something incredible. Dive in with:${NC} cd example-app && ./vendor/bin/sail up"
fi
掲載
compose.yaml (変更後)
services:
app:
build:
#** context: './vendor/laravel/sail/runtimes/8.5'
context: './Docker'
dockerfile: Dockerfile
args:
WWWGROUP: '${WWWGROUP}'
image: 'sail-8.5/app'
extra_hosts:
- 'host.docker.internal:host-gateway'
ports:
- '${APP_PORT:-80}:80'
- '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
environment:
WWWUSER: '${WWWUSER}'
LARAVEL_SAIL: 1
XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
IGNITION_LOCAL_SITES_PATH: '${PWD}'
volumes:
- '.:/var/www/html'
networks:
- sail
depends_on:
- mysql
- mailpit
mysql:
image: 'mysql:8.4'
ports:
- '${FORWARD_DB_PORT:-3306}:3306'
environment:
MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
MYSQL_ROOT_HOST: '%'
MYSQL_DATABASE: '${DB_DATABASE}'
MYSQL_USER: '${DB_USERNAME}'
MYSQL_PASSWORD: '${DB_PASSWORD}'
MYSQL_ALLOW_EMPTY_PASSWORD: 1
MYSQL_EXTRA_OPTIONS: '${MYSQL_EXTRA_OPTIONS:-}'
volumes:
#- 'sail-mysql:/var/lib/mysql'
- './DB/volume:/var/lib/mysql'
- './DB/conf.d/mysql.cnf:/etc/mysql/conf.d/mysql.cnf'
- './DB/conf.d/mysqldump.cnf:/etc/mysql/conf.d/mysqldump.cnf'
- './vendor/laravel/sail/database/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh'
networks:
- sail
healthcheck:
test:
- CMD
- mysqladmin
- ping
- '-p${DB_PASSWORD}'
retries: 3
timeout: 5s
phpmyadmin:
image: phpmyadmin/phpmyadmin
depends_on:
- mysql
ports:
- '${PHPMYADMIN_PORT:-8888}:80'
environment:
PMA_USER: '${DB_USERNAME}'
PMA_PASSWORD: '${DB_PASSWORD}'
PMA_HOST: mysql
networks:
- sail
mailpit:
image: 'axllent/mailpit:latest'
ports:
- '${FORWARD_MAILPIT_PORT:-1025}:1025'
- '${FORWARD_MAILPIT_DASHBOARD_PORT:-8025}:8025'
networks:
- sail
networks:
sail:
driver: bridge
volumes:
sail-mysql:
driver: local
compose.yaml (変更前)
services:
laravel.test:
build:
context: './vendor/laravel/sail/runtimes/8.5'
dockerfile: Dockerfile
args:
WWWGROUP: '${WWWGROUP}'
image: 'sail-8.5/app'
extra_hosts:
- 'host.docker.internal:host-gateway'
ports:
- '${APP_PORT:-80}:80'
- '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
environment:
WWWUSER: '${WWWUSER}'
LARAVEL_SAIL: 1
XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
IGNITION_LOCAL_SITES_PATH: '${PWD}'
volumes:
- '.:/var/www/html'
networks:
- sail
depends_on:
- mysql
- mailpit
mysql:
image: 'mysql:8.4'
ports:
- '${FORWARD_DB_PORT:-3306}:3306'
environment:
MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
MYSQL_ROOT_HOST: '%'
MYSQL_DATABASE: '${DB_DATABASE}'
MYSQL_USER: '${DB_USERNAME}'
MYSQL_PASSWORD: '${DB_PASSWORD}'
MYSQL_ALLOW_EMPTY_PASSWORD: 1
MYSQL_EXTRA_OPTIONS: '${MYSQL_EXTRA_OPTIONS:-}'
volumes:
- 'sail-mysql:/var/lib/mysql'
- './vendor/laravel/sail/database/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh'
networks:
- sail
healthcheck:
test:
- CMD
- mysqladmin
- ping
- '-p${DB_PASSWORD}'
retries: 3
timeout: 5s
mailpit:
image: 'axllent/mailpit:latest'
ports:
- '${FORWARD_MAILPIT_PORT:-1025}:1025'
- '${FORWARD_MAILPIT_DASHBOARD_PORT:-8025}:8025'
networks:
- sail
networks:
sail:
driver: bridge
volumes:
sail-mysql:
driver: local
.env.example (変更後)
APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
# sailはデフォルトでlaravel.testのコンテナ名で
# sail artisan ...が動くがそれを変更したいとき必要
APP_SERVICE=app
APP_PORT=8081
VITE_PORT=5174
FORWARD_DB_PORT=3307
PHPMYADMIN_PORT=8889
APP_LOCALE=ja
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_US
APP_MAINTENANCE_DRIVER=file
# APP_MAINTENANCE_STORE=database
# PHP_CLI_SERVER_WORKERS=4
BCRYPT_ROUNDS=12
LOG_CHANNEL=stack
LOG_STACK=single
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=sqlite
# DB_HOST=127.0.0.1
# DB_PORT=3306
# DB_DATABASE=laravel
# DB_USERNAME=root
# DB_PASSWORD=
SESSION_DRIVER=database
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
SESSION_PATH=/
SESSION_DOMAIN=null
BROADCAST_CONNECTION=log
FILESYSTEM_DISK=local
QUEUE_CONNECTION=database
CACHE_STORE=database
# CACHE_PREFIX=
MEMCACHED_HOST=127.0.0.1
REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=log
MAIL_SCHEME=null
MAIL_HOST=127.0.0.1
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false
VITE_APP_NAME="${APP_NAME}"
SAIL_XDEBUG_MODE=debug
SAIL_XDEBUG_CONFIG=client_host=host.rancher-desktop.internal
SAIL_XDEBUG_CONFIG=client_host=host.rancher-desktop.internal
は、Rancher Desktop用である。
Docker Desktopの場合は、
SAIL_XDEBUG_CONFIG="client_host=host.docker.internal"
にする。
.env.example (変更前)
APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
APP_LOCALE=en
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_US
APP_MAINTENANCE_DRIVER=file
# APP_MAINTENANCE_STORE=database
# PHP_CLI_SERVER_WORKERS=4
BCRYPT_ROUNDS=12
LOG_CHANNEL=stack
LOG_STACK=single
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=sqlite
# DB_HOST=127.0.0.1
# DB_PORT=3306
# DB_DATABASE=laravel
# DB_USERNAME=root
# DB_PASSWORD=
SESSION_DRIVER=database
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
SESSION_PATH=/
SESSION_DOMAIN=null
BROADCAST_CONNECTION=log
FILESYSTEM_DISK=local
QUEUE_CONNECTION=database
CACHE_STORE=database
# CACHE_PREFIX=
MEMCACHED_HOST=127.0.0.1
REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=log
MAIL_SCHEME=null
MAIL_HOST=127.0.0.1
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false
VITE_APP_NAME="${APP_NAME}"
Dockerfile (変更なし)
FROM ubuntu:24.04
LABEL maintainer="Taylor Otwell"
ARG WWWGROUP
ARG NODE_VERSION=24
ARG MYSQL_CLIENT="mysql-client"
ARG POSTGRES_VERSION=18
WORKDIR /var/www/html
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=UTC
ENV SUPERVISOR_PHP_COMMAND="/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80"
ENV SUPERVISOR_PHP_USER="sail"
ENV PLAYWRIGHT_BROWSERS_PATH=0
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN echo "Acquire::http::Pipeline-Depth 0;" > /etc/apt/apt.conf.d/99custom && \
echo "Acquire::http::No-Cache true;" >> /etc/apt/apt.conf.d/99custom && \
echo "Acquire::BrokenProxy true;" >> /etc/apt/apt.conf.d/99custom
RUN apt-get update && apt-get upgrade -y \
&& mkdir -p /etc/apt/keyrings \
&& apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python3 dnsutils librsvg2-bin fswatch ffmpeg nano \
&& curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xb8dc7e53946656efbce4c1dd71daeaab4ad4cab6' | gpg --dearmor | tee /etc/apt/keyrings/ppa_ondrej_php.gpg > /dev/null \
&& echo "deb [signed-by=/etc/apt/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \
&& apt-get update \
&& apt-get install -y \
libgd3 \
php8.5-cli \
php8.5-dev \
php8.5-pgsql \
php8.5-sqlite3 \
php8.5-gd \
php8.5-curl \
php8.5-mongodb \
php8.5-imap \
php8.5-mysql \
php8.5-mbstring \
php8.5-xml \
php8.5-zip \
php8.5-bcmath \
php8.5-soap \
php8.5-intl \
php8.5-readline \
php8.5-ldap \
php8.5-msgpack \
php8.5-igbinary \
php8.5-redis \
#php8.5-swoole \
php8.5-memcached \
php8.5-pcov \
php8.5-imagick \
php8.5-xdebug \
&& curl -sLS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer \
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \
&& apt-get update \
&& apt-get install -y nodejs \
&& npm install -g npm \
&& npm install -g pnpm \
&& npm install -g bun \
&& npx playwright install-deps \
&& curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /etc/apt/keyrings/yarn.gpg >/dev/null \
&& echo "deb [signed-by=/etc/apt/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \
&& curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/keyrings/pgdg.gpg >/dev/null \
&& echo "deb [signed-by=/etc/apt/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt noble-pgdg main" > /etc/apt/sources.list.d/pgdg.list \
&& apt-get update \
&& apt-get install -y yarn \
&& apt-get install -y $MYSQL_CLIENT \
&& apt-get install -y postgresql-client-$POSTGRES_VERSION \
&& apt-get -y autoremove \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.5
RUN userdel -r ubuntu
RUN groupadd --force -g $WWWGROUP sail
RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail
RUN git config --global --add safe.directory /var/www/html
COPY start-container /usr/local/bin/start-container
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY php.ini /etc/php/8.5/cli/conf.d/99-sail.ini
RUN chmod +x /usr/local/bin/start-container
EXPOSE 80/tcp
ENTRYPOINT ["start-container"]
php.ini (変更後)
[PHP]
post_max_size = 100M
upload_max_filesize = 100M
variables_order = EGPCS
pcov.directory = .
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host="host.docker.internal"
xdebug.client_port=9101
xdebug.log=/tmp/xdebug.log
php.ini (変更前)
[PHP]
post_max_size = 100M
upload_max_filesize = 100M
variables_order = EGPCS
pcov.directory = .
Discussion