Laravel Sail and Docker

Laravel Sail 1,922 (https://github.com/laravel/sail 1,922 ) is Laravel 2,157 's Docker 514 development environment: a compose.yaml in your project plus a sail script that forwards php, composer, artisan and npm 2,036 into the containers. It runs on macOS, Linux and Windows through WSL2 6 , needs only Docker on the host, defaults to a PHP 8.5 image on Ubuntu 24.04 225 , and offers fifteen services, among them MySQL 524 , PostgreSQL 1,289 , Redis 2,763 , Meilisearch 106,756 , Mailpit and Selenium 44,681 . Here it is added to a copy of the bookshop with MySQL only:

Adding Sail to an application and starting itShell
composer require laravel/sail --dev
php artisan sail:install --with=mysql
printf 'APP_PORT=8301\nFORWARD_DB_PORT=13301\nVITE_PORT=5301\n' >> .env
./vendor/bin/sail up -d --wait
./vendor/bin/sail php --version | head -1
./vendor/bin/sail artisan migrate
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8301/up
Output
...
 Container bookshop-laravel.test-1 Started
 Container bookshop-laravel.test-1 Healthy
 Container bookshop-mysql-1 Healthy
PHP 8.5.10 (cli) (built: Aug 28 2026 07:25:54) (NTS)
...
  0001_01_01_000002_create_jobs_table .......................... 253.29ms DONE
200

--wait holds sail up until MySQL's health check passes; without it, the migration here failed with SQLSTATE[HY000] [2002] Connection refused while the database was still initializing. sail:install set DB_HOST=mysql, because containers reach each other by service name, and Sail's default ports, 80, 3306 and 5173, collide with any Apache, MySQL or Vite 25,978 already running; the three variables move them. The first sail up built the image in 12 minutes, after one attempt failed on a mirror checksum error; later starts take seconds. The container runs PHP 8.5.10 but MySQL 8.4, not MySQL's 9.7.