Versioned multi-architecture Moodle images for development and self-hosting.
9.9K

Versioned, multi-architecture Moodle images for local development and self-hosted deployments. Images are published to GitHub Container Registry and Docker Hub.
Caution
The `latest` tag now tracks Moodle 5.2, not the historical Moodle 3.x image. Existing installations must pin `3.11` before pulling, or follow the [staged upgrade guide](https://github.com/42ae/moodle-docker/blob/master/UPGRADING.md). Never upgrade a production database without a tested backup and plugin-compatibility review.
| Moodle | PHP | Status | Tags |
|---|---|---|---|
| 3.11.18 | 8.0 | Legacy/EOL; upgrade compatibility only | 3.11.18, 3.11, 3, legacy-3.11 |
| 4.1.22 | 8.1 | Legacy/EOL; upgrade bridge only | 4.1.22, 4.1, legacy-4.1 |
| 4.5.13 | 8.3 | LTS, security fixes | 4.5.13, 4.5, 4, lts |
| 5.2.2 | 8.4 | Current stable | 5.2.2, 5.2, 5, latest |
Use a full version tag for reproducible production deployments. Series tags are convenient but can move to newer point releases after rebuilds.
cp .env.example .env
# Replace every example password in .env before exposing this stack.
docker compose up -d
Open http://localhost:8080. The first visit starts Moodle's web installer. The Compose stack includes MySQL 8.4 and a separate Moodle cron service; phpMyAdmin is optional:
docker compose --profile tools up -d
Set MOODLE_VERSION in .env, then pull and start the stack:
MOODLE_VERSION=4.5
docker compose pull
docker compose up -d
Supported choices include 3.11, 4.1, 4.5, and 5.2. Changing the value on an existing installation is an upgrade, not a downgrade or a fresh selection; follow the upgrade guide.
GitHub Container Registry is the default. To use Docker Hub instead:
MOODLE_IMAGE=aesr/moodle
The image supports the following environment variables. If any Moodle configuration variable is provided and config.php is absent, the entrypoint creates a minimal cross-version configuration file.
| Variable | Default | Purpose |
|---|---|---|
MOODLE_DB_HOST | database | MySQL/MariaDB hostname |
MOODLE_DB_PORT | 3306 | Database port |
MOODLE_DB_NAME | moodle | Database name |
MOODLE_DB_USER | moodle | Database user |
MOODLE_DB_PASSWORD | empty | Database password |
MOODLE_DB_PREFIX | mdl_ | Table prefix |
MOODLE_WWW_ROOT | http://localhost:8080 | Public Moodle URL |
MOODLE_DATA_ROOT | /var/www/moodledata | Private writable data directory |
MOODLE_REVERSE_PROXY | false | Trust a reverse proxy |
MOODLE_SSL_PROXY | false | TLS terminates at a trusted proxy |
MOODLE_CRON_INTERVAL | 60 | Cron-sidecar interval in seconds |
Every variable also accepts Docker secret syntax through a matching _FILE variable, such as MOODLE_DB_PASSWORD_FILE=/run/secrets/moodle_db_password. Do not set both forms for the same variable.
The entrypoint configures Moodle; it deliberately does not create databases. Provision the database separately or use the included Compose stack.
Only database data and moodledata are persisted by the supplied Compose file:
db_data stores MySQL files.moodle_data stores uploads, caches, and generated application data.Moodle core remains inside the immutable image. Do not mount a volume over /var/www/html; doing so hides the versioned code and makes upgrades difficult to reproduce. Back up both the database and moodledata, and test restores regularly. See the upgrade guide for example backup and upgrade commands.
For repeatable deployments, build a derived image and pin its base to a full version:
FROM ghcr.io/42ae/moodle:5.2.2
COPY --chown=www-data:www-data local/myplugin/ /var/www/html/local/myplugin/
COPY --chown=www-data:www-data theme/mytheme/ /var/www/html/theme/mytheme/
Targeted read-only mounts can be useful for local development, but a derived image is safer for production. Install additional PHP extensions in the derived image when a plugin requires them.
Run a one-off Moodle CLI command with the web service:
docker compose exec --user www-data moodle php admin/cli/maintenance.php --enable
docker compose exec --user www-data moodle php admin/cli/upgrade.php --non-interactive
docker compose exec --user www-data moodle php admin/cli/maintenance.php --disable
The cron service runs admin/cli/cron.php continuously at MOODLE_CRON_INTERVAL. To run cron once:
docker compose exec --user www-data moodle php admin/cli/cron.php
Version metadata and verified upstream SHA-256 values live in versions.json. For example:
docker build \
--build-arg MOODLE_VERSION=5.2.2 \
--build-arg PHP_VERSION=8.4 \
--build-arg MOODLE_BRANCH=502 \
--build-arg MOODLE_SHA256=72be209e7c0f5341b87de0bc993b2430087fda2769d8c3cc2f32736d1513e88c \
--build-arg APACHE_DOCUMENT_ROOT=/var/www/html/public \
-t moodle:local .
moodledata.Issues and contributions are welcome in the 42ae/moodle-docker repository.
Content type
Image
Digest
sha256:6332c6873…
Size
276.2 MB
Last updated
16 days ago
docker pull aesr/moodle