How To Install Moodle on Ubuntu

Install Moodle on Ubuntu

If you’re looking to build a scalable, self-hosted online learning platform, Moodle is one of the most powerful and widely used open-source Learning Management Systems (LMS) available today. Whether you’re an educator, IT administrator, or a startup building an e-learning product, knowing how to install Moodle on Ubuntu Linux is a foundational skill that gives you full control over your learning environment.

In this step-by-step guide, you will learn exactly how to install and configure Moodle on Ubuntu 22.04 LTS — from setting up the LAMP/LEMP stack, to securing your site with HTTPS via Let’s Encrypt, to completing the Moodle web installer. This tutorial is written by a Linux system administrator with hands-on experience deploying Moodle on production servers, ensuring every command you run has been tested and verified.

What Is Moodle and Why Install It on Ubuntu?

Moodle (Modular Object-Oriented Dynamic Learning Environment) is a free, open-source LMS used by over 400 million users across more than 240 countries worldwide. It enables educators to create feature-rich online classrooms with course management, quizzes, assignments, discussion forums, video embedding, and SCORM-compliant e-learning content.

Ubuntu Linux — particularly Ubuntu 22.04 LTS (Long-Term Support) — is the preferred server operating system for Moodle deployments because of its stability, extensive community support, and five-year security maintenance window. Running Moodle on Ubuntu gives you complete ownership of your data, eliminates recurring SaaS fees, and allows unlimited customization through Moodle’s plugin ecosystem.

Prerequisites Before You Begin

Before starting the installation, ensure you have the following ready:

  • A Ubuntu 22.04 LTS server — minimum 2 CPUs, 2 GB RAM, 40 GB SSD storage
  • A non-root sudo user — for secure command execution
  • A domain name (FQDN) — e.g., lms.yourdomain.com pointed to your server’s IP via DNS A record
  • SSH access — to connect and configure the server remotely
  • Open ports — HTTP (80) and HTTPS (443) must be allowed in your firewall

💡 Author’s Tip: Always snapshot or backup your server before beginning a major installation. If anything goes wrong, you can restore to a clean state in seconds — a habit that has saved countless production environments.

Step 1 — Update Your Ubuntu System

The first step is ensuring all system packages are up-to-date to avoid dependency conflicts and security vulnerabilities.

sudo apt update && sudo apt upgrade -y
sudo apt install curl wget git nano unzip -y

  • apt update refreshes the package list from repositories
  • apt upgrade -y installs all pending updates automatically
  • Additional tools like curl, wget, git, and nano are essential for the next steps

Step 2 — Configure the UFW Firewall

Moodle requires HTTP and HTTPS ports to function correctly. Open them using Ubuntu’s Uncomplicated Firewall (UFW):

sudo ufw allow http
sudo ufw allow https
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status

  • Always allow OpenSSH before enabling UFW to prevent locking yourself out of the server
  • Verify the status shows ports 80 and 443 as ALLOW

Step 3 — Install Nginx Web Server

While Apache is a valid alternative, Nginx offers better performance for concurrent connections, making it ideal for Moodle deployments with many simultaneous users.

sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring -y
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg arch=amd64] \
http://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list

sudo apt update
sudo apt install nginx -y
nginx -v

  • Install from the official Nginx repository (not the Ubuntu default) to get the latest stable version
  • Verify with nginx -v — you should see a version number like nginx/1.26.x

Step 4 — Install PHP and Required Extensions

Moodle is a PHP-based application and requires PHP 8.0 or higher along with a specific set of PHP extensions.

sudo add-apt-repository ppa:ondrej/php -y
sudo apt update
sudo apt install php8.1-fpm php8.1-cli php8.1-mysql php8.1-gd \
php8.1-curl php8.1-intl php8.1-mbstring php8.1-soap php8.1-xmlrpc \
php8.1-xml php8.1-zip php8.1-pspell php8.1-ldap graphviz aspell \
ghostscript clamav -y

Next, tune critical PHP settings in php.ini:

sudo nano /etc/php/8.1/fpm/php.ini

Find and update the following values:

memory_limit = 256M
max_input_vars = 5000
upload_max_filesize = 128M
post_max_size = 128M
session.auto_start = 0
allow_url_fopen = On
file_uploads = On

  • Setting max_input_vars = 5000 is mandatory for Moodle — without it, the installer will throw a PHP warning and certain course features may not work correctly
  • Restart PHP-FPM to apply changes: sudo systemctl restart php8.1-fpm

Step 5 — Install and Secure MySQL Database

Moodle stores all its data — users, courses, assignments, grades — in a MySQL or MariaDB relational database.

sudo apt install mysql-server -y
sudo mysql

Inside the MySQL shell, set a secure root password:

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'YourRootPassword!';
exit

Run the MySQL security hardening script:

sudo mysql_secure_installation

Answer the prompts as follows:

  • Set password validation to STRONG (2)
  • Remove anonymous users → Y
  • Disallow remote root login → Y
  • Remove test database → Y
  • Reload privilege tables → Y

Now create the Moodle database and user:

sudo mysql -u root -p

CREATE DATABASE moodledb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'moodleuser'@'localhost' IDENTIFIED BY 'SecureMoodlePass!';
GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,CREATE TEMPORARY TABLES,DROP,INDEX,ALTER
ON moodledb.* TO 'moodleuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;

  • Always use utf8mb4 character set and utf8mb4_unicode_ci collation to ensure full Unicode, emoji, and multilingual content support in Moodle courses

