10 mins read

Powerful Guide: Laravel with Docker for Fast Development

Setup Laravel with Docker

Laravel with Docker provides a consistent, isolated, and portable environment for developing and deploying modern PHP applications. Instead of installing PHP, Composer, MySQL, Redis, Nginx, and other dependencies directly on your operating system, Docker packages these services into containers that can be created, configured, and removed independently. This approach is particularly useful for Laravel developers working across Windows, Linux, and macOS because the application environment can remain consistent regardless of the host machine.

Why Use Docker for Laravel Development?

Traditional Laravel development often requires developers to install and configure multiple components manually. A typical Laravel application may require a specific PHP version, Composer, database server, web server, Node.js, npm, and additional PHP extensions. Version differences between developers can create the familiar “works on my machine” problem.

Docker addresses this problem by allowing each project to define its own runtime environment. A development team can specify the PHP version, database version, ports, volumes, networks, and supporting services in configuration files and share them through Git.

  • Consistency: Developers can use the same PHP and database versions.
  • Isolation: Project dependencies remain separated from the host operating system.
  • Portability: The same container configuration can be used across development and CI/CD environments.
  • Easy setup: New developers can start the project without manually installing every dependency.
  • Scalability: Additional services such as Redis, queues, or workers can be added as containers.

Basic Architecture for Laravel with Docker

A practical Laravel with Docker environment usually contains several services. The exact architecture depends on the project, but a common setup separates the application, database, and web server.

  • Laravel/PHP container: Runs PHP and the Laravel application.
  • Nginx container: Handles HTTP requests and forwards PHP requests to PHP-FPM.
  • MySQL container: Stores application data.
  • Redis container: Provides caching, queues, and other in-memory functionality when required.
  • Node.js container: Can be used for frontend asset compilation when required.

Docker Compose can connect these services through an internal Docker network, allowing Laravel to communicate with MySQL using the service name rather than a hard-coded IP address.

Prerequisites

Before starting, install Docker Desktop on Windows or macOS, or Docker Engine and Docker Compose on Linux. On Windows, Docker Desktop can also work with WSL 2 to provide a Linux-based development environment.

You should also have basic knowledge of Laravel, Docker commands, environment variables, and YAML configuration.

Create a Laravel Project

If you already have a Laravel project, you can use that project directory. For a new application, Laravel can be created using Composer or an appropriate Laravel starter workflow.

composer create-project laravel/laravel laravel-docker

Move into the project directory:

cd laravel-docker

The project should contain the standard Laravel structure, including directories such as app, config, database, public, resources, and routes.

Create the Dockerfile

The Dockerfile defines the environment required to run Laravel. A simple PHP-FPM image can be used as the foundation.

FROM php:8.3-fpm

WORKDIR /var/www/html

RUN apt-get update && apt-get install -y \
    git \
    unzip \
    libzip-dev \
    libpng-dev \
    libonig-dev

RUN docker-php-ext-install \
    pdo_mysql \
    mbstring \
    zip \
    bcmath

COPY --from=composer:2 /usr/bin/composer /usr/bin/composer

COPY . /var/www/html

RUN chown -R www-data:www-data /var/www/html

EXPOSE 9000

CMD ["php-fpm"]

This image installs PHP-FPM, required PHP extensions, Composer, and the Laravel application code. The exact extensions should be adjusted according to the application’s requirements.

Create Docker Compose Configuration

Docker Compose makes it easier to manage multiple containers as one application environment. Create a file named docker-compose.yml in the Laravel with docker project directory. Use Docker Hub for download images

services:

  app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: laravel_app
    working_dir: /var/www/html
    volumes:
      - ./:/var/www/html
    networks:
      - laravel

  nginx:
    image: nginx:alpine
    container_name: laravel_nginx
    ports:
      - "8080:80"
    volumes:
      - ./:/var/www/html
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - app
    networks:
      - laravel

  mysql:
    image: mysql:8.0
    container_name: laravel_mysql
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_USER: laravel
      MYSQL_PASSWORD: secret
      MYSQL_ROOT_PASSWORD: root
    ports:
      - "3307:3306"
    volumes:
      - mysql_data:/var/lib/mysql
    networks:
      - laravel

networks:
  laravel:

volumes:
  mysql_data:

This configuration creates three primary services: Laravel/PHP, Nginx, and MySQL. The MySQL volume ensures that database data can persist when the container is recreated.

