Abstract
When Dockerizing a Laravel application, it’s easy to end up with large, bloated images or frustrating permission errors.
In this guide, you’ll learn how to properly configure your .dockerignore
, manage file permissions, and keep your Laravel app working smoothly inside containers.
Understanding .dockerignore
The .dockerignore
file is used to tell Docker which files and directories to ignore when building an image with docker build
.
It works similarly to .gitignore
and helps optimize the image build process by:
- reducing build context size (fewer files sent to the Docker daemon);
- speeding up build times;
- preventing sensitive files (e.g., .env, SSH keys) from being copied into the image;
- avoiding unnecessary cache invalidation due to unrelated file changes.
.dockerignore
must be placed in the Docker build context directory.
If your folder structure looks like this:
project-root/
├── Dockerfile
├── .dockerignore
└── src/ (your Laravel project)
And you run:
docker build -f Dockerfile .
Then project-root/
is the build context — so .dockerignore
belongs there.
All ignore rules will be relative to this context.
This means paths like src/vendor
in .dockerignore
will correctly match project-root/src/vendor
.
Laravel-Specific .dockerignore
example
Here is an example of .dockerignore
tailored for Laravel, assuming Laravel app lives in src/
:
# Laravel vendor and frontend deps
src/vendor
src/node_modules
# Laravel cache and logs
src/storage/logs
src/storage/framework/cache/**
!src/storage/framework/cache/
# Environment files
src/.env
src/.env.*
# PHPUnit and tests (for production builds)
src/phpunit.xml
src/phpunit.xml.dist
src/tests
# Bootstrap cache
src/bootstrap/cache/**
!src/bootstrap/cache/
# Lock files
src/composer.lock
src/yarn.lock
src/package-lock.json
# Editor & OS junk
*.swp
*.swo
*.bak
*.tmp
*.log
*.idea
*.vscode
.DS_Store
Thumbs.db
# Git
.git
.gitignore
Preserving empty directories
Laravel expects certain directories to exist:
storage/framework/cache
bootstrap/cache
If you want to ignore the contents but keep the folders, use negation:
src/storage/framework/cache/**
!src/storage/framework/cache/
src/bootstrap/cache/**
!src/bootstrap/cache/
This ensures Docker keeps the folder structure but skips the files inside.
Fixing “permission denied” error
You might see this error when running the container:
The stream or file "/var/www/html/storage/logs/laravel.log" could not be opened in append mode: Failed to open stream: Permission denied
This means the user running PHP doesn’t have write permission to storage/
, and we need to fix permissions.
Add the following after copying your project:
RUN chown -R www-data:www-data storage bootstrap/cache \
&& chmod -R ug+rwX storage bootstrap/cache
This command ensures the web server user (www-data) owns the necessary directories and has the correct write permissions.
Recap
- Place
.dockerignore
in the build context, not just next to the Dockerfile. - Ignore the
vendor
andlogs
folders. - Preserve Laravel folder structure with negation (
!folder/
). - Fix permissions for
storage/
andbootstrap/cache
.