Step-by-step Installation Guide for Ubuntu
Read this before installation
Moodle on a Ubuntu based VPS can be a production server or the path towards learning how to install and maintain a Linux production Moodle. A Linux VPS is not for everyone and without basic Linux administration skills, you will have difficulties.
Alternatives to a Moodle VPS which might suit you better are:
- Mount Orange is a demo site where you can try Moodle in a real-school environment as a manager, teacher, student, parent or privacy officer
- Moodlecloud which allows you to have your own Moodle and focus on using Moodle to create courses.
- Moodle Partners offer specialized support, customization, and services for organizations that need a more tailored experience.
Prerequisites
- Newly installed Ubuntu 24.10 Server with root access. A desktop GUI is not required.
- Know the server IP address
- Able to log in or ssh to your Ubuntu server
Recommended
- A Domain name (eg MyMoodle123.com) as this guide can only set up a https encrypted connection for sites with a domain name. The encrypted https protocol is an essential security feature for any Moodle where students are expected to submit work and getting a domain before you install Moodle will save you work later. Using an IP address (4 numbers separated by dots) is fine for a learning Moodle for your own use.
- A notebook to write down passwords
Database Root password
- Root password is initially empty. If you are using a domain name with the https protocol, the database will be secured.
- Installing to a domain, you will be told the root password during the installation process, Write it down! A forgotten password will give you problems later,
- If you are installing to an IP address, your database will not be secured and the password remains empt
How to install
- Copy each step onto the prompt of your Ubuntu server.
- Some steps may produce many lines of output and take several minutes to finish and return to the prompt.
- Each block of code has a start and end comment to remind you to copy all the lines in each step. You can copy lines starting with a #
- You do not need to change any of the lines on this page before copying them.
- You will be asked for your domain name (mymoole123.com). You can use an IP address if you do not have one.
- The Ubuntu update process may also ask you to make choices. Enter the default values.
Steps
# Step 1 Get all packages needed. if the web address is valid, apply firewall
#Start copy here as you need to copy each step as one block, not line by line.
read -p "Enter the web address (without the http:// prefix, example: mymoodle123.com): " WEBSITE_ADDRESS
if ping -c 1 -W 3 "$WEBSITE_ADDRESS" &>/dev/null; then
sudo apt-get update && sudo apt upgrade -y && sudo DEBIAN_FRONTEND=noninteractive apt-get -y install apache2 php libapache2-mod-php php-mysql graphviz aspell git clamav php-pspell php-curl php-gd php-intl ghostscript php-xml php-xmlrpc php-ldap php-zip php-soap php-mbstring unzip mariadb-server mariadb-client certbot python3-certbot-apache ufw
sudo ufw allow 22/tcp && sudo ufw --force enable && sudo ufw default deny incoming && sudo ufw default allow outgoing && sudo ufw allow www && sudo ufw allow 'Apache Full'
else
echo "$WEBSITE_ADDRESS can not be reached. Check your settings"
fi
#End step 1
# Step 2 Git moodle, moodledata, ownership and permissions, edit config files, cron
cd /var/www && sudo git clone https://github.com/moodle/moodle.git && cd moodle && sudo git checkout origin/MOODLE_405_STABLE && sudo git config pull.ff only
sudo chown -R root:root /var/www/moodle && sudo chmod -R 777 /var/www/moodle
sudo mkdir -p /var/www/moodledata && sudo mkdir /var/quarantine && sudo chown -R www-data:www-data /var/quarantine
sudo chown -R www-data:www-data /var/www/moodledata && sudo find /var/www/moodledata -type d -exec chmod 700 {} \; && sudo find /var/www/moodledata -type f -exec chmod 600 {} \;
sudo sed -i 's/.*max_input_vars =.*/max_input_vars = 5000/' "/etc/php/8.3/apache2/php.ini" "/etc/php/8.3/cli/php.ini"
echo "* * * * * www-data /var/www/moodle/admin/cli/cron.php >/dev/null" | sudo tee -a /etc/crontab
echo "0 3 * * * root apt update && apt upgrade -y && git -C /var/www/moodle pull" | sudo tee -a /etc/cron.d/moodle_updates
# End step 2
# Step 3 Create virtual host, encrypted protocol if domain name supplied
# Enter your email when prompted, all others answer "Y"
PROTOCOL="http://"
echo -e "<VirtualHost *:80>\n ServerAdmin webmaster@localhost\n DocumentRoot /var/www/moodle\n ServerName $WEBSITE_ADDRESS\n ServerAlias www.$WEBSITE_ADDRESS\n ErrorLog /var/log/apache2/error.log\n CustomLog /var/log/apache2/access.log combined\n</VirtualHost>" | sudo tee /etc/apache2/sites-available/moodle.conf > /dev/null
sudo a2dissite 000-default.conf && sudo a2ensite moodle.conf && sudo certbot --apache
if [ $? -eq 0 ]; then PROTOCOL="https://"; fi
sudo systemctl reload apache2
# End step 3
# Step 4 Set up the Moodle database with a root password for security
MYSQL_MOODLEUSER_PASSWORD=$(openssl rand -base64 6) && MOODLE_ADMIN_PASSWORD=$(openssl rand -base64 6)
sudo mysql -e "CREATE DATABASE moodle DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER 'moodleuser'@'localhost' IDENTIFIED BY '$MYSQL_MOODLEUSER_PASSWORD'; GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, CREATE TEMPORARY TABLES, DROP, INDEX, ALTER ON moodle.* TO 'moodleuser'@'localhost';"
if [ "$PROTOCOL" == "https://" ]; then
DATABASE_ROOT_PASSWORD=$(openssl rand -base64 6) && echo -e "Y\n${DATABASE_ROOT_PASSWORD}\n${DATABASE_ROOT_PASSWORD}\nY\nY\nY\nY\n" | sudo mariadb-secure-installation
echo "IMPORTANT!!! Your MariaDB database root password has been set to $DATABASE_ROOT_PASSWORD. WRITE THIS DOWN IN A SAFE PLACE"
fi
# End step 4
# 5 Install Moodle from the back end, reset file permissions
if sudo -u www-data /usr/bin/php /var/www/moodle/admin/cli/install.php --non-interactive --lang=en --wwwroot="$PROTOCOL$WEBSITE_ADDRESS" --dataroot=/var/www/moodledata --dbtype=mariadb --dbhost=localhost --dbname=moodle --dbuser=moodleuser --dbpass="$MYSQL_MOODLEUSER_PASSWORD" --fullname="Moodle Docs Step by Step Guide" --shortname="SG" --adminuser=admin --summary="" --adminpass="$MOODLE_ADMIN_PASSWORD" --adminemail=joe@123.com --agree-license; then
echo "Moodle installation completed successfully. You can now log on to your new Moodle at $PROTOCOL$WEBSITE_ADDRESS as admin with $MOODLE_ADMIN_PASSWORD and complete your site registration"
sudo find /var/www/moodle -type d -exec chmod 755 {} \; && sudo find /var/www/moodle -type f -exec chmod 644 {} \;
sudo sed -i '/\/\/ There is no php closing tag in this file,/i \$CFG->phpcli = "\/usr\/bin\/php";\n\$CFG->du_path = "\/usr\/bin\/du";\n\$CFG->aspell_path = "\/usr\/bin\/aspell";\n\$CFG->dot_path = "\/usr\/bin\/dot";' /var/www/moodle/config.php
else
echo "Sorry, something went wrong. Check if your web address is correct."
fi
# End step 5
Congrats! You can now start using Moodle!
Now register your copy, changing the site name, short name and admin email.
Don't Forget
Set up Clamav antivirus
Navigate to Site Administration > Plugins > Antivirus plugins > Manage antivirus plugins
Enable ClamAV antivirus
Click on Settings
Set the proper settings
Save changes
In previous Moodle branches: Check "Use ClamAV on uploaded files" ClamAV Path : /usr/bin/clamscan Quarantine Directory : /var/quarantine
Save Changes
Hosting several Moodle branches in one Ubuntu server
- This is very useful for the language pack maintainers to test translations in several Moodle branches.
- It is also very useful for developers to test their plugins in different Moodle branches.
- Just create a folder for each instance inside the web folder and that would be enough.
- To access the sites you only need to add the folder to localhost URL: http://localhost/moodle31
- You can have an instance for each version from 1.9 to 3.1
- You do need a separate data folder for each instance and a separate database (You can use phpmyadmin to set your database, but that's not necessary), add each instance in its own folder, and carry on as above. You can also host another service (e.g., Mahara) in its separate folder.
Example 1
- So, one example folder tree on one Linux laptop (an actual server would be more) may look something like:
var
--www
----maharadata ----moodlecleandata ----moodlestabledata ----moodlemasterdata ----moodletestingdata ----uswmoodledata ----html ------mahara ------moodleclean ------moodlestable ------moodlemaster ------moodletesting ------uswmoodle
Example 2
- Have several sandboxed Moodles on a single (CentOS X) server all of different versions .. only the ones that are supported for security fixes and above - 2.7,2.8,2.9,3.0, and now a 3.1. Pretty much 'stock' Moodles with only occasional addons, etc. for testing.
- All have their separate code and data directories as well as their separate DB's.
- Hint: install and maintain them all with git ... even if you don't prefer/like command line, that is by far the most efficient way to update and/or upgrade a site.
/var/www/html/moodle27/version.php:$release = '2.7.14 (Build: 20160509)' /var/www/html/moodle28/version.php:$release = '2.8.12 (Build: 20160509)' /var/www/html/moodle29/version.php:$release = '2.9.6+ (Build: 20160520)' /var/www/html/moodle30/version.php:$release = '3.0.4+ (Build: 20160603)' /var/www/html/moodle31/version.php:$release = '3.1+ (Build: 20160603)'
- The git -b command locks a site into the version provided with the rest of the git command ... for example, installing the 3.1, which is a long-term support version, installed with git -b option. Don't plan on upgrading nor testing upgrades with that one.
git clone -b MOODLE_31_STABLE git://git.moodle.org/moodle.git moodle31
- All the other moodles I have on that server have been installed via git
git clone git://git.moodle.org/moodle.git [nameofdir]
- then from nameofdir
git branch --track MOODLE_2#_STABLE origin/MOODLE_2#_STABLE git checkout MOODLE_2#_STABLE
- 2# is the version number.
- That allows one to march that moodle upwards ... higher branch(es). So one can test an upgrade (as opposed to an 'update').
- This second method 'gits' more code and backups will range in the 5+ Meg range due to all the older version git stuff The 3.1 much less (restricted to 3.1 branch):
- 545M ./moodle296-code-20160604145012.tar
- 193M ./moodle31+-code-2016060883737.tar
See also
- Installation on Ubuntu using Git
- DigitalOcean's How To Install Linux, Apache, MySQL, PHP (LAMP) Stack on Ubuntu 22.04
- DigitalOcean's How To Install Linux, OpenLiteSpeed, MariaDB, PHP (LOMP stack) on Ubuntu 22.04
- DigitalOcean's How to Keep Ubuntu 22.04 Servers Updated
- DigitalOcean's How To Set Up a Firewall with UFW on Ubuntu 22.04