Configure Nginx for Laravel

Create the directory structure for the Nginx configuration:

mkdir -p docker/nginx

Create docker/nginx/default.conf with a configuration similar to the following:

server {
    listen 80;
    server_name localhost;

    root /var/www/html/public;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    location ~ /\.ht {
        deny all;
    }
}

The important detail is root /var/www/html/public. Laravel’s public directory should be the web server’s document root rather than the project root.

Configure Laravel Database Connection

Inside Laravel’s .env file, configure the database connection using the Docker Compose service name.

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laravel
DB_PASSWORD=secret

A common Docker mistake is using localhost for DB_HOST. Inside the Laravel container, localhost refers to the Laravel container itself, not the MySQL container. Because the Compose service is named mysql, Laravel should use mysql as its database hostname.

Build and Start the Containers

Build the application image and start the environment with Docker Compose:

docker compose build
docker compose up -d

Check running containers:

docker compose ps

You should see the application, Nginx, and MySQL services running.

Install Laravel Dependencies

Run Composer inside the application container:

docker compose exec app composer install

Generate the Laravel application key:

docker compose exec app php artisan key:generate

Run database migrations:

docker compose exec app php artisan migrate

Once the containers are running, open the application through the configured host port:

http://localhost:8080

Useful Docker Commands for Laravel Developers

Once the environment is running, developers can perform most Laravel tasks directly inside the application container.

  • View containers: docker compose ps
  • View application logs: docker compose logs app
  • Open a shell: docker compose exec app bash
  • Run migrations: docker compose exec app php artisan migrate
  • Clear Laravel cache: docker compose exec app php artisan optimize:clear
  • Run Composer: docker compose exec app composer install
  • Stop services: docker compose down

Case Study: Standardizing a Laravel Development Team

Consider a development team with five engineers. One developer uses PHP 8.2, another uses PHP 8.3, while a third has a different MySQL version installed locally. These differences can result in dependency conflicts and inconsistent application behavior.

With Docker, the team can define one PHP image, one database version, and a shared Compose configuration. Every developer starts the same environment using the same commands. This does not eliminate every application bug, but it substantially reduces differences caused by local runtime configuration.

Performance and Development Considerations

Docker adds an additional abstraction layer, so filesystem performance can matter, particularly when large Laravel with docker projects use bind mounts. Developers working on Windows should pay particular attention to where project files are stored when using Docker Desktop and WSL 2.

For improved development performance, consider:

  • Keeping frequently accessed Linux-based project files inside the WSL filesystem when appropriate.
  • Using Docker volumes strategically for dependencies and databases.
  • Avoiding unnecessary file watchers and background processes.
  • Using production-oriented images separately from development images.
  • Pinning important image versions instead of relying blindly on latest.

Docker in Laravel CI/CD

The same containerized approach can extend beyond local development. CI/CD systems can build the Laravel application, execute automated tests, run static analysis, and create deployment artifacts using controlled Docker environments.

This provides an important advantage: development and automation environments can use the same dependency definitions. Teams can therefore reduce configuration drift between local development, testing, and deployment workflows.

Best Practices for Laravel with Docker Projects

  • Use versioned base images rather than depending exclusively on latest.
  • Keep secrets outside Dockerfiles and source control.
  • Use separate development and production configurations where necessary.
  • Persist databases using Docker volumes.
  • Keep Docker images as small as reasonably possible.
  • Use multi-stage builds for production images when appropriate.
  • Document common Docker and Laravel commands for the development team.
  • Regularly update PHP, Laravel, operating-system packages, and container images.

Conclusion

Running Laravel with Docker creates a repeatable development environment in which PHP, Laravel, Nginx, MySQL, Redis, and other services can be managed independently while still working together as one application stack. Docker Compose simplifies the process by defining these services, networks, volumes, and configuration in a version-controlled file.

The most important concepts are understanding container networking, configuring Laravel’s database connection correctly, managing persistent storage, and separating development concerns from production deployment. Once these fundamentals are understood, Docker becomes more than a local development convenience: it becomes a practical foundation for consistent testing, CI/CD automation, and modern Laravel deployments.

For Laravel with docker and DevOps teams, learning to containerize applications is therefore a valuable step toward more predictable, portable, and maintainable application delivery.

Share your Love