Upgrading¶
How to move between Moodle versions safely.
The basics¶
The image applies Moodle database upgrades automatically on startup unless you opt out:
Steps the container takes on start, when an existing installation is detected:
admin/cli/maintenance.php --enableadmin/cli/upgrade.php --non-interactive --allow-unstableadmin/cli/maintenance.php --disable
This covers database schema upgrades. It does not by itself swap out the Moodle PHP code — that depends on how you handle the /var/www/html volume.
Upgrading the Moodle code¶
Your upgrade procedure depends on whether you persist /var/www/html as a named volume.
The container replaces the Moodle code on every start. Upgrading is just:
Trade-off: plugins and themes must be re-installed on every boot (use POST_CONFIGURE_COMMANDS with Moosh).
Pinned Moodle code in a persistent volume will not be overwritten when you change the image tag (#102). You will see logs like:
To actually upgrade:
- Back up the database,
moodledata, andmoodlehtml(see Persistence & Volumes). - Put the site into maintenance mode (optional but recommended).
-
Stop the stack and remove the
moodlehtmlvolume: -
Change the image tag in
docker-compose.yml: -
Bring it back up:
-
Reinstall any custom plugins and themes.
Always back up first
Upgrades that involve removing volumes are irreversible. Take a database dump and a tarball of moodledata before you run docker volume rm.
Upgrading from Moodle < 5.1 to ≥ 5.1¶
Moodle 5.1 introduces a public/ subdirectory for all web-exposed files (MDL-83424). The container handles this automatically: when it detects /var/www/html/public, it rewrites the Nginx root and runs composer install --no-dev --classmap-authoritative.
Recommended upgrade flow:
- Back up:
config.php- the
moodledatavolume - the database
- Stop the stack and remove the
moodlehtmlvolume (as above) — this is essential because the old 5.0 layout will otherwise confuse the new server config. - Change the image tag to a
5.1.x(or newer) release. - Start the stack. The container installs the new code, serves it from
/public, and runscomposer install. - Reapply customisations (plugins, themes,
config.phptweaks).
If you see "/var/www/html/vendor/composer does not exist" (#117), the container has not finished bootstrapping yet. Watch docker compose logs -f moodle — the error is transient unless it recurs after 30+ seconds.
Upgrading moodledata mounted from an older installation¶
Mounting an existing populated moodledata from a different image (for example migrating from Bitnami) can hit permission or layout mismatches (#114, #105):
Checklist:
- The volume must be writable by UID
65534(nobody). Fix withsudo chown -R 65534:65534 moodledata. config.phpon the new container must match the database — mount it alongside or inject it viaPOST_CONFIGURE_COMMANDS.- The target Moodle version must be equal to or newer than the version that created the data.
For a full Bitnami migration see #105. In short: restore the database first, mount moodledata second, ensure the admin credentials in config.php match the database, then start the container.
Disabling automatic upgrades¶
Set AUTO_UPDATE_MOODLE=false if you prefer to run admin/cli/upgrade.php manually:
Manual upgrade:
docker compose exec moodle php admin/cli/maintenance.php --enable
docker compose exec moodle php admin/cli/upgrade.php --non-interactive
docker compose exec moodle php admin/cli/maintenance.php --disable
Skipping versions¶
Moodle's upgrade scripts support skipping minor versions but you should not jump across multiple major versions in one go. Upgrade step by step (for example 4.1 → 4.5 → 5.0 → 5.1), backing up between each step.