Laravel And Docker: A Guide To Using Laravel Sail

Set up a fully containerized development environment for Laravel applications in minutes--no manual PHP or database installation required.

What Is Laravel Sail

Laravel Sail is an officially maintained package that provides a pre-configured Docker development environment specifically designed for Laravel applications. At its core, Sail is built on Docker Compose, the industry-standard tool for defining and running multi-container Docker applications. The package includes a custom sail script that acts as a wrapper around Docker Compose commands, making it intuitive for developers who may not be familiar with Docker's command-line interface.

Key benefits of Laravel Sail:

  • Cross-platform compatibility - Works on macOS, Linux, and Windows via WSL2
  • Consistent environments - Every team member runs identical configurations
  • No local dependencies - PHP, Composer, Node.js all run in containers
  • Pre-configured services - MySQL, Redis, Mailpit included by default
  • Extensible - Easily add Meilisearch, Selenium, MongoDB, and more

The "works on my machine" problem has plagued PHP development teams for years, where applications behave differently between developer environments due to varying PHP versions, extensions, or database configurations. Laravel Sail eliminates this issue by ensuring every developer on your team runs the exact same containerized configuration, from PHP version to database settings. Containerized development has become essential for modern PHP applications because it mirrors production environments more accurately, catches configuration-related bugs early in development, and simplifies onboarding new team members who can get started in minutes rather than hours of setup time.

Laravel Sail is essentially a docker-compose.yml file combined with a sail script stored at your project's root directory. The sail script provides convenient methods for executing commands against the Docker containers defined by your compose.yaml file. This approach ensures that every developer on your team--and your production environment--runs the exact same configuration, eliminating discrepancies between development setups. Whether you're working on a new Laravel project or integrating Docker into an existing application, Sail provides a standardized path to containerized development that integrates seamlessly with Laravel's ecosystem. Our web development team regularly uses Sail to streamline PHP projects for clients across North America and Europe.

Why Use Laravel Sail for Development

Streamline your development workflow with containerization

Instant Setup

Spin up a complete development environment in minutes without manually installing PHP, MySQL, Redis, or other dependencies.

Team Consistency

Every developer runs identical container configurations, eliminating environment-related bugs and configuration issues.

Resource Isolation

Your development environment is isolated from your host system, preventing conflicts with other projects or system packages.

Production Parity

Development environment mirrors production configuration, reducing deployment surprises and environment-specific bugs.

Installing Laravel Sail Into New Projects

When creating a new Laravel application, Sail is automatically installed, providing you with a ready-to-use Docker development environment immediately after project creation. The Laravel installer or Composer create-project command will set up your project structure and include all necessary Docker configuration files.

For new Laravel projects using the Laravel installer:

# Create new Laravel application
laravel new my-app
cd my-app

# Start the development environment
./vendor/bin/sail up

For developers who prefer the Composer method, the composer create-project command provides an alternative approach that works the same way with Sail included by default. Both methods produce identical project structures with Sail pre-configured and ready to use.

The first time you run sail up, Docker will download the necessary base images and set up your containers, which may take several minutes depending on your internet connection speed. Once the containers are running, you can access your Laravel application at http://localhost. The default configuration includes PHP-FPM for application processing, MySQL for database storage, Redis for caching and queues, and Mailpit for local email testing.

After your containers are running, the development experience feels seamless--you run all commands through Sail (sail artisan, sail composer, sail npm) without needing any tools installed locally. The sail script automatically delegates to the appropriate container and executes your commands in the correct environment, ensuring consistency across your entire team regardless of operating system.

Installing Sail Into Existing Applications

For existing Laravel applications, integrating Sail requires adding the package to your project and publishing its Docker configuration. This process allows you to containerize an existing application without modifying your application's core code, making it possible to transition to Docker-based development at your own pace.

Steps to add Sail to an existing project:

# Install Sail as a development dependency
composer require laravel/sail --dev

# Publish Docker configuration
php artisan sail:install

# Start the containers
./vendor/bin/sail up

The sail:install command runs interactively and prompts you to select which services you want to include in your development environment. Options include MySQL, PostgreSQL, MariaDB, Redis, Meilisearch, Mailpit, MinIO, and Selenium. You can select multiple services or accept the defaults (MySQL and Redis) for a standard Laravel application.

During installation, Sail will modify your .env file to include the necessary environment variables for connecting to Docker-based services. It backs up your existing .env first and provides clear comments explaining each new variable. This makes it easy to review changes and understand how your application now connects to containerized services. The installer also creates the docker-compose.yml file and supporting configuration in your project root.

