Atualizar Moodle 4.5 para 5.1.1: Corrigir /public, DocumentRoot e Plugins [2026]

Atualizar Moodle 4.5 para 5.1.1
Atualizar Moodle 4.5 para 5.1.1

Precisa atualizar Moodle 4.5 para 5.1.1 e o site parou de funcionar? Apareceu listagem de diretório, erro 404 ou página em branco? Calma — o problema quase sempre é o mesmo: no Moodle 5.1, o DocumentRoot precisa apontar para a pasta /public. Se você não ajustou isso, o site quebra na hora.

Neste guia você vai aprender como atualizar o Moodle 4.5 LTS para 5.1.1 de forma segura, incluindo atualização de PHP e MariaDB, corrigir o problema do /public, mover plugins corretamente e ter um rollback rápido se algo der errado. Funciona em Ubuntu, Debian, CentOS — e tem instruções específicas pra quem usa Virtualmin/Webmin.

✅ Testado em produção: Este tutorial foi validado em ambiente real com ~78.000 usuários, PHP 8.3, MariaDB 10.11 e Apache. Todos os comandos e soluções de erros são baseados em experiência prática.

⚠️ Antes de começar: Troque os valores de exemplo pelos do seu ambiente:

  • SEU_BANCO → nome do banco MySQL do Moodle
  • www-data → usuário do webserver (pode ser apache, moodle, etc.)
  • /var/www/moodle → caminho da instalação do Moodle
  • seu-moodle.com.br → domínio real do seu site

O Que Mudou no Moodle 5.1 (Por Que Quebra)

A partir do Moodle 5.1, a equipe reestruturou o código pra melhorar a segurança. Agora existe uma pasta /public que é o único diretório que deve ser acessível via web. Se você deixar o DocumentRoot apontando pra raiz do Moodle (como era antes), vai ver listagem de diretório ou erro.

Estrutura antes (Moodle 4.x):

/var/www/moodle/           ← DocumentRoot apontava AQUI
├── admin/cli/             ← CLI ficava aqui
├── course/
├── theme/
├── config.php
└── index.php

Estrutura agora (Moodle 5.1):

/var/www/moodle/
├── config.php             ← fica FORA do webroot (mais seguro)
├── admin/cli/             ← CLI continua na RAIZ (não em /public!)
└── public/                ← DocumentRoot aponta AQUI agora
    ├── course/
    ├── theme/
    ├── mod/
    └── index.php

Sacou? O config.php e a pasta admin/cli/ ficam fora do alcance do navegador — isso evita vazamento de credenciais se algo der errado com o PHP.

Fonte oficial: Code Restructure (MoodleDev) e Release Notes 5.1.

Requisitos do Moodle 5.1 (Verifique Antes de Atualizar)

Antes de começar, confirme que seu servidor atende aos requisitos mínimos. Se você ainda precisa instalar o ambiente LAMP ou atualizar o PHP, faça isso primeiro. Se faltar algo, o upgrade trava ou dá erro esquisito:

ComponenteMínimoRecomendadoObservação
PHP8.28.38.4 também funciona
MariaDB10.1110.11+Ou MySQL 8.4
PostgreSQL1515+Alternativa ao MySQL
Extensão PHPsodium, bcmath, intlObrigatórias
max_input_vars≥5000No php.ini
Moodle origem4.2.3+Se estiver abaixo, atualize em etapas

Como verificar no terminal

# Versão do PHP
php -v

# Extensões instaladas (procure por sodium, bcmath)
php -m | grep -E "sodium|mysqli|intl|mbstring|gd|curl|zip|bcmath"

# Versão do MySQL/MariaDB
mysql -e "SELECT VERSION();"

# max_input_vars
php -i | grep max_input_vars

# Espaço em disco (precisa caber backup + código novo)
df -h

⚠️ Atenção: se você está no Moodle 3.x, não dá pra pular direto pro 5.1. Precisa fazer upgrade intermediário (3.x → 4.2.3 → 5.1). Consulte a documentação oficial de upgrade.

Pré-requisito: Atualizar PHP para 8.3

