Laravel Sail: The Docker Development Environment for Laravel 13, Step by Step
Laravel Sail is the official Docker development environment for Laravel, and it ships with Laravel 13: a single command brings up PHP, MySQL, and Redis without requiring any Docker experience. Behind it there is no magic, just a compose.yaml file and a sail script at the project root.
What Laravel Sail Is and Why Use It
Sail is, in essence, the compose.yaml file and the sail script that Laravel keeps at the root of your project. The script acts as a wrapper that translates familiar commands —artisan, composer, npm— into calls to the corresponding Docker containers. The whole team keeps using the same interface as always while Docker stays in the background.
Docker Without Friction: compose.yaml + the Sail Script
You do not need to master Docker to get value from Sail. Sail defines the services in compose.yaml, and the sail script takes care of starting them, wiring them together, and running commands inside the application container. If you have ever fought with misconfigured volumes, networks, or images, Sail removes that layer of friction: containers are built and started with a single command.
Reproducible Environments for the Whole Team
Because compose.yaml is versioned alongside the code, it guarantees that everyone develops with the same versions of PHP, MySQL, and Redis, whether they use Linux, macOS, or Windows with WSL2. The classic "it works on my machine" problem disappears: if the configuration lives in the repository, reproducibility is automatic and onboarding new people becomes clone and run.
Installation: Docker and Your First Sail Project
The only prerequisite is having Docker installed and running (Docker Desktop on macOS and Windows, or the Docker engine on Linux). From there, creating a Sail project is straightforward and requires no manual setup.
Creating a New Project with Sail Included
The official route creates the project and leaves Sail configured with the services you pick during installation:
curl -s https://laravel.build/example-app | bash
cd example-app
./vendor/bin/sail up -dThe installer lets you mark the services you need: mysql, pgsql, mariadb, redis, memcached, meilisearch, minio, selenium, and mailpit. With sail up -d the application is available at http://localhost with PHP, MySQL 8, and Redis running, without touching anything else.
Adding Sail to an Existing Laravel Project
If you already have a project, Sail is installed as a development package and publishes its configuration with two commands:
composer require laravel/sail --dev
php artisan sail:installThen start the environment with ./vendor/bin/sail up -d. Sail does not rewrite your code: it adds compose.yaml, the sail script, and a sample .env adapted to the containers, with ports, credentials, and service hosts pointing to Docker's internal addresses.
The Daily Workflow with the Sail Command
Once running, Sail prefixes the commands you already know so they execute inside the application container, with the project's PHP version and extensions.
sail up, sail artisan, and sail composer
./vendor/bin/sail up -d # start the environment in the background
./vendor/bin/sail artisan migrate # run migrations inside the container
./vendor/bin/sail composer require laravel/telescope
./vendor/bin/sail npm run dev # assets with the container's NodeTo type less, add an alias to your shell: alias sail='[ -f sail ] && sh sail || sh vendor/bin/sail'. There are also handy commands like sail shell, which opens a terminal inside the container, and sail down, which stops every service when you finish for the day.
Available Services: MySQL, Redis, Mailpit, Meilisearch, and More
Beyond PHP and the web server, Sail includes ready-to-use services: MySQL 8, PostgreSQL, MariaDB, Redis, Memcached, Meilisearch for search, MinIO as a local S3, Selenium for browser tests, and Mailpit to capture the emails your application sends in development (visible at http://localhost:8025). You choose them when creating the project or add them later by editing compose.yaml.
Customizing Sail: Services and PHP Version
The environment adapts to the project by editing compose.yaml and rebuilding the image. This is the mechanism you use both to change the PHP version and to trim the services down to what the application actually needs.
Changing the PHP Version (Up to 8.5)
The PHP version is defined in the build argument of the laravel.test container. To move up to PHP 8.5, the standard in Laravel projects in 2026:
laravel.test:
build:
args:
PHP_VERSION: '8.5'After editing, rebuild the image with ./vendor/bin/sail build --no-cache and start the environment again. Changing the PHP version is one of the most common reasons to touch Sail, and the process is always the same: edit, build, start.
Adding and Removing Services in compose.yaml
Services are added or removed as compose.yaml blocks. If your project does not use Redis, delete its definition; if you start needing Meilisearch, add its service and declare the dependency in the laravel.test container. After each change, rebuild and restart so the containers reflect the new configuration without dragging dead services along.
Common Problems and Fixes
Even though Sail hides most of Docker's complexity, three typical issues show up eventually for almost everyone.
Storage Permissions and Busy Ports
The permission error in storage/ and bootstrap/cache/ appears mostly on Linux, when files are created by a different user. The usual fix is adjusting the owner of the project directory or running commands through sail, which already runs as the correct user. Busy ports —3306 for MySQL or 80 are often taken by other local services— are solved by changing the port mapping in compose.yaml, for example 3307:3306.
Performance on macOS and Windows (WSL2)
On macOS, Docker Desktop virtualizes Linux and file performance depends on how the project is mounted; keeping the code out of problematic paths and giving Docker enough memory helps. On Windows, the recommended setup is WSL2 with the project inside the Linux filesystem rather than under /mnt/c, because crossing filesystems slows read and write operations down considerably.
Sail vs. Laradock, Herd, and FrankenPHP
Sail is not the only option. Laradock offers many more services and fine-grained control, but at the cost of manual configuration and a steep learning curve. Herd is Laravel's native environment: no Docker, lighter and faster for local development on macOS and Windows, ideal when you do not need containers. FrankenPHP, meanwhile, is a PHP application server written in Go that shines in production and also works for development, especially if you want to test the same runtime you will deploy with. The practical rule: Sail when you want a standardized Docker environment without friction, Herd when you prefer native tooling, and FrankenPHP when the focus is production.
Conclusion
Laravel Sail turns Docker into a configuration detail: a compose.yaml file and a script your team can share without an instruction manual. Install it in your project, customize the PHP version and services, and forget about broken environments. If you want to keep improving your Laravel 13 workflow, check out the rest of the web development guides on this blog.