Moodle em branco ou 404 depois de atualizar: a pasta public e o r.php

Resposta rápida: A partir do Moodle 5.1, o servidor web precisa apontar para a pasta public, e não mais para a pasta principal do Moodle. Se ele continua apontando para a raiz, o site mostra erro, tela em branco ou 404. Corrija a raiz do site, acrescente a regra do r.php e limpe os caches.
Você atualizou o Moodle e, ao abrir o site, encontrou uma tela branca, um "Not Found" ou um "Forbidden". Se a atualização foi do 5.0 (ou de uma versão mais antiga) para o 5.1 ou mais nova, o problema provavelmente não está no banco de dados nem nos cursos: está na nova estrutura de pastas. É uma mudança na configuração do servidor, pequena quando se sabe onde olhar.
O que você está vendo
- Mensagem sobre o diretório raiz. O Moodle tem um aviso próprio, que diz que o diretório raiz não deve ficar acessível ao público e que o servidor deve usar o diretório
/public. Se ele aparecer, a causa está dita na tela. - 404 "Not Found" do servidor em páginas internas ou em links diretos, como a página de gerenciamento de um curso. Indica que falta a regra de fallback do
r.php, o roteador do Moodle. - 403 "Forbidden". Costuma ser o servidor já apontando para a pasta nova, enquanto a permissão de acesso (o bloco
Directorydo Apache) ainda se refere ao caminho antigo. - Tela em branco. O PHP parou antes de montar a página. Pode ser versão de PHP incompatível com o Moodle novo, ou arquivos da versão antiga misturados com os da nova (acontece quando o pacote novo é extraído por cima da pasta antiga). O log de erros do servidor mostra qual. Veja Moodle com erro 500.
- Página abre, mas sem estilo. Abra as ferramentas do navegador (F12), vá à aba Rede e veja qual endereço de CSS ou JavaScript devolve 404 ou 403. Costuma ter a mesma causa: o servidor não está servindo a pasta
publicdo jeito certo.
O que mudou no Moodle 5.1
Até o 5.0, o Moodle inteiro ficava dentro da pasta pública do servidor. A partir do 5.1, existe uma pasta public que reúne todos os arquivos acessíveis pela web, e a configuração e outros arquivos sensíveis ficam fora dela, por segurança. O servidor precisa servir somente essa pasta. A documentação oficial avisa que a atualização para o 5.1 não prossegue enquanto isso não estiver configurado. Quem já estava no 5.1 e vai para o 5.2 não precisa repetir a mudança.
/var/www/moodle/
config.php (fica aqui, na raiz)
admin/cli/ (scripts de linha de comando)
public/ (o servidor aponta para cá)
index.php
r.php
mod/ theme/ local/
O r.php é o roteador do Moodle, presente desde o 4.5 e cada vez mais usado. Ele atende endereços que não correspondem a um arquivo físico, e o servidor precisa enviar para ele tudo o que não existe como arquivo. Sem essa regra, esses endereços dão 404. A partir do 5.2, o painel também avisa quando o roteador não está bem configurado.
Os scripts de linha de comando continuam em admin/cli, na raiz, fora de public. O comando do cron, portanto, não muda.
Corrigir no Apache
Com acesso à configuração do servidor, o trecho da documentação oficial é este (ajuste o caminho ao do seu servidor):
DocumentRoot /var/www/moodle/public
<Directory /var/www/moodle/public>
AllowOverride None
Require all granted
DirectoryIndex index.php
FallbackResource /r.php
</Directory>
Teste a configuração com apachectl configtest antes de recarregar o Apache. Sem acesso à configuração central, a documentação aceita um arquivo .htaccess dentro da pasta public, com a linha FallbackResource /r.php, se a hospedagem permitir essa diretiva. Se não permitir, ela traz uma alternativa com mod_rewrite.
Corrigir no nginx
O nginx não lê .htaccess: tudo vai na configuração central do servidor.
root /var/www/moodle/public;
location / {
try_files $uri $uri/ /r.php$is_args$args;
}
O bloco que entrega os arquivos .php ao PHP-FPM continua sendo necessário e precisa enxergar o novo root. A documentação avisa que a linha exata depende do conjunto nginx e PHP-FPM de cada servidor. Valide com nginx -t antes de recarregar.
Hospedagem compartilhada: link simbólico
Em hospedagem compartilhada você não edita o Apache, e o domínio costuma apontar para uma pasta fixa, como public_html. As saídas são trocar a raiz do domínio para a pasta public (quando o painel permite), usar um alias ou criar um link simbólico. Com acesso ao terminal (SSH), a documentação oficial mostra assim:
mkdir -p ~/sites/
mv ~/public_html ~/sites/moodle
ln -s ~/sites/moodle/public ~/public_html
Isso move o site inteiro para ~/sites/moodle e recria o public_html como atalho para a pasta public. Faça backup antes e confira se há outros sites na mesma pasta (como um WordPress): eles precisam ser movidos e ligados de volta à parte. Sem acesso ao terminal, peça ao suporte da hospedagem para apontar o domínio para a pasta public. Os limites desse tipo de plano estão em instalar Moodle na hospedagem compartilhada.
Plugins, temas e o config.php
Plugins e temas de terceiros também mudam de lugar: o que ficava em mod/meuplugin passa a ficar em public/mod/meuplugin. Quem atualiza por git ou copia pastas deixa os plugins nos locais antigos, e eles precisam ser realocados para dentro de public. Num upgrade por pacote, o exemplo da documentação é:
mv moodle moodle.backup
tar xvzf NOME-DO-PACOTE.tgz
cp moodle.backup/config.php moodle
cp -pr moodle.backup/theme/mytheme moodle/public/theme/mytheme
cp -pr moodle.backup/mod/mymod moodle/public/mod/mymod
Três cuidados. Primeiro, o config.php vai na raiz da pasta do Moodle, ao lado de public, nunca dentro dela: lá existe um config.php do próprio Moodle que só carrega o da raiz. Segundo, confira se cada plugin tem versão compatível com o Moodle novo, e não sobrescreva código novo com código antigo. Terceiro, plugin sem versão compatível deve ser desinstalado antes da atualização (veja o guia de plugins).
Como confirmar que ficou certo
Recarregue o servidor, entre na pasta do Moodle e rode, com o usuário do servidor web (costuma ser www-data, apache ou httpd):
cd /var/www/moodle
sudo -u www-data /usr/bin/php admin/cli/purge_caches.php
sudo -u www-data /usr/bin/php admin/cli/checks.php
O primeiro limpa os caches; o segundo roda as verificações do sistema e mostra o que falhou. Depois, faça os testes da documentação do roteador:
- Abra um endereço que não existe. Com o roteador funcionando, aparece a página de erro do Moodle, com o visual do site, e não a do servidor.
- Abra um endereço sem
.php, como/course/ID/manage(troque ID pelo número de um curso). A página de administração do curso deve abrir. - No 5.2 ou superior, veja Administração do site > Relatórios > Status do sistema: a verificação do roteador deve estar sem erro.
Se algo ainda falhar, volte ao error.log do servidor web: ele diz qual arquivo ou regra falhou. Confira também a versão do PHP em qual versão do PHP usar e os prazos em versões do Moodle e datas de suporte.
Leia também: Moodle 5.3 chegou: atualizar agora ou esperar? e como fazer backup do Moodle antes de qualquer atualização.
Leia também: como instalar o Moodle local no seu PC.
Perguntas frequentes
Por que o Moodle ficou em branco ou deu 404 depois de atualizar?
Se você atualizou de uma versão anterior ao 5.1 para o 5.1 ou mais nova, a causa mais provável é a nova estrutura de pastas. O servidor web precisa apontar para a pasta public do Moodle, e o roteador r.php precisa de uma regra de fallback. Com o servidor ainda apontando para a pasta antiga, aparecem erro, tela em branco, 403 ou 404.
Para qual pasta o servidor deve apontar no Moodle 5.1 ou superior?
Para a pasta public dentro da instalação do Moodle, por exemplo /var/www/moodle/public. Só essa pasta deve ficar acessível pela web. A configuração e outros arquivos sensíveis ficam fora dela.
Onde fica o config.php no Moodle 5.1 ou superior?
Na raiz da pasta do Moodle, ao lado da pasta public, e não dentro dela. Ao atualizar, copie o config.php antigo para a raiz da instalação nova. Dentro de public já existe um config.php do próprio Moodle, que apenas carrega o da raiz.
O que é o r.php e preciso configurar o servidor para ele?
O r.php é o roteador do Moodle. Ele atende endereços que não correspondem a um arquivo físico. O servidor precisa enviar para ele tudo o que não existe como arquivo: no Apache, com FallbackResource /r.php; no nginx, com try_files. Sem essa regra, esses endereços devolvem 404 do servidor.
Dá para atualizar o Moodle em hospedagem compartilhada sem acesso à raiz do site?
Dá, desde que seja possível fazer o domínio apontar para a pasta public. Com acesso ao terminal, um link simbólico resolve; sem ele, peça ao suporte da hospedagem para trocar a raiz do domínio. Se o plano não permitir nenhuma alternativa, é hora de considerar outra hospedagem.