Se seu servidor ainda usa PHP 8.1 ou inferior, você precisa atualizar antes do upgrade do Moodle. Esse passo é crítico e muita gente esquece.

Passo 1: Instalar PHP 8.3 e extensões

# Ubuntu/Debian - Adicionar repositório Ondrej (se não tiver)
apt install software-properties-common
add-apt-repository ppa:ondrej/php
apt update

# Instalar PHP 8.3 com extensões necessárias para Moodle
apt install php8.3-fpm php8.3-cli php8.3-mysql php8.3-xml php8.3-mbstring \
    php8.3-curl php8.3-zip php8.3-gd php8.3-intl php8.3-soap php8.3-bcmath \
    php8.3-redis php8.3-igbinary php8.3-sodium php8.3-bz2 php8.3-xsl

# Verificar instalação
php8.3 -v
php8.3 -m | grep -E "sodium|bcmath|intl"

Passo 2: Copiar configurações do PHP antigo

Se você tinha configurações customizadas no PHP 8.1, copie para o 8.3:

# Verificar configurações importantes do PHP antigo
grep -E "^(memory_limit|max_execution|max_input_vars|post_max|upload_max)" /etc/php/8.1/fpm/php.ini

# Aplicar no PHP 8.3 (ajuste os valores conforme seu ambiente)
sed -i 's/^memory_limit = .*/memory_limit = 2048M/' /etc/php/8.3/fpm/php.ini
sed -i 's/^max_execution_time = .*/max_execution_time = 1800/' /etc/php/8.3/fpm/php.ini
sed -i 's/^max_input_vars = .*/max_input_vars = 5000/' /etc/php/8.3/fpm/php.ini
sed -i 's/^post_max_size = .*/post_max_size = 520M/' /etc/php/8.3/fpm/php.ini
sed -i 's/^upload_max_filesize = .*/upload_max_filesize = 512M/' /etc/php/8.3/fpm/php.ini

# Reiniciar PHP-FPM
systemctl restart php8.3-fpm

Passo 3: Atualizar VirtualHost para usar PHP 8.3

# Editar VirtualHost do Apache
# Trocar: SetHandler "proxy:unix:/run/php/php8.1-fpm.sock|fcgi://localhost"
# Para:   SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost"

# Ou usar sed:
sed -i 's/php8.1-fpm.sock/php8.3-fpm.sock/g' /etc/apache2/sites-available/seu-moodle.conf

# Testar e recarregar Apache
apachectl configtest
systemctl reload apache2

# Verificar se está usando PHP 8.3
php -v

Pré-requisito: Atualizar MariaDB para 10.11

O Moodle 5.1 exige MariaDB 10.11 ou MySQL 8.4. Se você usa MariaDB 10.6, precisa atualizar:

Passo 1: Verificar versão atual

mysql -e "SELECT VERSION();"
# Se mostrar 10.6.x, precisa atualizar

Passo 2: Fazer backup do banco (OBRIGATÓRIO!)

# Backup completo antes de atualizar MariaDB
mysqldump --single-transaction --routines --triggers --all-databases | gzip > /root/mariadb_backup_$(date +%Y%m%d).sql.gz

# Verificar se criou
ls -lh /root/mariadb_backup_*.sql.gz

Passo 3: Atualizar repositório e instalar

# Parar o serviço (flush das transações)
mysql -e "FLUSH TABLES;"
mysql -e "FLUSH LOGS;"
systemctl stop mariadb

# Atualizar repositório para 10.11 (Ubuntu/Debian)
# Edite o arquivo do repositório MariaDB e troque 10.6 por 10.11
sed -i 's/10.6/10.11/g' /etc/apt/sources.list.d/mariadb*.list

# Atualizar
apt update
apt install mariadb-server mariadb-client

# ⚠️ IMPORTANTE: Quando perguntar sobre 50-server.cnf, responda N
# para MANTER suas configurações atuais (buffer pool, etc.)

# Iniciar serviço
systemctl start mariadb

# Executar upgrade do schema
mariadb-upgrade

# Verificar versão
mysql -e "SELECT VERSION();"
# Deve mostrar 10.11.x

Passo a Passo: Atualizar Moodle 4.5 para 5.1.1