Step 6 — Download and Install Moodle

Create the Moodle web root directory and download the latest stable release using Git:

sudo mkdir -p /var/www/html/moodle
sudo chown -R $USER:$USER /var/www/html/moodle
cd /var/www/html/moodle
git clone https://github.com/moodle/moodle.git .
git branch -a
git branch --track MOODLE_403_STABLE origin/MOODLE_403_STABLE
git checkout MOODLE_403_STABLE

Create the Moodle data directory outside the web root for security:

sudo mkdir -p /var/moodledata
sudo chown -R nginx /var/moodledata
sudo chmod -R 775 /var/moodledata
sudo chmod -R 755 /var/www/html/moodle

  • Storing moodledata outside the web root (/var/www/html/) is a critical security best practice — it prevents direct browser access to uploaded files and session data

Step 7 — Configure Moodle’s config.php

Copy the sample configuration file and configure it for your server:

cd /var/www/html/moodle
cp config-dist.php config.php
sudo nano config.php

Edit the following lines to match your environment:

$CFG->dbtype    = 'mysqli';
$CFG->dbhost    = 'localhost';
$CFG->dbname    = 'moodledb';
$CFG->dbuser    = 'moodleuser';
$CFG->dbpass    = 'SecureMoodlePass!';
$CFG->prefix    = 'mdl_';
$CFG->wwwroot   = 'https://lms.yourdomain.com';
$CFG->dataroot  = '/var/moodledata';

Save with Ctrl+XYEnter.

Step 8 — Install SSL Certificate with Let’s Encrypt

A valid HTTPS certificate is essential for protecting login credentials and complying with modern browser security standards.

sudo snap install core && sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

sudo certbot certonly --standalone --agree-tos --no-eff-email \
--staple-ocsp --preferred-challenges http \
-m [email protected] -d lms.yourdomain.com

Generate a Diffie-Hellman parameter for enhanced encryption strength:

sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096

Configure auto-renewal by editing the Certbot renewal config:

sudo nano /etc/letsencrypt/renewal/lms.yourdomain.com.conf

Add at the bottom of the file:

pre_hook = systemctl stop nginx
post_hook = systemctl start nginx

Test renewal with: sudo certbot renew --dry-run

Step 9 — Configure Nginx for Moodle

Create the Nginx server block for Moodle with HTTPS and HTTP-to-HTTPS redirect:

sudo nano /etc/nginx/conf.d/moodle.conf

Paste the following configuration (replace lms.yourdomain.com with your actual domain):

server {
    listen 80; listen [::]:80;
    server_name lms.yourdomain.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2; listen [::]:443 ssl http2;
    server_name lms.yourdomain.com;
    root /var/www/html/moodle;
    index index.php;

    ssl_certificate /etc/letsencrypt/live/lms.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/lms.yourdomain.com/privkey.pem;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_session_cache shared:MozSSL:10m;
    ssl_session_tickets off;

    client_max_body_size 100M;
    autoindex off;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location /dataroot/ {
        internal;
        alias /var/moodledata/;
    }

    location ~ ^(.+\.php)(.*)$ {
        fastcgi_split_path_info ^(.+\.php)(.*)$;
        fastcgi_pass unix:/run/php/php8.1-fpm.sock;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }

    location ~ (/vendor/|/node_modules/|composer\.json|/readme|/README|/upgrade\.txt|phpunit\.xml) {
        deny all;
        return 404;
    }
}

Verify the configuration and restart Nginx:

sudo nginx -t
sudo systemctl restart nginx

Step 10 — Complete the Moodle Web Installer

Open your browser and navigate to https://lms.yourdomain.com. The Moodle setup wizard will launch automatically. Follow these steps:

  1. Choose Language → Select your preferred language → Click Next
  2. Confirm Paths → Verify web root and data directory paths → Click Next
  3. Database Settings → Select MySQL (native/mysqli) → Enter database name, user, and password → Click Next
  4. Accept License → Read and accept the GPL license → Click Continue
  5. Server Checks → All environment checks must show OK → Click Continue
  6. Database Installation → Moodle installs tables (this may take 2–5 minutes) → Click Continue
  7. Create Admin Account → Set username, strong password, email address → Click Update Profile
  8. Site Settings → Enter full site name, short name, and timezone → Click Save Changes

You will be redirected to the Moodle dashboard — your LMS is now live.

Step 11 — Enable the Moodle Cron Job

Moodle relies on a scheduled cron job for automated tasks such as sending email notifications, processing assignment submissions, generating reports, and running backups.

crontab -e -u www-data

Add this line:

* * * * * /usr/bin/php /var/www/html/moodle/admin/cli/cron.php > /dev/null

This runs the Moodle cron every minute, which is the recommended interval for production deployments.

Troubleshooting Common Issues

Issue Cause Fix
White screen after installer PHP max_input_vars too low Set max_input_vars = 5000 in php.ini
502 Bad Gateway PHP-FPM not running sudo systemctl restart php8.1-fpm
Permission denied on moodledata Wrong ownership sudo chown -R nginx /var/moodledata
SSL certificate not found Certbot path mismatch Verify path in nginx.conf matches /etc/letsencrypt/live/
Cron not running Cron user mismatch Ensure cron is set under www-data user

Marshall Anthony is a professional Linux DevOps writer with a passion for technology and innovation. With over 8 years of experience in the industry, he has become a go-to expert for anyone looking to learn more about Linux.

Related Posts