For teams adopting Sail gradually, the transition strategy is straightforward: install Sail alongside your existing setup, configure it to work with your current database or a fresh Docker database, then gradually migrate team members. Your existing local development setup remains functional while you validate the Docker workflow, ensuring no disruption to active development. Once comfortable, you can update your project's README with Sail instructions and deprecate any custom local setup documentation.

Executing Commands With Laravel Sail

Laravel Sail provides convenient commands for executing various tasks within your Docker containers, eliminating the need to install PHP, Composer, or other tools on your local machine. These commands ensure consistent execution across your team using the same PHP version and extensions.

Essential Sail commands:

CommandPurpose
sail upStart all containers
sail up -dStart containers in detached mode
sail downStop and remove containers
sail stopStop containers without removal
sail artisan [command]Run Artisan commands
sail composer [command]Run Composer commands
sail php [script.php]Execute PHP scripts
sail npm [command]Run npm/Node commands
sail testRun PHPUnit tests
sail shellOpen interactive bash session

Example workflows:

# Run database migrations
sail artisan migrate

# Install a Composer package
sail composer require laravel/sanctum

# Start Vite dev server
sail npm run dev

# Run tests with coverage
sail test --coverage

# Open a shell in the container
sail shell

# Check container status
sail ps

The sail shell command is particularly valuable for complex operations, giving you full access to your container's filesystem and command-line tools. Within the shell session, you can run multiple commands without the sail prefix, chain commands together, and use your preferred development tools. This is essential for debugging, running database migrations with prompts, or any workflow requiring interactive input.

Best practices for command execution include using detached mode (sail up -d) for routine development to free your terminal, creating shell aliases for frequently used commands, and running tests through Sail to ensure they execute in the same environment as your production code. Consistent use of Sail commands across your team eliminates environment-specific test failures and ensures every developer sees identical results.

Configuring Shell Aliases For Convenience

Typing ./vendor/bin/sail repeatedly can become tedious. Configuring a shell alias streamlines your workflow significantly and is one of the first optimizations most developers make when adopting Sail.

Add this to your ~/.bashrc or ~/.zshrc:

alias sail='sh $([ -f sail ] && echo sail || echo vendor/bin/sail)'

This intelligent alias checks whether the sail script exists in your current directory (useful for projects with a local sail file) and falls back to vendor/bin/sail if not found. After adding the alias, restart your terminal or run source ~/.bashrc (or source ~/.zshrc for Zsh users) to apply the changes.

Additional workflow aliases many developers add:

alias sailup='sail up -d'
alias sailstop='sail stop'
alias saildown='sail down'
alias sailart='sail artisan'
alias sailcom='sail composer'
alias sailtest='sail test'
alias saillogs='sail logs -f'
alias sailps='sail ps'

These shortcuts compound over time, significantly reducing the friction of managing containerized development. The key is to configure aliases that match your actual workflow--if you rarely run Composer commands, skip that alias. Test your alias configuration by running sail --version to confirm everything is working correctly before relying on it for important operations.

Shell Alias Configuration
# Add Sail alias to shell config
alias sail='sh $([ -f sail ] && echo sail || echo vendor/bin/sail)'

# Apply changes
source ~/.bashrc # or ~/.zshrc

# Verify it works
sail --version

# Common workflow shortcuts
alias sailup='sail up -d'
alias sailstop='sail stop'
alias saildown='sail down'

Database Configuration And Management

Laravel Sail includes MySQL as the default database service, configured with persistent storage using Docker volumes to ensure your data survives container restarts and rebuilds. When you start your Sail containers for the first time, MySQL automatically creates a database using the name specified in your .env file's DB_DATABASE variable, along with a dedicated testing database that won't interfere with your development data.

Default database configuration:

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=sail
DB_PASSWORD=password

For PostgreSQL instead of MySQL, choose PostgreSQL during the sail:install prompt, or modify your docker-compose.yml to use the PostgreSQL service instead of MySQL. PostgreSQL configuration follows similar patterns with DB_CONNECTION=pdo-pgsql and appropriate host, port, and credential variables.

Connecting from your host machine:

You can connect to the MySQL database using any database client (TablePlus, DBeaver, MySQL Workbench) by connecting to localhost on port 3306 with the credentials from your .env file. This allows you to inspect your database, run queries, or use your preferred database management tools alongside Sail's containerized environment.

Data persistence with Docker volumes:

Docker volumes preserve your database data even when containers are stopped or removed. The volume is created automatically the first time you run Sail and persists in Docker's managed storage. You can verify volumes exist with docker volume ls and inspect them with docker volume inspect laravel-mysql. For important projects, consider regular database exports as a backup strategy, since Docker volumes exist on your host machine and could be affected by system changes or disk issues. To completely reset your database, run sail down -v to remove volumes, then sail up to create fresh ones.