A estratégia mais segura é: montar o 5.1.1 em outra pasta, e só na janela de mudança trocar as pastas + DocumentRoot. Assim você tem rollback instantâneo se algo der errado.

Passo 1: Ativar manutenção e parar o cron

Primeiro, coloca o site em manutenção pra ninguém entrar durante o upgrade. Use o mesmo usuário que já executa o Moodle (pode ser www-data, apache, moodle, ou o usuário do Virtualmin).

# Substitua os valores conforme seu ambiente:
# - /var/www/moodle = caminho do seu Moodle atual
# - www-data = usuário do webserver (pode ser apache, moodle, etc.)

sudo -u www-data php /var/www/moodle/admin/cli/maintenance.php --enable

# Fazer backup do cron atual
crontab -u www-data -l > /root/cron_moodle_backup.txt

# Desativar o cron (comentar todas as linhas)
crontab -u www-data -l | sed 's/^/#DESATIVADO# /' | crontab -u www-data -

Dica: Se você usa Virtualmin, o usuário provavelmente é o nome do virtual server (ex: moodle ou ead).

Passo 2: Atualizar plugins ANTES do Moodle

⚠️ Importante: Atualize os plugins de terceiros ANTES de atualizar o Moodle. Isso evita erros de incompatibilidade durante o upgrade.

  1. Acesse Administração do site → Plugins → Visão geral de plugins
  2. Clique em “Verificar atualizações disponíveis”
  3. Atualize todos os plugins que têm versões novas, especialmente:
    • Tema Moove → precisa versão 5.1.x (não funciona com versão 4.5.x!)
    • mod_booking → versões antigas causam erro fatal
    • local_wunderbyte_table → dependência do booking
  4. Reinicie o site após cada atualização para verificar se não quebrou nada

Passo 3: Backup obrigatório (banco + código)

Sem backup, você tá apostando o site. Leva 5 minutos e pode salvar horas de dor de cabeça. Se você usa Bacula Enterprise pra backup corporativo, configure um job antes do upgrade:

# Crie pasta de backup
mkdir -p /root/backup_moodle_$(date +%Y%m%d)
cd /root/backup_moodle_$(date +%Y%m%d)

# Backup do banco (ajuste SEU_BANCO)
mysqldump --single-transaction --routines --triggers SEU_BANCO | gzip > moodle_db_backup.sql.gz

# Backup do código (para rollback rápido)
tar -czf moodle_code_backup.tgz -C /var/www moodle

# Verificar se criou
ls -lh

⚠️ Se o moodledata for muito grande (10GB+), não compacte agora. Faça rsync pra outro disco ou confie no backup de rotina.

Passo 4: Baixar o Moodle 5.1.1

Use o link com /direct/ pra baixar o arquivo direto (evita redirecionamentos que quebram o wget):

cd /var/www

# Download direto (sem redirecionamentos)
wget -O moodle-5.1.1.tgz https://download.moodle.org/download.php/direct/stable501/moodle-5.1.1.tgz

# Extrair em pasta separada
tar -xzf moodle-5.1.1.tgz

# Renomear para moodle_new
mv moodle moodle_new

# Copiar config.php do site atual para a RAIZ (não em /public!)
cp /var/www/moodle_antigo/config.php /var/www/moodle_new/config.php

# Ajustar permissões (use seu usuário do webserver)
chown -R www-data:www-data /var/www/moodle_new

Passo 5: Mover plugins para dentro de /public

Essa é a parte que pega muita gente. No Moodle 5.1, plugins de terceiros precisam estar dentro da pasta /public. Se você tinha um tema em /theme/moove, agora ele vai pra /public/theme/moove.

# Ajuste os caminhos conforme seu ambiente
ATUAL="/var/www/moodle_antigo"
NOVO="/var/www/moodle_new"

# Temas (ex: Moove)
if [ -d "$ATUAL/theme/moove" ]; then
  cp -r "$ATUAL/theme/moove" "$NOVO/public/theme/"
fi

# Atividades (ex: mod_booking, mod_customcert)
for plugin in booking customcert; do
  if [ -d "$ATUAL/mod/$plugin" ]; then
    cp -r "$ATUAL/mod/$plugin" "$NOVO/public/mod/"
  fi
