Installing Moodle is more than copying files - it means assembling a fully compatible web stack, securing data paths, and wiring background services so the LMS stays healthy from day one. You'll spend 2-4 hours configuring servers, another hour debugging permissions, and countless hours maintaining security patches afterward.
If you'd rather launch courses quickly than spend days fighting infrastructure, MooDIY Cloud provisions production-ready Moodle with Redis caching, automated cron, and proactive security updates. But if you need to understand the manual process - whether to evaluate hosting complexity or run your own stack - this playbook shows you exactly what professional installation entails.
Why One-Click Installers Fall Short
One-click installers (Softaculous, cPanel) often deliver "barely-functional" installations that create long-term technical debt:
- Security Risks: Data directories are often placed inside the web root; insecure permissions (chmod 777).
- Performance Issues: OPcache and Redis caching are rarely configured; memory limits are set too low (128M vs. the required 512M).
- Version Lag: Installers often trail official releases by many months, missing critical security patches.
One-click installers may work for short-term testing (48-hour prototypes). But in production environments with real users, cleanup and fixes often take longer than a proper manual setup -- and introduce technical debt from the start.
1. Pre-Flight: Verify Your Stack
Moodle 5.2 has strict requirements. If you're on older Ubuntu or PHP versions, expect to spend 1-2 hours upgrading your stack before starting the installation.
| Component | Minimum for Moodle 5.2 | Recommended for production |
|---|---|---|
| OS | 64-bit Linux (Ubuntu 22.04+/RHEL 9+) | Managed Linux server with automatic security updates |
| Web server | Apache 2.4 or Nginx 1.18+ | Nginx + PHP-FPM for better concurrency |
| PHP | 8.3 minimum with required Moodle extensions such as intl, sodium, curl, opcache, zip, mbstring, soap, gd, fileinfo, json, xml, and ctype | Tune memory_limit=512M, max_input_vars=5000, opcache.enable=1 |
| Database | MariaDB 10.11+, MySQL 8.4+, PostgreSQL 16+, or MSSQL 2019+ | Dedicated database host with UTF8MB4 default |
| Hardware | 2 vCPU / 4 GB RAM / 20 GB SSD (starter) | Scale CPU + RAM based on concurrency; use NVMe storage |
Note: Moodle 5.0/5.1 used PHP 8.2 as the floor, but Moodle 5.2 raised the current install baseline to PHP 8.3. Oracle Database support ended with Moodle 5.0. If you're currently running Moodle on Oracle, you must migrate to MariaDB, MySQL, PostgreSQL, or MSSQL before upgrading to 5.x.
2. Install the Professional Way (Manual + CLI)
Time Budget: 2-4 hours for first-time installation (experienced admins: 1-2 hours)
Step 1: Create the Moodle Codebase
Via Git (recommended for easier updates):
git clone -b MOODLE_502_STABLE https://github.com/moodle/moodle.git /var/www/moodleOr download the latest .tgz/.zip from moodle.org/downloads and extract:
cd /var/www
tar -xzf moodle-latest-502.tgzSet ownership to match your web server user:
chown -R www-data:www-data /var/www/moodleWeb users vary by distribution (e.g., www-data for Ubuntu/Debian, apache/nginx for RHEL/CentOS ). Incorrect ownership causes 20-30 minutes of permission errors.
Moodle 5.1+ Critical Change: Public Folder Structure
Moodle 5.1 introduced a major architectural change that affects web server configuration. The codebase now uses a /public directory as the web root, similar to how Laravel and other modern PHP frameworks work. This means your web server (Apache or Nginx) must point to /var/www/moodle/public instead of /var/www/moodle.
Nginx configuration change:
# Before (Moodle 5.0 and earlier):
root /var/www/moodle;
# After (Moodle 5.1+):
root /var/www/moodle/public;Apache configuration change:
# Before (Moodle 5.0 and earlier):
DocumentRoot /var/www/moodle
# After (Moodle 5.1+):
DocumentRoot /var/www/moodle/publicThis improves security by keeping application code outside the browser-accessible directory. Missing this change causes blank pages/404 errors. Moodle 5.1 also introduced a new routing engine, so URL rewrite rules from older versions may need updating.
Step 2: Provision the Database
Create database with utf8mb4 (required for emoji and full Unicode support):
CREATE DATABASE moodle CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'moodleuser'@'localhost' IDENTIFIED BY 'superSecretPassword';
GRANT ALL PRIVILEGES ON moodle.* TO 'moodleuser'@'localhost';
FLUSH PRIVILEGES;Step 3: Create a Secure moodledata Directory
Place outside web root (critical for security):
mkdir /var/moodledata
chmod 770 /var/moodledata
chown www-data:www-data /var/moodledataWhy this matters: moodledata stores uploaded files, session data, and caches. If accessible via browser, attackers can download student assignments, extract session tokens, or execute uploaded PHP files.
Step 4: Configure config.php
Copy the distribution template:
cp /var/www/moodle/config-dist.php /var/www/moodle/config.phpEdit critical settings:
$CFG->dbtype = 'mariadb';
$CFG->dblibrary = 'native';
$CFG->dbhost = 'localhost';
$CFG->dbname = 'moodle';
$CFG->dbuser = 'moodleuser';
$CFG->dbpass = 'superSecretPassword';
$CFG->prefix = 'mdl_';
$CFG->wwwroot = 'https://moodle.example.com';
$CFG->dataroot = '/var/moodledata';
$CFG->directorypermissions = 02770;Step 5: Run the Command-Line Installer
Use CLI to avoid browser timeouts:
php /var/www/moodle/admin/cli/install.php \
--wwwroot=https://moodle.example.com \
--dataroot=/var/moodledata \
--dbtype=mariadb \
--dbhost=localhost \
--dbname=moodle \
--dbuser=moodleuser \
--dbpass=superSecretPassword \
--fullname="Example LMS" \
--shortname="example" \
--adminuser=admin \
--adminpass='Complex#Pass123' \
--adminemail=admin@example.com \
--agree-license \
--non-interactiveThis installs all database tables, configures default roles, installs core plugins, and writes final config.php settings. Expect 3-5 min on modern hardware or 10+ min on a budget VPS.
3. Post-Install Essentials (Another 1-2 Hours)
Your Moodle is installed but not production-ready. These configurations separate working installations from reliable production systems.
Configure Cron (Required, Not Optional)
Add to system crontab:
* * * * * www-data /usr/bin/php /var/www/moodle/admin/cli/cron.php >/dev/nullOr use crontab -e for the web user:
sudo -u www-data crontab -eWhat breaks without cron:
- Assignment notifications never send
- Gradebook calculations freeze mid-process
- Forum digests pile up unsent
- Temporary files accumulate, filling storage
- Background course backups never run
- User enrollments don't synchronize
Test with: sudo -u www-data /usr/bin/php /var/www/moodle/admin/cli/cron.php and verify output shows tasks executing.
Configure Caching (Critical for Performance)
Navigate to: Site administration -> Plugins -> Caching -> Configuration
Set up Redis or Memcached:
- Install Redis:
apt install redis-server php-redis(15-20 minutes including testing) - Configure Moodle to use Redis for sessions and application cache
- Restart PHP-FPM:
systemctl restart php8.3-fpm
Performance impact: Redis caching reduces database queries by 60-80%, cutting page load time from 2-3 seconds to under 1 second. Without it, your database handles all session storage -- with 100+ concurrent users, the site will noticeably slow down.
Set Up Email Delivery
Configure SMTP (Site administration -> Server -> Email):
- Use a transactional email service (Amazon SES, SendGrid, Mailgun)
- Avoid
mail()function - it lands in spam 80% of the time - Test with Site administration -> Development -> Email test
What breaks without reliable email:
- Password reset links never arrive
- Students miss assignment deadlines (no notifications)
- Admin alerts about disk space/failures go nowhere
Many VPS providers block port 25 by default. You'll spend 30-60 minutes troubleshooting why emails "silently fail" before discovering you need SMTP relay with authentication.
Lock Down the Stack (Security Hardening)
Essential security steps (budget 1-2 hours):
Force HTTPS: Add to config.php:
php$CFG->wwwroot = 'https://moodle.example.com'; $CFG->sslproxy = true;Enable firewall:
bashufw allow 22/tcp ufw allow 80/tcp ufw allow 443/tcp ufw enableSchedule automatic security updates (Ubuntu):
bashapt install unattended-upgrades dpkg-reconfigure -plow unattended-upgradesRestrict file permissions:
bashfind /var/www/moodle -type f -exec chmod 644 {} \; find /var/www/moodle -type d -exec chmod 755 {} \;Remove test files: Delete
phpinfo.php, sample scripts, and install files outside web root
4. The Real Cost: DIY vs. Managed (Time & Money)
| Task | DIY Time Investment | Managed (MooDIY) |
|---|---|---|
| Initial Installation | 2-4 hours (first time) | 8 minutes automated provisioning |
| Troubleshooting | 1-3 hours (permissions, cron, email) | Zero - stack pre-configured |
| Security Hardening | 1-2 hours initial, ongoing monitoring | Included - proactive patches |
| Caching Setup | 1-2 hours (Redis config + testing) | Included - Redis pre-installed |
| SSL Certificate | 30-60 min (Let's Encrypt + renewal) | Included - automatic renewal |
| Backup Configuration | 2-3 hours (setup + offsite storage) | Included - daily offsite backups |
| Monthly Maintenance | 3-5 hours (updates, monitoring, optimization) | Included in subscription |
| First Year Total | 40-80 hours of admin time | 8 minutes + zero ongoing admin |
Cost calculation example (500-user deployment):
- DIY on VPS: $60/month VPS + $50/month backup storage + 5 hours/month admin time x $75/hour loaded cost = $435/month ($5,220/year)
- MooDIY Managed: $200-300/month all-inclusive = $2,400-3,600/year
- Savings: $1,600-2,800/year plus zero weekend emergencies
Source checked May 2026: Moodle latest download and requirements and Moodle release support table.
5. Why MooDIY Cloud Eliminates Installation Complexity
MooDIY Cloud provisions production-ready Moodle within minutes - not "technically functional" installations, but production-grade infrastructure that handles day-one traffic and scales to exam-day peaks.
What You Get in Few Minutes
Automated stack provisioning:
- Nginx + PHP-FPM 8.2 (or 8.3/8.4) with all required extensions pre-configured
- MariaDB or PostgreSQL with UTF8MB4, optimized buffer pools, and query caching
- Redis caching for sessions and application data (reduces database load by 5x)
- Let's Encrypt SSL with automatic renewal
- Cron configured and monitored (we alert if tasks fail)
Security baked in:
moodledataoutside web root with correct permissions- OS-level firewall configured
- Automated security patching (kernel, PHP, database) without downtime
- Daily offsite backups with 30-day retention
- Intrusion detection and DDoS protection
Performance optimizations:
- OPcache enabled and tuned for Moodle workloads
- PHP-FPM workers scaled to your concurrency requirements
- Database connection pooling
- CDN integration for static assets
- NVMe storage with automatic scaling
The MooDIY Difference: Specifics, Not Promises
- Concurrency-ready architecture: Designed to support typical LMS peak usage scenarios (e.g., ~20% concurrent users), with load testing available
- Performance optimization: Configured to deliver fast page loads under real course conditions, with monitoring tools for visibility
- 99.9% uptime SLA: Backed by service credits under defined SLA terms
- Managed updates with staging: Updates scheduled to minimize disruption, with staging environments for safe testing before production rollout
When DIY Makes Sense vs. When Managed Wins
Stick with DIY if:
- You already employ full-time Linux/PHP/database admins
- You need deep server customization for regulatory compliance
- You're running specialized research infrastructure alongside Moodle
- Your organization forbids cloud hosting for data sovereignty reasons
Choose MooDIY Cloud if:
- You want instructional designers focused on courses, not server maintenance
- You need predictable monthly costs instead of surprise admin time
- Exam-day reliability matters more than saving $100/month on hosting
- You would rather spend 8 minutes provisioning than 40 hours installing + maintaining
Related guides: Once installed, learn how to use Moodle effectively, explore the best plugins to extend your instance, or understand Moodle performance optimization.
