moodle-herd-installer
Install and configure Moodle LMS on Laravel Herd (Windows/Mac). Use this skill when: - User wants to install Moodle on Herd/Valet - User mentions "moodle" + "herd" or "valet" - Troubleshooting Moodle CSS/JS not loading on Herd - Moodle showing "Unexpected token '<'" errors - ERR_CONTENT_DECODING_FAILED errors with Moodle
Moodle Installation on Laravel Herd
Overview
Moodle 5.x has a new directory structure with a public/ folder as the web root. This requires specific configuration to work correctly with Laravel Herd/Valet.
Key Requirements
1. Directory Structure (Moodle 5.x)
moodle/
├── config.php # Main config (stays in root)
├── config-dist.php # Distribution config template
├── lib/ # Legacy lib (migration helper)
│ └── setup.php # Redirects to public/lib/setup.php
└── public/ # WEB ROOT - Herd must point here!
├── config.php # Loader that requires ../config.php
├── lib/ # Actual library files
├── theme/ # Theme files
├── admin/ # Admin interface
└── login/ # Login page
2. Herd Link Command
# IMPORTANT: Link from the PUBLIC folder, not root!
cd D:\Project\<project>\moodle\public
herd link moodle
# Enable HTTPS
herd secure moodle
3. Critical Config Settings
Create config.php in the root moodle folder (NOT in public):
<?php
unset($CFG);
global $CFG;
$CFG = new stdClass();
// Database
$CFG->dbtype = 'mariadb'; // Use 'mariadb' for MariaDB, 'mysqli' for MySQL
$CFG->dblibrary = 'native';
$CFG->dbhost = '127.0.0.1';
$CFG->dbname = 'moodle';
$CFG->dbuser = 'root';
$CFG->dbpass = '';
$CFG->prefix = 'mdl_';
$CFG->dboptions = [
'dbpersist' => false,
'dbsocket' => false,
'dbport' => '3306', // Or 3307 for Herd's MariaDB
'dbcollation' => 'utf8mb4_unicode_ci',
];
// URLs
$CFG->wwwroot = 'https://moodle.test'; // Use HTTPS!
// CRITICAL: Point to public folder for Moodle 5.x
$CFG->dirroot = __DIR__ . '/public';
$CFG->libdir = __DIR__ . '/public/lib';
// Data directory (outside web root)
$CFG->dataroot = 'D:\\Project\\<project>\\moodledata';
$CFG->directorypermissions = 02777;
$CFG->admin = 'admin';
// Timezone
date_default_timezone_set('Asia/Jakarta');
// CRITICAL: Disable slash arguments for Herd/Nginx compatibility
$CFG->slasharguments = false;
// Production mode
$CFG->themedesignermode = false;
$CFG->cachejs = true;
$CFG->langstringcache = true;
$CFG->debugdisplay = 0;
$CFG->debug = 0;
require_once(__DIR__ . '/lib/setup.php');
4. Nginx Config for Moodle (Optional - Custom)
If default Herd config doesn't work, add gzip off; to the site config:
File: C:\Users\<user>\.config\herd\config\valet\Nginx\moodle.test.conf
Add after http2 on;:
# Disable gzip for Moodle (it handles its own compression)
gzip off;
Then restart: herd restart nginx
Installation Steps
-
Clone Moodle
git clone -b MOODLE_501_STABLE https://github.com/moodle/moodle.git moodle -
Create data directory
mkdir moodledata -
Create database
CREATE DATABASE moodle DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -
Create config.php (see above)
-
Link to Herd (from public folder!)
cd moodle/public herd link moodle herd secure moodle -
Run CLI installer
cd moodle php admin/cli/install_database.php --adminpass=YourPassword123! --agree-license [email protected] --fullname="Moodle LMS" --shortname="Moodle" -
Purge caches
php admin/cli/purge_caches.php -
Access: https://moodle.test
Common Issues & Solutions
CSS/JS Not Loading (Unstyled Page)
Symptoms:
- Page loads but looks unstyled
- Console shows:
Unexpected token '<' - JS files return HTML instead of JavaScript
Cause: Slash arguments not working with Herd/Nginx
Solution: Add to config.php:
$CFG->slasharguments = false;
ERR_CONTENT_DECODING_FAILED
Symptoms:
- CSS/JS files fail with encoding error
- Browser shows gzip decode failed
Cause: Nginx gzip conflicts with Moodle's compression
Solution: Disable gzip in site config:
gzip off;
"Undefined property: stdClass::$libdir"
Cause: dirroot pointing to wrong folder
Solution: Ensure config.php has:
$CFG->dirroot = __DIR__ . '/public';
$CFG->libdir = __DIR__ . '/public/lib';
Database Connection Issues
For MariaDB (Herd default):
$CFG->dbtype = 'mariadb'; // NOT 'mysqli'
Check port:
$CFG->dboptions['dbport'] = '3307'; // Herd uses 3307
Development Mode
To enable development mode (slower but no caching):
$CFG->themedesignermode = true;
$CFG->cachejs = false;
$CFG->langstringcache = false;
$CFG->debugdisplay = 1;
$CFG->debug = E_ALL;
Remember to purge caches after changing modes:
php admin/cli/purge_caches.php