done

# Blocos
for plugin in completion_progress configurable_reports navbuttons; do
  if [ -d "$ATUAL/blocks/$plugin" ]; then
    cp -r "$ATUAL/blocks/$plugin" "$NOVO/public/blocks/"
  fi
done

# Formatos de curso
for plugin in tiles onetopic topicsactivitycards; do
  if [ -d "$ATUAL/course/format/$plugin" ]; then
    cp -r "$ATUAL/course/format/$plugin" "$NOVO/public/course/format/"
  fi
done

# Filtros
if [ -d "$ATUAL/filter/filtercodes" ]; then
  cp -r "$ATUAL/filter/filtercodes" "$NOVO/public/filter/"
fi

# Admin tools
for plugin in opcache redis copy_courses; do
  if [ -d "$ATUAL/admin/tool/$plugin" ]; then
    cp -r "$ATUAL/admin/tool/$plugin" "$NOVO/public/admin/tool/"
  fi
done

# Local plugins
if [ -d "$ATUAL/local/wunderbyte_table" ]; then
  cp -r "$ATUAL/local/wunderbyte_table" "$NOVO/public/local/"
fi

# Ajustar permissões de tudo
chown -R www-data:www-data "$NOVO"

Regra prática: se antes o plugin ficava em RAIZ/tipo/plugin, agora ele deve ficar em RAIZ/public/tipo/plugin.

Passo 6: Trocar as pastas (swap)

cd /var/www

# Renomear o antigo com data (para rollback)
mv moodle moodle_old_$(date +%Y%m%d)

# Colocar o novo no lugar
mv moodle_new moodle

# Verificar estrutura - deve ter /public e admin/cli na raiz
ls -la moodle/
ls -la moodle/public/
ls -la moodle/admin/cli/

Passo 7: Ajustar DocumentRoot para /public

🚨 Esse é o passo mais importante! O webserver precisa servir apenas a pasta /public, não a raiz do Moodle.

Apache (edite seu VirtualHost)

# Edite o arquivo do seu site (ex: /etc/apache2/sites-available/moodle.conf)

<VirtualHost *:443>
    ServerName seu-moodle.com.br
    DocumentRoot /var/www/moodle/public   # ← MUDOU AQUI
    
    <Directory /var/www/moodle/public>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>
# Ou usar sed para alterar automaticamente:
sed -i 's|DocumentRoot /var/www/moodle$|DocumentRoot /var/www/moodle/public|g' /etc/apache2/sites-available/moodle.conf
sed -i 's|Directory /var/www/moodle>|Directory /var/www/moodle/public>|g' /etc/apache2/sites-available/moodle.conf

# Testar config e reiniciar
apachectl configtest
systemctl reload apache2

Nginx

server {
    server_name seu-moodle.com.br;
    root /var/www/moodle/public;   # ← MUDOU AQUI
    
    # ... resto da config
}

# Testar e recarregar
nginx -t
systemctl reload nginx

Virtualmin/Webmin (passo a passo)

Se você usa Virtualmin, o processo é diferente — é tudo pelo painel:

  1. Acesse Virtualmin → Server Configuration → Website Options
  2. Em Document Root, altere de /home/usuario/public_html para /home/usuario/public_html/public
  3. Clique em Save
  4. Vá em Virtualmin → Server Configuration → PHP Options e confirme que está usando PHP 8.2+
  5. Se usar PHP-FPM, reinicie: systemctl restart php8.3-fpm

