Como resolver erros de permissões no Laravel logs

O erro no Laravel sobre Permission Denied é um dos problemas mais frustrantes que desenvolvedores e times de DevOps/SRE podem encontrar ao trabalhar com o framework Laravel. Este problema geralmente ocorre devido a configurações incorretas de permissões de arquivos e diretórios relacionados a Laravel Logs, especialmente em ambientes de produção. Neste artigo, vamos explorar as principais causas e apresentar soluções definitivas para resolver este erro e evitar indisponibilidades na sua aplicação PHP.

erros de permissões no laravel

Principais erros de permissões no Laravel

O Laravel é um popular framework PHP usado por muitos desenvolvedores para criar aplicativos web. Um problema comum que pode ocorrer ao trabalhar com o Laravel é o erro:

The stream or file "/var/www/html/storage/logs/laravel.log" could not be opened in append mode: failed to open stream: permission denied

Esse erro ocorre quando o Laravel não consegue gravar em seu arquivo de log, porque não tem permissão para acessar a pasta de armazenamento.

Outro erro muito comum, que pode acontecer quanto não temos as permissões definidas corretamente no Laravel, é o erro abaixo:

Error in exception handler: The stream or file "/var/www/laravel/app/storage/logs/laravel.log" could not be opened: failed to open stream: Permission denied in /var/www/laravel/bootstrap/compiled.php:8423

Solução paliativa

Uma solução que é indicada em muitos fóruns e blogs, é aplicarmos a permissão chmod 777, que acaba deixando nosso servidor muito exposto.

Em alguns casos são sugeridos outros comandos chmod, chgrp, que até podem não deixar o servidor com a segurança menor, mas não trazem uma solução definitiva para erros de permissão no Laravel.

Solução definitiva

Felizmente, há uma solução relativamente fácil para esse problema. Você pode aplicar permissões e herança nas permissões da pasta /var/www/html/storage/logs no servidor.

Para fazer isso, você precisará acessar o servidor onde o Laravel está hospedado e executar alguns comandos na pasta do projeto(neste exemplo estamos usando a /var/www/html/).

Outro ponto importante é que eu procuro adicionar os usuários que trabalham com o Laravel ao grupo www-data, para que após aplicada a solução eles consigam manipular os arquivos sem trazer problemas e novos erros de permissão no Laravel.

Segue o script que devemos utilizar, adapte ele conforme a sua necessidade:

## laravel log permission
cd /var/www/html/
sudo chgrp -R www-data bootstrap/ storage/ storage/logs/
sudo chmod -R 755 bootstrap/ storage/ storage/logs/
sudo chmod -R g+w bootstrap/ storage/ storage/logs/
cd bootstrap/
sudo find -type d -exec chmod g+s {} +
cd ..
cd storage/
sudo find -type d -exec chmod g+s {} +
cd ..
cd storage/logs/
sudo find -type d -exec chmod g+s {} +

Um pouco mais sobre cada comando

Esse script em Bash é usado para conceder permissões corretas para os diretórios bootstrap/, storage/ e storage/logs/ de um projeto Laravel que está localizado em /var/www/html/. Especificamente, o script define o grupo proprietário desses diretórios como www-data, que é o usuário e grupo padrão do servidor da web no Ubuntu. Além disso, o script garante que esses diretórios tenham permissões de gravação para o grupo www-data.

A parte do script que se refere a herança de permissões é a seguinte linha:

sudo find -type d -exec chmod g+s {} +

Essa linha define o bit SGID em todos os diretórios dentro dos diretórios bootstrap/, storage/ e storage/logs/. Quando o bit SGID é definido em um diretório, ele garante que todos os novos arquivos criados dentro desse diretório herdem o grupo proprietário do diretório pai. Isso é útil para garantir que todos os arquivos criados dentro dos diretórios bootstrap/, storage/ e storage/logs/ tenham o mesmo grupo proprietário (www-data) e, portanto, possam ser lidos e gravados pelo servidor da web.

Em resumo, o script executa as seguintes ações:

  1. Navega até a pasta do projeto Laravel em /var/www/html/.
  2. Define o grupo proprietário dos diretórios bootstrap/, storage/ e storage/logs/ como www-data.
  3. Concede permissões 755(O dono do arquivo tem permissão total. O grupo do arquivo tem permissão de leitura e execução. Outros usuários têm permissão de leitura e também de execução.) e gravação para o grupo www-data nos diretórios bootstrap/, storage/ e storage/logs/.
  4. Define o bit SGID em todos os diretórios dentro dos diretórios bootstrap/, storage/ e storage/logs/, para garantir a herança de permissões de grupo em novos arquivos criados nesses diretórios.
framework php laravel

Detalhando cada opção dos comandos

sudo chgrp -R

sudo : o comando sudo é usado para executar comandos com privilégios de super usuário (root) no sistema operacional Linux ou Unix.

chgrp: o comando chgrp é usado para alterar o grupo proprietário de um arquivo ou diretório.

-R: é uma opção para o comando chgrp que significa “recursivamente”. Ela faz com que o comando seja executado em todos os diretórios e subdiretórios abaixo do diretório atual.

Em resumo, o comando sudo chgrp -R altera recursivamente o grupo proprietário de todos os arquivos e diretórios abaixo do diretório atual.

sudo chmod 755

A permissão 755 é uma configuração de permissões comumente usada em sistemas operacionais baseados em Unix, como Linux e macOS. Ela define os seguintes níveis de acesso:

  • Dono do arquivo:
    • Leitura (r)
    • Escrita (w)
    • Execução (x)
  • Grupo do arquivo:
    • Leitura (r)
    • Execução (x)
  • Outros usuários:
    • Leitura (r)
    • Execução (x)

