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

  1. Clone Moodle

    git clone -b MOODLE_501_STABLE https://github.com/moodle/moodle.git moodle
    
  2. Create data directory

    mkdir moodledata
    
  3. Create database

    CREATE DATABASE moodle DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    
  4. Create config.php (see above)

  5. Link to Herd (from public folder!)

    cd moodle/public
    herd link moodle
    herd secure moodle
    
  6. Run CLI installer

    cd moodle
    php admin/cli/install_database.php --adminpass=YourPassword123! --agree-license [email protected] --fullname="Moodle LMS" --shortname="Moodle"
    
  7. Purge caches

    php admin/cli/purge_caches.php
    
  8. 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