A Docker Compose setup for Moodle 4.5 development environment with MySQL 8.0, pre-installed plugins, and easy plugin management.
- Moodle 4.5 (built from official download)
- PHP 8.2 + Apache web server
- MySQL 8.0 database
- No Docker volumes - all data stored on host filesystem via path mappings
- 13 pre-installed plugins ready to use
- Easy plugin installation - add plugins without rebuilding the image
- Development-friendly - error reporting enabled, hot-reload support
- Docker Engine 20.10+
- Docker Compose 2.0+
- Git (for plugin installation)
-
Clone or navigate to this directory
-
Copy environment file
cp .env.example .env
-
Build and start the stack
docker compose up -d --build
-
Wait for containers to boot: the first time it might take several minutes for the containers to boot. Check
docker compose logs moodlefor details. When the container is started you will se the message:Moodle container started...Starting Apache.... -
Access Moodle
- Open your browser at: http://localhost:8080
-
Complete the Moodle installation wizard (if first time):
- The first three steps steps (Choose a language, Confirm paths, Choose database driver) can be left with the default values
- In the Database settings step, use the following values:
- Database host: mysql
- Database user: moodle
- Database password: moodle
- Finally, follow the instructions to complete the setup
- Login with admin credentials from
.envfile
The following plugins are pre-installed:
mod_choicegroup- Choice group activitymod_reservation- Reservation activity
block_course_status- Course status blockblock_qrcode- QR code block (v4.5-r1 for Moodle 4.5)block_user_cohorts- User cohorts block (install manually; no public repo found)
atto_teamsmeeting- Teams meeting integration for Atto editor
availability_ipaddress- IP address availability condition
report_allbackups- All backups report
theme_academi- Academi themetheme_boost_o365teams- Boost O365 Teams theme
local_cohort_profile- Cohort profilelocal_o365- Office 365 integrationlocal_office365- Office 365 local pluginlocal_reminders- Reminders plugin
-
Download or clone the plugin
# Example: Clone a plugin repository cd plugins git clone https://github.com/username/moodle-plugin_name.git plugin_name
-
Place plugin in correct directory structure
The plugin should be placed inplugins/directory. The entrypoint script will automatically detect and install it based on the plugin type:- Activity modules:
plugins/mod_pluginname/ - Blocks:
plugins/block_pluginname/ - Local plugins:
plugins/local_pluginname/ - Themes:
plugins/theme_pluginname/ - etc.
- Activity modules:
-
Restart the Moodle container
docker compose restart moodle
-
Install via Moodle admin
- Go to Site administration → Plugins → Install plugins
- Or use CLI:
docker compose exec moodle php admin/cli/upgrade.php --non-interactive
-
Access Moodle admin
- Login as administrator
- Navigate to Site administration → Plugins → Install plugins
-
Upload plugin ZIP file
- Upload the plugin ZIP file through the web interface
- Moodle will automatically install it
-
Copy plugin to appropriate directory
# Example for a block plugin cp -r plugin_directory moodle/blocks/pluginname -
Set permissions
docker compose exec moodle chown -R www-data:www-data /var/www/html/blocks/pluginname docker compose exec moodle chmod -R 755 /var/www/html/blocks/pluginname
-
Run Moodle upgrade
docker compose exec moodle php admin/cli/upgrade.php --non-interactive
moodle/
├── docker compose.yml # Docker Compose configuration
├── Dockerfile # Custom Moodle image
├── docker-entrypoint.sh # Container entrypoint script
├── install-plugins.sh # Plugin installation script
├── .env # Environment variables (create from .env.example)
├── .env.example # Example environment file
├── config.php.template # Moodle config template
├── README.md # This file
├── moodle/ # Moodle codebase (created on first run)
├── moodledata/ # Moodle data directory (created on first run)
├── mysql-data/ # MySQL data directory (created on first run)
└── plugins/ # Custom plugins directory (optional)
docker compose up -ddocker compose down# All services
docker compose logs -f
# Moodle only
docker compose logs -f moodle
# MySQL only
docker compose logs -f mysqldocker compose exec moodle bashdocker compose exec mysql mysql -u moodle -p moodle# Upgrade database
docker compose exec moodle php admin/cli/upgrade.php --non-interactive
# Purge caches
docker compose exec moodle php admin/cli/purge_caches.php
# Create admin user
docker compose exec moodle php admin/cli/create_admin_user.phpdocker compose build --no-cacheEdit .env file to customize:
MOODLE_URL- Moodle site URLMOODLE_PORT- Port for Moodle web interface (default: 8080)MOODLE_ADMIN_USER- Admin usernameMOODLE_ADMIN_PASSWORD- Admin passwordMYSQL_ROOT_PASSWORD- MySQL root passwordMYSQL_DATABASE- Database nameMYSQL_USER- Database userMYSQL_PASSWORD- Database passwordMYSQL_PORT- MySQL port (default: 3306)
If you need to update plugin repository URLs, edit install-plugins.sh and rebuild:
docker compose build --no-cache moodle
docker compose up -dIf port 8080 or 3306 is already in use (e.g. another MySQL instance), change them in .env:
MOODLE_PORT=8081
MYSQL_PORT=3307Then run docker compose down and docker compose up -d again.
If the installer reports that the data folder cannot be created: use /var/moodledata as the data directory path. A symlink from /var/www/moodledata to /var/moodledata is created automatically, and /var/www is made writable at container start.
If you encounter permission issues with moodledata:
sudo chown -R $(id -u):$(id -g) moodledata/
chmod -R 777 moodledata/- Check plugin compatibility with Moodle 4.4
- Verify plugin repository URLs in
install-plugins.sh - Check container logs:
docker compose logs moodle - Try installing plugin manually via Moodle admin interface
- Ensure MySQL container is healthy:
docker compose ps - Check MySQL logs:
docker compose logs mysql - Verify database credentials in
.envmatchconfig.php
To start fresh:
docker compose down -v
rm -rf moodle/ moodledata/ mysql-data/
docker compose up -d --build- Hot-reload: Changes to Moodle code in
moodle/directory are immediately reflected - Plugin development: Place plugins in
plugins/directory for automatic installation - Database access: Use MySQL client or phpMyAdmin container for database management
- Debug mode: PHP error reporting is enabled by default in this development setup
- Default passwords are weak
- Error reporting is enabled
- Database is exposed on port 3306
- Do NOT use this configuration in production
For production deployment:
- Use strong passwords
- Disable error reporting
- Use Docker secrets or environment variable management
- Restrict database access
- Use SSL/TLS encryption
- Follow Moodle security best practices
This Docker setup is provided as-is. Moodle and plugins have their own licenses.
For issues with:
- Moodle: https://moodle.org/support
- Docker setup: Check container logs and this README
- Plugins: Contact plugin maintainers