Laravel Sail: Docker Development Environment Setup Guide
Learn Laravel Sail for Docker-based PHP development.
20+ years shipping production PHP systems at scale. Lessons pulled from things that broke in production.
- ✓Basic knowledge of Laravel and PHP
- ✓Docker and Docker Compose installed on your machine
- ✓Composer installed globally or in your project
- ✓Familiarity with command-line interface
- Laravel Sail is a lightweight command-line interface for interacting with Laravel's default Docker configuration.
- It provides a pre-configured Docker environment for PHP, MySQL, Redis, and more.
- No need to install PHP, Composer, or a database locally; everything runs in containers.
- Sail is ideal for team consistency and quick project setup.
- It uses Docker Compose under the hood and is highly customizable.
Imagine you're building a model ship. Instead of gathering all the tiny pieces and tools yourself, you get a complete kit with everything pre-sorted and instructions. Laravel Sail is like that kit for your web app—it gives you a ready-to-use environment (PHP, database, etc.) inside a box (Docker), so you can start building without worrying about setup.
Setting up a local development environment for Laravel can be a pain. You need PHP, Composer, a database server, Redis, maybe Node.js, and you have to manage versions and configurations. If you're working on a team, everyone's environment might be slightly different, leading to the dreaded 'it works on my machine' problem.
Enter Laravel Sail. Sail is a lightweight command-line interface for interacting with Laravel's default Docker configuration. It provides a complete development environment with PHP, MySQL, Redis, Mailhog, and more, all running in Docker containers. With Sail, you can start a new Laravel project with a single command, and your entire team gets the same environment.
Sail is built on top of Docker Compose, so you can customize it to your needs. It's perfect for both beginners who want to avoid system configuration headaches and experienced developers who need a consistent, reproducible environment.
In this tutorial, you'll learn how to install and use Laravel Sail, customize services, run commands, debug issues, and follow best practices for production-like setups. By the end, you'll be able to spin up a full Laravel environment in minutes.
What is Laravel Sail?
Laravel Sail is a lightweight command-line interface for interacting with Laravel's default Docker configuration. It provides a pre-configured Docker environment for developing Laravel applications. Sail is built on top of Docker Compose, and it's designed to be a simple, fast way to get a Laravel development environment up and running.
Sail includes services like PHP, MySQL, Redis, Mailhog, and more. You can customize which services are installed during setup. Sail also provides a convenient CLI for running common commands like 'sail artisan', 'sail composer', and 'sail npm'.
One of the key benefits of Sail is consistency. Every developer on your team gets the same environment, eliminating 'it works on my machine' issues. It also isolates your project from your host system, so you can work on multiple projects with different requirements without conflicts.
Sail is not meant for production use. It's a development tool. For production, you should use a more robust setup like Laravel Forge or custom Docker configurations.
Installing and Configuring Laravel Sail
To install Sail in an existing Laravel project, you need to require the package via Composer. Then run the 'sail:install' Artisan command to publish the Docker Compose file and configure services.
During installation, you can choose which services you need: MySQL, PostgreSQL, Redis, Mailhog, etc. Sail will generate a 'docker-compose.yml' file in your project root.
After installation, you can start Sail with './vendor/bin/sail up -d' or by using the 'sail' alias. To make things easier, add an alias to your shell: alias sail='[ -f sail ] && bash sail || bash vendor/bin/sail'.
Sail uses environment variables from your .env file. Make sure to set DB_HOST to 'mysql' (or the service name) instead of '127.0.0.1'. Also, set DB_PORT to 3306 (internal port).
You can customize the Docker configuration by editing the 'docker-compose.yml' file. For example, you can change the PHP version, add new services, or modify resource limits.
Running Common Commands with Sail
Sail provides a convenient CLI for running common Laravel and PHP commands. Instead of typing 'php artisan', you use 'sail artisan'. Similarly, 'sail composer', 'sail npm', 'sail yarn', and 'sail shell' are available.
- sail up -d: Start containers in the background
- sail down: Stop containers
- sail build: Rebuild containers
- sail artisan migrate: Run migrations
- sail composer require package: Install a Composer package
- sail npm install: Install Node dependencies
- sail shell: Open a bash shell inside the container
- sail root-shell: Open a shell as root
- sail logs: View logs from all containers
- sail logs mysql: View logs from the MySQL container
You can also run any command inside the container using 'sail exec'.
Customizing Sail Services and Environment
Sail is highly customizable. You can change PHP versions, add services like Meilisearch or Selenium, and modify environment variables.
To change the PHP version, edit the 'build' context in docker-compose.yml to point to a different runtime directory (e.g., './vendor/laravel/sail/runtimes/8.2').
To add a new service, simply add a new service definition to docker-compose.yml. For example, to add Meilisearch:
meilisearch: image: 'getmeili/meilisearch:latest' ports: - '7700:7700' environment: MEILI_MASTER_KEY: '${MEILI_MASTER_KEY}' volumes: - 'sail-meilisearch:/meili_data' networks: - sail
You can also customize environment variables in the .env file. Sail uses variables like APP_PORT, DB_PORT, FORWARD_DB_PORT, etc.
If you need to install additional PHP extensions, you can create a custom Dockerfile that extends Sail's base image.
Debugging with Xdebug in Sail
Sail comes with Xdebug pre-installed, but it's disabled by default. To enable Xdebug, set the SAIL_XDEBUG_MODE environment variable in your .env file.
For example, to enable debugging and profiling: SAIL_XDEBUG_MODE=debug,profile
You also need to set the client host. On macOS and Windows, use 'host.docker.internal'. On Linux, you may need to use your host's IP address.
After setting the variables, rebuild the containers with 'sail build --no-cache' and restart.
Then configure your IDE to listen for Xdebug connections. For PhpStorm, set the server name to 'sail' and map the project root to '/var/www/html'.
You can also use 'sail debug' command to start a debugging session.
Sharing Your Local Site with Sail Share
Sail includes a 'share' command that exposes your local development site to the internet using Ngrok. This is useful for testing webhooks, mobile apps, or sharing progress with clients.
To use it, simply run: sail share
This will start an Ngrok tunnel and provide a public URL like https://abc123.ngrok.io.
You can customize the subdomain or region using options: sail share --subdomain=myapp --region=eu
Note: Ngrok requires an account for custom subdomains and longer sessions. You can sign up for free at ngrok.com.
Sail Best Practices and Common Pitfalls
Here are some best practices to get the most out of Laravel Sail:
- Use .env for configuration: Keep environment-specific settings in .env. Never commit sensitive data to version control.
- Rebuild containers after changes: If you modify docker-compose.yml or Dockerfile, run 'sail build --no-cache' to apply changes.
- Persist data with volumes: Sail uses named volumes for databases and Redis. This ensures data persists across container restarts.
- Avoid using 'sail down' unnecessarily: It stops and removes containers. Use 'sail stop' to pause them.
- Set file permissions: If you encounter permission issues, run 'sail root-shell' and fix permissions inside the container.
- Use 'sail artisan optimize' for production: Before deploying, run optimization commands like 'config:cache', 'route:cache', etc.
- Forgetting to set DB_HOST to the service name.
- Using 'localhost' instead of 'mysql' for database connections.
- Not running 'sail artisan config:clear' after changing .env.
- Assuming Sail is suitable for production.
- Ignoring Docker resource limits (CPU, memory).
The Case of the Missing MySQL Connection
- Always use Docker service names as hostnames when connecting between containers.
- Run 'sail artisan config:clear' after changing .env values.
- Check container logs with 'sail logs mysql' to verify the database is ready.
- Use 'sail ps' to see which containers are running.
- Remember that Sail's environment is isolated; localhost refers to the container, not your host machine.
php artisan sail:installsail up -d| File | Command / Code | Purpose |
|---|---|---|
| install-sail.sh | composer require laravel/sail --dev | What is Laravel Sail? |
| docker-compose.yml | version: '3' | Installing and Configuring Laravel Sail |
| sail-commands.sh | sail up -d | Running Common Commands with Sail |
| Dockerfile.custom | FROM sail-8.3/app | Customizing Sail Services and Environment |
| .env.xdebug | SAIL_XDEBUG_MODE=debug,profile | Debugging with Xdebug in Sail |
| sail-share.sh | sail share | Sharing Your Local Site with Sail Share |
| sail-best-practices.sh | sail build --no-cache | Sail Best Practices and Common Pitfalls |
Key takeaways
Common mistakes to avoid
4 patternsUsing '127.0.0.1' as DB_HOST in .env
Forgetting to run 'sail artisan config:clear' after changing .env
Running 'sail down' frequently
Assuming Sail is suitable for production
Interview Questions on This Topic
What is Laravel Sail and what problem does it solve?
Frequently Asked Questions
20+ years shipping production PHP systems at scale. Lessons pulled from things that broke in production.
That's Laravel. Mark it forged?
4 min read · try the examples if you haven't