Laravel Sail command is very slow compared to docker compose. How can I improve the performance of Laravel Sail?

Updated: Feb 20, 2025

Laravel Sail command is very slow compared to docker compose. How can I improve the performance of Laravel Sail?

Laravel Sail is a Docker-based development environment provided by Laravel for building and testing PHP applications. It simplifies the process of setting up a local development environment by providing pre-configured Docker images for various components such as MySQL, Redis, and PHP. However, some developers have reported that Laravel Sail is slower than using Docker Compose directly. In this answer, we will discuss some possible reasons for this performance issue and provide solutions to improve the performance of Laravel Sail.

  1. Use a dedicated MySQL image: Laravel Sail uses a multi-stage Dockerfile to build the application image, which includes a MySQL server image in the build process. However, this approach may not be the most efficient way to run a MySQL server for development purposes. Instead, you can use a separate MySQL image for your development environment and mount it as a volume in your Laravel Sail container. This approach can improve the performance of your Laravel Sail environment by allowing the MySQL server to run in its own container with dedicated resources.

To use a separate MySQL image with Laravel Sail, follow these steps:

a. Create a new MySQL image based on the official MySQL Docker image:

docker pull mysql:8.0
docker build -t my-mysql:8.0 .

b. Create a .docker-compose.yml file with the following content:

version: '3.8'

services:
  db:
    image: my-mysql:8.0
    volumes:
      - db_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: homestead
      MYSQL_USER: homestead
      MYSQL_PASSWORD: secret
    ports:
      - "3306:3306"

volumes:
  db_data:

c. Start the MySQL container:

docker-compose up -d db

d. Update your .env file with the new database connection details:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_database_name
DB_USERNAME=your_database_user
DB_PASSWORD=your_database_password

e. Start Laravel Sail with the updated configuration:

sail up
  1. Use a dedicated Redis image: Similar to the MySQL server, you can also use a separate Redis image for your Laravel application. This approach can improve the performance of your Laravel Sail environment by allowing Redis to run in its own container with dedicated resources.

To use a separate Redis image with Laravel Sail, follow these steps:

a. Create a new Redis image based on the official Redis Docker image:

docker pull redis:7.0
docker build -t my-redis:7.0 .

b. Create a .docker-compose.yml file with the following content:

version: '3.8'

services:
  redis:
    image: my-redis:7.0
    volumes:
      - redis_data:/data
    ports:
      - "6379:6379"

volumes:
  redis_data:

c. Start the Redis container:

docker-compose up -d redis

d. Update your .env file with the new Redis connection details:

BROADCAST_DRIVER=redis
CACHE_DRIVER=redis
SESSION_DRIVER=redis
QUEUE_DRIVER=redis
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_database_name
DB_USERNAME=your_database_user
DB_PASSWORD=your_database_password
REDIS_HOST=127.0.0.1
REDIS_PORT=6379

e. Start Laravel Sail with the updated configuration:

sail up
  1. Use a smaller PHP image: Laravel Sail uses a large PHP image that includes many development tools and libraries that may not be necessary for your development environment. You can improve the performance of Laravel Sail by using a smaller PHP image that only includes the necessary components for your application.

To use a smaller PHP image with Laravel Sail, follow these steps:

a. Create a new Dockerfile based on the official PHP image:

touch Dockerfile

b. Add the following content to the Dockerfile:

FROM php:8.0-fpm-alpine

RUN apk add --no-cache --update \
    zip \
    unzip \
    curl \
    gzip \
    tar \
    oniguruma-utils \
    libxml2-dev \
    && docker-php-ext-install pdo pdo_mysql zip unzip \
    && apk del apk --purge \
        gcc \
        g++ \
        make \
        libc-dev \
        zlib-dev \
        oniguruma-dev \
        libxml2-dev

c. Create a .dockerignore file with the following content:

/var/www/html
/var/www
/var/cache
/var/log

d. Update your .sailfile with the new Dockerfile location:

version: '3.8'

services:
  laravel:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8000:80"
      - "8080:8080"
      - "3333:3333"
      - "9527:9527"
      - "8001:8001"
      - "3306:3306"
      - "6379:6379"
      depends_on:
        - db
        - redis
    volumes:
      - "./:/var/www/html"
      - "./.env:/var/www/html/.env"
      - "./php.ini:/usr/local/etc/php/php.ini"
      - "./artisan:/var/www/html/artisan"
      - "./storage:/var/www/html/storage"
      - "./bootstrap/cache:/var/www/html/bootstrap/cache"
      - "./vendor:/var/www/html/vendor"
      - "./node_modules:/var/www/html/node_modules"
    environment:
      - HOST=0.0.0.0
      - DB_HOST=db:3306
      - DB_PORT=3306
      - DB_DATABASE=your_database_name
      - DB_USERNAME=your_database_user
      - DB_PASSWORD=your_database_password
      - REDIS_HOST=redis:6379
      - REDIS_PORT=6379
      - MAIL_MAILER=smtp
      - MAIL_HOST=smtp.gmail.com
      - MAIL_PORT=587
      - [email protected]
      - MAIL_PASSWORD=your_email_password
      - MAIL_ENCRYPTION=tls
      - APP_KEY=base64:your_app_key
      - Laravel_SAIL=1

  db:
    image: my-mysql:8.0
    volumes:
      - db_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD=root
      MYSQL_DATABASE=homestead
      MYSQL_USER=homestead
      MYSQL_PASSWORD=secret
    ports:
      - "3306:3306"

  redis:
    image: my-redis:7.0
    volumes:
      - redis_data:/data
    ports