⚠️ Importante: NÃO coloque /public no $CFG->wwwroot! O wwwroot continua com a URL normal do site (ex: https://moodle.exemplo.com.br). O que muda é só o DocumentRoot do servidor.

Passo 8: Rodar o upgrade via CLI

✅ Importante: No Moodle 5.1, o CLI (admin/cli/) fica na RAIZ, não dentro de /public!

# CORRETO - CLI está na raiz do Moodle
sudo -u www-data php /var/www/moodle/admin/cli/upgrade.php --non-interactive

# Limpar cache após upgrade
sudo -u www-data php /var/www/moodle/admin/cli/purge_caches.php

⚠️ O comando upgrade.php NÃO coloca o site em manutenção automaticamente. Por isso você ativou no Passo 1. Isso é documentado oficialmente na documentação do CLI.

Passo 9: Desativar manutenção e reativar cron

# Desativar manutenção (CLI na raiz!)
sudo -u www-data php /var/www/moodle/admin/cli/maintenance.php --disable

# Criar novo cron otimizado para Moodle 5.1
# ⚠️ Use versão EXPLÍCITA do PHP (php8.3, não apenas "php")
cat <<'EOF' | crontab -u www-data -
# Cron principal (tarefas agendadas)
* * * * * flock -n /tmp/moodle_cron.lock /usr/bin/php8.3 /var/www/moodle/admin/cli/cron.php > /dev/null 2>&1

# Workers adhoc (processar fila de tarefas)
* * * * * flock -n /tmp/adhoc1.lock /usr/bin/php8.3 /var/www/moodle/admin/cli/adhoc_task.php --execute --keep-alive=55 > /dev/null 2>&1
* * * * * flock -n /tmp/adhoc2.lock /usr/bin/php8.3 /var/www/moodle/admin/cli/adhoc_task.php --execute --keep-alive=55 > /dev/null 2>&1
EOF

Passo 10: Testar o site

Acesse o site e faça login como admin. Verifique:

  • Administração do site → Notificações (ver se tem algo pendente)
  • Administração do site → Plugins (confirmar se todos apareceram)
  • Relatórios → Status do ambiente (deve estar tudo verde)
# Teste rápido via curl
curl -sI https://seu-moodle.com.br/ | head -5
# Deve retornar HTTP/1.1 200 OK

# Verificar versão no banco
mysql SEU_BANCO -e "SELECT value FROM mdl_config WHERE name='release';"
# Deve mostrar: 5.1.1

Erros Comuns Após Atualizar o Moodle 5.1 (e Como Corrigir)

Erro: Aparece listagem de diretório ou “Index of /”

Causa: DocumentRoot ainda aponta pra raiz do Moodle, não pra /public.

Solução: Edite o VirtualHost/config do Nginx e aponte pra .../public. Reinicie o webserver. Se usa Virtualmin, veja o Passo 7 acima.

Erro: Página em branco ou erro 500

Causa: PHP incompatível, extensão faltando (sodium), ou erro no config.php.

Solução: Verifique os logs do Apache/PHP:

# Apache (Debian/Ubuntu)
tail -50 /var/log/apache2/error.log

# PHP-FPM
tail -50 /var/log/php8.3-fpm.log

# Se não tiver arquivo de log, use journalctl:
journalctl -u php8.3-fpm -n 50 --no-pager

Confirme que PHP 8.2+ está ativo e a extensão sodium instalada: php -m | grep sodium

Erro: Cannot redeclare clean_string() (mod_booking)

🔴 Erro real encontrado em produção:

Fatal error: Cannot redeclare clean_string() 
(previously declared in /mod/booking/lib.php:2620) 
in /public/lib/weblib.php

Causa: O plugin mod_booking em versões antigas (antes de dezembro/2025) tinha uma função clean_string() que conflita com a função homônima do Moodle 5.1.

Solução:

  1. Mova temporariamente o plugin: mv public/mod/booking public/mod/booking.disabled
  2. Execute o upgrade: php admin/cli/upgrade.php
  3. Baixe a versão mais recente do mod_booking (2025121200 ou superior) em moodle.org/plugins/mod_booking
  4. Extraia e substitua a pasta booking
  5. Execute upgrade novamente para registrar o plugin

Erro: Plugins ou tema sumiram

Causa: Plugins ficaram na estrutura antiga (fora de /public).

Solução: Mova os plugins pro caminho equivalente dentro de /public/ (ex: /public/theme/moove). Depois limpe o cache:

# CLI na RAIZ, não em /public!
php /var/www/moodle/admin/cli/purge_caches.php

Erro: 404 em várias páginas

Causa: O Moodle 5.1 introduziu um novo Router. Em alguns ambientes, pode precisar de ajuste no .htaccess ou config do Nginx.

Solução: Consulte a documentação do Router.

Erro: read error on connection to Redis

Causa: O Redis pode ter ficado instável durante o upgrade ou com cache antigo.

Solução:

# Reiniciar Redis e limpar cache
systemctl restart redis-server
redis-cli FLUSHALL

# Limpar cache do Moodle
php /var/www/moodle/admin/cli/purge_caches.php

Como Fazer Rollback (Se Der Errado)

Se o upgrade deu problema grave e você precisa voltar, é rápido (por isso fizemos swap de pastas):

# 1) Identificar a pasta antiga (tem a data no nome)
ls -la /var/www/ | grep moodle_old

# 2) Voltar o código antigo
cd /var/www
rm -rf moodle
mv moodle_old_20260110 moodle   # ajuste o nome conforme a data

# 3) Voltar DocumentRoot (remover o /public)
sed -i 's|/var/www/moodle/public|/var/www/moodle|g' /etc/apache2/sites-available/moodle.conf
systemctl reload apache2

# 4) Se necessário, restaurar o banco
gunzip -c /root/backup_moodle_YYYYMMDD/moodle_db_backup.sql.gz | mysql SEU_BANCO

# 5) Desativar manutenção
php /var/www/moodle/admin/cli/maintenance.php --disable

# 6) Se voltou PHP, alterar VirtualHost também
sed -i 's/php8.3-fpm.sock/php8.1-fpm.sock/g' /etc/apache2/sites-available/moodle.conf
systemctl reload apache2

Perguntas Frequentes

O que é a pasta /public no Moodle 5.1?

A pasta /public é a nova estrutura do Moodle 5.1 que separa arquivos públicos (acessíveis via web) dos arquivos internos. Isso melhora a segurança porque o config.php fica fora do alcance do navegador.

Onde fica o admin/cli no Moodle 5.1?

O admin/cli/ fica na RAIZ do Moodle, NÃO dentro de /public. Isso é proposital para que os scripts CLI não fiquem acessíveis via web.

Preciso colocar /public no $CFG->wwwroot?

Não! O $CFG->wwwroot continua com a URL normal do site (ex: https://moodle.exemplo.com.br). O que muda é o DocumentRoot do webserver, que aponta pra pasta /public.

O upgrade via CLI coloca o site em manutenção automaticamente?

Não. Você precisa ativar manutenção manualmente antes (maintenance.php --enable) e desativar depois (maintenance.php --disable). Isso é documentado oficialmente.

Posso pular do Moodle 3.x direto para o 5.1?

Não diretamente. O Moodle 5.1 exige que você venha do 4.2.3 ou superior. Se estiver em versão mais antiga, precisa fazer upgrades intermediários primeiro (3.x → 4.2.3 → 5.1).

Por que meus plugins pararam de funcionar no Moodle 5.1?

Porque no Moodle 5.1 os plugins precisam estar dentro da pasta /public. Se ficaram no local antigo (fora de /public), o Moodle não carrega eles. Mova cada plugin pro caminho equivalente em /public/.

Qual a diferença entre $CFG->dirroot e DocumentRoot?

$CFG->dirroot é calculado automaticamente no Moodle 5.1 pelo setup.php — você não precisa definir manualmente. O DocumentRoot é o que o webserver serve pro navegador, que deve apontar pra /public.

O upgrade para o Moodle 5.1 é pago?

Não. O Moodle é Open Source (licença GPL) e 100% gratuito. Você não paga licença pra atualizar do 4.5 para o 5.1 — mas pode ter custos de servidor se precisar aumentar RAM ou atualizar PHP/MySQL pra atender os novos requisitos.

Qual a diferença do Moodle 4.5 LTS para o 5.1?

O 4.5 é LTS (Long Term Support) com suporte estendido de segurança até 2027. O 5.1 é versão nova com recursos modernos e a nova estrutura de pastas (/public), mas exige mudanças na infraestrutura como explicado neste tutorial.

Referências Oficiais

🎓 Profissional Linux? Certificação LPI em Breve!

Estamos preparando simulados para Linux Essentials e LPIC-1

Avatar de Jonas Oliveira
Jonas Oliveira é especialista em tecnologia e redator no TecMestre.