Working With Redis And Additional Services

Redis is included by default in Sail's service offering, providing a powerful in-memory data store for caching, session management, and queue processing. The Redis container runs alongside your PHP and database containers, accessible through the REDIS_HOST environment variable configured by Sail. Laravel's Redis integration works immediately with this configuration, allowing you to use Redis for cache drivers, session storage, or as a backend for Laravel Horizon queue workers without additional configuration.

Default Redis configuration:

REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379

Adding additional services with sail:add:

php artisan sail:add

This command presents an interactive menu for adding services:

  • Meilisearch - Full-text search engine integrated with Laravel Scout, ideal for applications requiring fast, typo-tolerant search capabilities
  • Mailpit - Local email testing and preview, replaces sending emails to external addresses during development
  • MinIO - S3-compatible object storage for testing cloud storage functionality locally
  • Selenium - Browser testing with Laravel Dusk for automated end-to-end testing
  • MongoDB - Document database for applications using MongoDB
  • Valkey - Redis-compatible key-value store with additional features

Each service is configured with appropriate default settings and environment variables. Meilisearch is particularly valuable for applications requiring fast, typo-tolerant search, while Mailpit provides a convenient web interface at http://localhost:8025 for viewing emails sent during development. Adding services after initial installation is non-destructive, updating your docker-compose.yml without affecting existing containers or data. Choose services based on your application's actual requirements rather than adding everything available--keep your development environment lean and focused.

Debugging With Xdebug

Xdebug is pre-configured in Laravel Sail's PHP containers, enabling powerful debugging capabilities for your Laravel applications. When Xdebug is enabled, you can set breakpoints, step through code execution, and inspect variable values using any Xdebug-compatible IDE. This debugging capability is invaluable for understanding complex code paths, diagnosing issues, and validating your application's behavior during development.

Enabling Xdebug mode for CLI commands:

XDEBUG_MODE=debug sail artisan migrate
XDEBUG_MODE=develop,debug sail test

IDE configuration:

Xdebug typically listens on port 9003. Configure your IDE to:

  1. Accept Xdebug connections on port 9003
  2. Set up path mappings from container paths to local paths
  3. Configure the correct IDE key (default: "docker")

For PHPStorm:

Enable the Xdebug listener (phone icon in top toolbar), configure PHP remote debug with the Docker interpreter, and set up path mappings that map /var/www/html in the container to your project root locally. The Docker plugin in PHPStorm simplifies this configuration significantly.

For VS Code:

Install the PHP Debug extension, create a launch.json configuration with "listen for Xdebug" mode, and configure port 9003. Path mappings in the debug configuration ensure breakpoints in your local files trigger correctly in container execution.

For Docker Desktop users:

The host.docker.internal alias allows containers to reach your IDE's debug listener running on your host machine.

For Linux users:

Add this to your docker-compose.yml to enable host access:

php:
 extra_hosts:
 - "host.docker.internal:host-gateway"

Debugging web requests vs CLI commands:

Web requests typically trigger Xdebug automatically when your IDE is listening. For CLI commands, you must set the XDEBUG_MODE environment variable. The XDEBUG_IDE_KEY helps your IDE identify which debugging session belongs to which request. Understanding this distinction is crucial for effective debugging--whether you're stepping through a web request or tracing an Artisan command execution.

Stopping And Managing Containers

Proper container management is essential for maintaining a clean development environment and conserving system resources.

Container lifecycle commands:

CommandAction
sail upStart containers (foreground)
sail up -dStart containers (background)
sail stopStop containers, keep data
sail downRemove containers and volumes
sail down -vRemove containers with volumes
sail down --rmi allRemove images too

When to use each command:

  • sail up - When starting work, after system reboot
  • sail stop - When stepping away, to free resources while preserving your environment
  • sail down - When done with work, before system changes
  • sail down -v - When you need a fresh database or want to completely reset

Volume persistence:

Docker volumes preserve your database and Redis data across container lifecycle changes. Use sail stop when you want to resume later with all data intact. Use sail down only when you need to free disk space or troubleshoot configuration issues. The -v flag is powerful but destructive--data in volumes is permanently deleted.

Rebuilding containers:

sail down
sail build --no-cache
sail up

Use rebuild when you've modified your Dockerfile or need to refresh container configurations. The --no-cache flag ensures a clean build without using cached layers, which is essential after configuration changes.

Port conflict resolution:

If containers fail to start due to port conflicts, check what's using the port:

