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
.gitignorePreserving empty directories
Laravel expects certain directories to exist:
storage/framework/cachebootstrap/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 deniedThis 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/cacheThis command ensures the web server user (www-data) owns the necessary directories and has the correct write permissions.
Recap
- Place
.dockerignorein the build context, not just next to the Dockerfile. - Ignore the
vendorandlogsfolders. - Preserve Laravel folder structure with negation (
!folder/). - Fix permissions for
storage/andbootstrap/cache.