How to Fix Permission Issues When Running PHPUnit with Laravel Sail

Dr. Adam Nielsen
3 min readAug 13, 2024

--

If you’re using Laravel Sail for your development environment, you may encounter permission issues when trying to run PHPUnit. In this article, I’ll walk you through the problem and provide a straightforward solution.

The Problem: Permission Denied When Running Tests with Sail

When working on a Laravel project with Sail, you might attempt to run your test suite using the following command:

sail phpunit

However, instead of successfully running your tests, you may be greeted with an error message like this:

mkdir(): Permission denied

This issue arises because the default user inside the Sail container is sail, which may not have the necessary permissions to write to certain directories in your Laravel project. These directories typically include storage and bootstrap/cache, which Laravel relies on for caching and logging during the test runs.

Interestingly, if you were to enter your Docker container as the root user and run PHPUnit, everything might work perfectly:

docker-compose exec laravel.test bash
./vendor/bin/phpunit

But why does it work as root and not as sail? The root cause is (pun intended) file permissions.

Understanding File Permissions in Dockerized Laravel Projects

In Unix-based systems, including the Linux containers used by Docker, each file and directory has an owner and a set of permissions that control who can read, write, or execute the file.

Permissions Breakdown

Permissions are typically represented by three numbers (e.g., 775). Each digit controls permissions for:

  • Owner: The user who owns the file or directory.
  • Group: The group that owns the file or directory.
  • Others: Everyone else.

For example, 775 means:

  • Owner: Can read, write, and execute (7 = rwx).
  • Group: Can read, write, and execute (7 = rwx).
  • Others: Can read and execute (5 = r-x).

Ownership Breakdown

Each file and directory is also owned by a specific user and group. When you run commands as the root user, files and directories are often created with root ownership. When you switch back to the sail user, they might not have the necessary permissions to modify these files, leading to permission errors.

The Solution: Fixing Permissions for the Sail User

To resolve these permission issues, you’ll need to adjust the permissions and ownership of the storage and bootstrap/cache directories. Here’s how you can do it:

Step 1: Adjust Directory Permissions

First, make sure that the sail user has the necessary write permissions:

docker-compose exec laravel.test bash
chmod -R 775 storage bootstrap/cache

This command recursively changes the permissions of all files and directories inside storage and bootstrap/cache so that the owner and group can read, write, and execute them.

Step 2: Update Directory Ownership

Next, set the ownership of these directories to the sail user:

chown -R sail:sail storage bootstrap/cache

This command recursively changes the owner and group of all files and directories inside storage and bootstrap/cache to sail.

Step 3: Run Your Tests

Now that the permissions and ownership are correctly set, you can run your test suite with the sail user without encountering permission issues:

sail phpunit

Everything should now work smoothly!

Step 4: Don’t commit

When you change file permissions or ownership in your project directory, Git often detects these changes as modifications, which is why it might ask you to commit them. This can be problematic, especially if you’re working in a team or if these permission changes are specific to your local environment.

Therefore, don’t commit the file owner changes in the storage and bootstrap/cache directories. You can simply disable git tracking file changes via:

git config core.fileMode false

Conclusion

Running into permission issues when using Laravel Sail can be frustrating, but they are relatively easy to fix once you understand how file permissions and ownership work within your Docker containers. By adjusting the permissions and ownership of critical directories like storage and bootstrap/cache, you can ensure that the sail user has the necessary access to run your tests.

Next time you encounter a “Permission denied” error, you’ll know exactly what to do!

Happy coding!

--

--