# Check what's using port 80 (Linux)
sudo lsof -i :80

# Check what's using port 80 (macOS)
lsof -i :80

# View container status and port bindings
sail ps

System resource management:

Regular container cleanup prevents resource accumulation. Run sail down periodically to remove stopped containers and networks. Monitor Docker Desktop's memory and CPU allocation--increase if containers seem slow. For teams working on multiple projects, stopping Sail containers when not in use prevents unnecessary resource consumption.

Best Practices And Common Issues

Following best practices with Laravel Sail ensures a smooth development experience and minimizes potential issues.

Best practices:

  1. Never run as root on Linux - Configure Docker to run as your user or use sail shell which executes within the container as a non-root user. This prevents files created inside containers from being owned by root on your host filesystem.
  2. Use .env for configuration - Never hardcode credentials or connection details. Sail's environment variables ensure consistency across all developers.
  3. Regular container cleanup - Run sail down periodically to prevent orphaned resources and free disk space.
  4. Commit docker-compose.yml - Keep Docker configuration in version control so environment changes are tracked alongside application code.
  5. Use sail test - Run tests in the containerized environment for consistency with production behavior.

Common issues and solutions:

Port conflicts:

# Check what's using port 80
sudo lsof -i :80
# Or on macOS
lsof -i :80

Permission issues on Linux:

# Add your user to the docker group
sudo usermod -aG docker $USER

Slow performance:

  • Increase Docker Desktop memory/CPU allocation in Docker settings
  • Use Laravel Octane for production-like performance during development
  • Consider volume mounting strategies--bind mounts can be slower than named volumes

Viewing logs:

sail logs # All container logs
sail logs -f php # Follow PHP container logs
sail logs -f --tail=100 mysql

Performance optimization tips:

For improved performance on macOS and Windows, configure Docker to use the VirtioFS file system (macOS) or WSL2 backend (Windows), which provide faster file sharing between host and containers. Exclude vendor directory and node_modules from file watchers to reduce CPU usage. For large applications, consider using Docker's build cache effectively by ordering Dockerfile instructions from least to most frequently changing.

Security considerations:

Never commit your .env file with real credentials to version control. The default Sail database password is intentionally weak for local development only. If you need to connect to external services, use environment-specific configuration that isn't shared in the repository. Regularly update your Docker images with sail build --no-cache to receive security patches in base images.

Frequently Asked Questions

Conclusion

Laravel Sail represents a significant advancement in Laravel development environment setup, providing a standardized, containerized approach that works consistently across all team members and platforms. By abstracting the complexity of Docker Compose behind an intuitive command-line interface, Sail makes containerized development accessible to developers of all experience levels while still providing full access to Docker's capabilities when needed. The automatic configuration of services like MySQL, Redis, and Mailpit means you can focus on building your application rather than managing infrastructure, and the cross-platform support ensures your entire team works in identical environments.

Key takeaways:

  • Get started in minutes - Automatic setup for new projects, simple integration for existing ones
  • Cross-platform consistency - macOS, Linux, and Windows (WSL2) support
  • Pre-configured services - MySQL, Redis, Mailpit ready out of the box
  • Extensible architecture - Add Meilisearch, Selenium, MongoDB, and more as needed
  • Xdebug integration - Professional debugging capabilities included

Whether you're starting a new Laravel project or containerizing an existing application, Laravel Sail provides a low-friction path to Docker-based development. The ability to add services extends Sail's utility beyond basic PHP application hosting, making it suitable for projects with diverse requirements. Combined with shell aliases for workflow efficiency and Xdebug integration for debugging, Sail delivers a comprehensive development environment solution that integrates seamlessly with Laravel's ecosystem. Embracing Sail means embracing modern development practices while maintaining the simplicity and productivity that Laravel developers have come to expect.

Ready to modernize your Laravel development workflow? Our team specializes in Docker containerization, Laravel architecture, and modern PHP development practices that help teams ship faster with fewer environment-related issues. Whether you're building new applications or migrating existing projects to containerized infrastructure, our web development services can help you implement professional-grade development workflows that scale with your business needs.

Sources

  1. Laravel 12.x Official Sail Documentation - Official Laravel documentation covering all Sail commands, installation steps, and service configurations
  2. Chapimaster Laravel Sail Setup Guide - Beginner-friendly tutorial with practical setup steps and command examples
  3. Docker Official: Laravel Development Setup - Docker's official guide for Laravel development environment configuration

Need Help Containerizing Your Laravel Applications?

Our team specializes in modern PHP development workflows using Docker, Laravel Sail, and containerization best practices.