Isso significa que:

  • O dono do arquivo tem permissão total (leitura, escrita e execução).
  • O grupo do arquivo tem permissão de leitura e execução.
  • Outros usuários têm permissão de leitura e a permissão de execução.

sudo chmod -R g+w

sudo: igual ao anterior

chmod: é um comando que é usado para alterar as permissões de acesso de um arquivo ou diretório.

-R: igual ao anterior

g+w: é uma opção para o comando chmod que significa “adicionar permissão de escrita para o grupo”. “g” é o grupo proprietário do arquivo ou diretório.

Em resumo, o comando sudo chmod -R g+w adiciona a permissão de escrita para o grupo proprietário em todos os arquivos e diretórios abaixo do diretório atual.

sudo find -type d -exec chmod g+s {} +

sudo: igual ao anterior

find: é um comando usado para encontrar arquivos e diretórios com base em critérios específicos.

-type d: é uma opção para o comando find que significa “encontrar apenas diretórios”.

-exec: é uma opção para o comando find que executa um comando em cada arquivo ou diretório encontrado.

chmod g+s: é o comando que será executado em cada diretório encontrado pelo find. “g” é o grupo proprietário do diretório e “s” é uma opção que significa “definir o bit setgid”. Isso faz com que todos os arquivos criados dentro do diretório herdem o grupo proprietário do diretório.

{}: é um espaço reservado para o nome do arquivo ou diretório encontrado pelo find.

+: indica que o comando chmod g+s deve ser executado uma vez para cada grupo de arquivos ou diretórios encontrados.

Em resumo, o comando sudo find -type d -exec chmod g+s {} + encontra todos os diretórios abaixo do diretório atual e executa o comando chmod g+s em cada um deles, garantindo que todos os arquivos criados dentro desses diretórios tenham o mesmo grupo proprietário.

Exemplo na prática

Aqui no meu laboratório eu gosto de utilizar o projeto Travellist – Laravel Demo App, que utiliza framework PHP Laravel, para praticar a instalação e o uso básico do Laravel, ele sobe um aplicativo de lista de viagens de exemplo, para mostrar uma lista de lugares para onde um usuário gostaria de viajar e uma lista de lugares que ele já visitou.

Após subir o projeto e acessar ele via Browser, esta é a página que é mostrada:

travellist
App – Travellist

Como é possível verificar na imagem abaixo, os arquivos e pastas estão com as permissões setadas de forma correta e os Containers estão funcionando dentro do esperado:

laravel logs
Containers e arquivos

Um diretório que é bem importante, pois grava todos os logs do Laravel, é o diretório storage/logs

Verificando as permissões deste diretório e dos diretórios que estão dentro do storage:

storage

Erros de permissões no Laravel e seu diretório storage ou no diretório logs, podem levar a falhas na sua aplicação e ocorrência de erros de “Permission denied” relacionados a pasta /var/www/storage/logs

Neste exemplo abaixo eu estou efetuando um ajuste incorreto nas permissões do diretório storage, para forçar a ocorrência do erro de permissão:

permissoes

Com as permissões setadas incorretamente, se eu tento acessar novamente a página do Travellist no meu ambiente local, ocorre o seguinte erro:

erro
Erro relacionado ao Laravel Logs

Mensagem de erro:

UnexpectedValueException
There is no existing directory at "/var/www/storage/logs" and its not buildable: Permission denied 

Para regularizar as permissões do diretório storage e os diretórios abaixo dele, executei os comandos abaixo:

docker exec -u 0 -it travellist-app /bin/bash
chgrp -R www-data storage/ storage/logs/
chmod -R 755 storage/ storage/logs/
chmod -R g+w storage/ storage/logs/
cd storage/
find -type d -exec chmod g+s {} +

Importante destacar que, neste caso eu utilizei um comando Docker para acessar o container como usuário root, para conseguir aplicar estes comandos, conforme o parâmetro:

-u 0: Especifica o ID do usuário (0 é o ID do root)

Não devem ocorrer erros durante a aplicação dos comandos, conforme abaixo:

comandos solucao definitiva
Comandos – Solução definitiva

Após aplicar os comandos, o acesso a página do projeto em Laravel é restabelecido:

travellist normalizado

Material de apoio


O erro “Laravel Permission Denied” pode parecer complicado, mas as soluções são diretas quando entendemos o funcionamento do sistema de permissões. Configurar corretamente os diretórios storage e bootstrap/cache, ajustar o usuário e grupo, e garantir que não sejam modificadas as permissões de forma indevida são etapas fundamentais para evitar que esse erro atrapalhe o funcionamento do projeto.

Mais dicas sobre solução de problemas? Acesse: https://devopsmind.com.br/category/troubleshooting


Imagem de capa de freepik

Compartilhe / Share
Fernando Müller Junior
Fernando Müller Junior

Eu sou o Fernando Müller, um Tech Lead SRE com 16 anos de experiência em TI, atualmente eu trabalho na Appmax, uma fintech localizada no Brasil. Apaixonado por trabalhar com arquiteturas e aplicações Cloud Native, ferramentas Open Source e tudo que existe no mundo SRE, sempre procurando se desenvolver e aprender constantemente(Lifelong learning), atuando em projetos inovadores!

Artigos: 39

Receba as notícias por email / Receive news by email

Insira seu endereço de e-mail abaixo e assine nossa newsletter / Enter your email address below and subscribe to our newsletter

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *