Since switching to use Laravel Forge to build servers for Laravel based projects I've not had to deal with the permissions issue that arises when first installing the app on your production server.
Basically, Laravel requires write permissions on the storage/ and bootstrap/cache directories. This is taken care of on a Homestead box as the vagrant user is added to the www-data group, so this issue doesn't show up until you get to production.
Today I had to install a Laravel project on a dedicated server running Apache... how 2010.
Anyway this issue came up again and as with pretty much everything I learn and solve in web development I couldn't remember how to fix it, so I'm writing this post, mainly so I can come back to it again next time!
The solution
The obvious way to solve this is to just grant the server user (in this case www-data) ownership of those directories and files, bit of chown and you're done, simple...
That is unless you're deploying the application using git. In my case I'm pushing the local repo to a "production" remote which simply checks out the files into a detached work tree... (I also had to look that up at first).
What this means is that the git commands are running as my system user account, so it can't update the contents of anything in storage, which it will want to do as this directory structure isn't .gitignored by default... so you end up with this when you push...
remote: error: unable to unlink old 'storage/app/.gitignore' (Permission denied)
remote: error: unable to unlink old 'storage/app/public/.gitignore' (Permission denied)
remote: error: unable to unlink old 'storage/framework/.gitignore' (Permission denied)
remote: error: unable to unlink old 'storage/framework/cache/.gitignore' (Permission denied)
remote: error: unable to unlink old 'storage/framework/sessions/.gitignore' (Permission denied)
remote: error: unable to unlink old 'storage/framework/testing/.gitignore' (Permission denied)
remote: error: unable to unlink old 'storage/framework/views/.gitignore' (Permission denied)
remote: error: unable to unlink old 'storage/logs/.gitignore' (Permission denied)
The solution then is slightly more involved... slightly.
What we need to do is basically make sure the server user is either the group for all files in /storage (or included in the group that's the group, I'm positive that's not how you say that). Then, we need to make sure that the group user has read, write, execute permissions on everything in /storage.
The way to do this is....
sudo chgrp -R www-data storage bootstrap/cache
sudo chmod -R ug+rwx storage bootstrap/cache
And that's it. (Thanks to bashy on Laracasts for providing that: https://laracasts.com/discuss/channels/general-discussion/laravel-framework-file-permission-security)
And there you have it, permissions on storage sorted.