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
andlogs
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!