Use Docker Volumes and Networks in Laravel Project

Containerizing PHP applications like Laravel is now the norm for seamless development, testing, and deployment. Docker's volumes and networks unlock the full potential of a containerized setup, providing flexibility, data persistence, and secure service-to-service communication.

In this article, you'll learn:

  • What Docker volumes are and how to use them in Laravel projects
  • How to leverage Docker networks for secure and efficient communication between services
  • Practical examples to integrate volumes and networks in your Laravel development workflow

Why Use Docker Volumes and Networks?

Before we dive into hands-on steps, let’s briefly recap what these Docker features bring to your workflow:

  • Docker Volumes: Persist and share application data outside container lifecycles. For Laravel, this means your project files and runtime data (like storage and logs) survive container rebuilds and updates.
  • Docker Networks: Enable isolated, secure communication between containers (e.g., app, database, cache) with fine-grained control.

By mastering both, your Laravel development becomes faster, safer, and more consistent.


1. Docker Volumes for Laravel

What Are Docker Volumes?

Volumes are managed, host-independent storage locations. Mappings ensure data is:

  • Not lost on container rebuilds/removals
  • Shareable across multiple containers

Typical Laravel usage includes:

  • Project source code (local development)
  • storage and logs directories
  • Database data if needed

Setting Up Volumes for Laravel

Suppose you have this directory structure:

laravel-docker/
├── docker-compose.yml
├── Dockerfile
└── src/    # Your Laravel app

Example docker-compose.yml for Volumes

version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    image: laravel-app
    container_name: laravel-app
    volumes:
      - ./src:/var/www/html          # Syncs local code for hot-reload
      - laravel_storage:/var/www/html/storage    # Dedicated persistent storage for `storage`
    networks:
      - laravel

  db:
    image: mysql:8.0
    container_name: laravel-db
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_ROOT_PASSWORD: secret
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - laravel

volumes:
  laravel_storage:    # Named volume for persistent app storage
  db_data:            # Named volume for MySQL data

networks:
  laravel:
    driver: bridge

Key Takeaways:

  • Mount project code for live development (./src:/var/www/html)
  • Separate, persistent volumes for storage and database
  • Volumes declared under the volumes root for sharing and reusability

Why Map the Storage Directory?

Laravel expects the storage and occasionally the bootstrap/cache directories to be writable. Keeping these directories mapped as a named volume ensures:

  • Persistence: Even if the code volume is unmounted or replaced, runtime assets like cached views, queues, and logs remain.
  • Isolation: Your host’s permissions won’t interfere with how the container manages these directories.

2. Docker Networks for Laravel

What Are Docker Networks?

Docker networks isolate and connect containers, preventing unwanted outside access and controlling how services "see" each other. Laravel projects often require:

  • The app server (PHP, Nginx) communicating with the database (MySQL/Postgres) and perhaps with a cache or queue (Redis)
  • Services NOT exposed externally except where required (e.g., only the web server on port 8000/80)

Setting Up Networks for Laravel

Most setups use a custom bridge network—flexible for local development and multi-container projects.

How It Works in docker-compose.yml

networks:
  laravel:
    driver: bridge

And reference it in each service:

services:
  app:
    networks:
      - laravel
  db:
    networks:
      - laravel
  redis:
    image: redis:alpine
    networks:
      - laravel

Benefits:

  • Containers discover each other by their service name. E.g., the app container can reference the database at laravel-db (the service name).
  • Isolation: Only containers on the same network can communicate.

3. Bringing It All Together

Complete Example

docker-compose.yml:

version: '3.8'

services:
  app:
    build:
      context: .
    container_name: laravel-app
    volumes:
      - ./src:/var/www/html
      - laravel_storage:/var/www/html/storage
    depends_on:
      - db
      - redis
    networks:
      - laravel
    ports:
      - "8000:8000"   # Exposes Laravel on http://localhost:8000

  db:
    image: mysql:8.0
    container_name: laravel-db
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_ROOT_PASSWORD: secret
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - laravel

  redis:
    image: redis:alpine
    container_name: laravel-redis
    networks:
      - laravel

volumes:
  laravel_storage:
  db_data:

networks:
  laravel:
    driver: bridge

Dockerfile:

FROM php:8.2-fpm

# Install system dependencies
RUN apt-get update && apt-get install -y \
    libpng-dev libonig-dev libxml2-dev zip unzip git curl

# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd

# Set working directory
WORKDIR /var/www/html

# Composer
COPY --from=composer:2.6 /usr/bin/composer /usr/bin/composer

4. Usage Tips

Starting the Environment

docker-compose up -d

Artisan Commands

Run Artisan in the container:

docker-compose exec app php artisan migrate

Composer Commands

docker-compose exec app composer install

5. Cleaning Up

  • Remove containers:
    docker-compose down

  • Remove volumes:
    docker-compose down -v


Conclusion

Docker volumes and networks are essential for creating a robust Laravel development environment. By persisting important data and securely connecting services, you keep your workflow fast, organized, and resilient.

Next Steps:
Experiment with additional services, add your favorite tools (Mailhog, Horizon), and tailor volumes/networks as your app grows!


Need help or want to share your setup? Comment below!