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.
1 Initial preparation
This guide requires a Linux Ubuntu 24 server with sudo or root access. All commands on this page are text based so there is no need for a desktop with a graphical interface. Each step will tell you what you need to do and then give the commands that will accomplish that step. You can copy the entire step or a line at a time but be careful with the longer lines. For example, there only 2 lines in step 2 and the second one is very long.
See the notes at the end of the page for more details on why we use Ubuntu server and how to get one.
First, some information needs to be stored as variables to make substitution of the values easier.
PROTOCOL="http://";
read -p "Enter the web address (without the http:// prefix, eg domain name mymoodle123.com or IP address 192.168.1.1.): " WEBSITE_ADDRESS
2 The LAMP stack
Moodle requires a web server, database and the php scripting language as described in https://moodledev.io/general/releases/4.5#server-requirements.
- Update Ubuntu with the latest packages
- Install all necessary packages using the package manager apt-get
sudo apt-get update && sudo apt upgrade -y
sudo 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 nano
3 Moodle code
git is a version control system that is the easiest way to download the latest Moodle code and unpack it into a directory. It also makes keeping up to date with patches much easier.
- Change to the directory where your web server will find the files.
- Clone the Moodle source code repository into the current directory.
- Change to the moodle directory where the repository was cloned.
- Switch to the Moodle 4.0.5 stable branch to use a specific release.
- Configure Git to allow only fast-forward merges when pulling updates.
cd /var/www/html
sudo git clone https://github.com/moodle/moodle.git
cd moodle
sudo git checkout origin/MOODLE_405_STABLE
sudo git config pull.ff only
4 Specific Moodle requirements
Moodle needs to store files in a specific directory accessible only by the web server. It also needs to change some php configuration settings and set up a cron task. This could be done using a text editor but echo and sed, a text replacement tool, simplifies the process.
- Create the moodledata directory outside your web server's document root
- Set the owner and group recursively to the webserver for moodledata
- Set the moodledata directory permissions so only the web server can read, write, and access them.
- Set the moodledata file permissions so only the web server can read and write them.
- Set file permissions for the moodle directory to read, write and execute for all during the install
- Set the maximum number of input variables that PHP will accept in a single request in the php.ini config files in /etc/php/8.3/apache2 and /etc/php/8.3/cli
- Call the cron.php in the moodle admin directory to run every minute
sudo mkdir -p /var/www/moodledata
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 chmod -R 777 /var/www/html/moodle
sudo sed -i 's/.*max_input_vars =.*/max_input_vars = 5000/' /etc/php/8.3/apache2/php.ini
sudo sed -i 's/.*max_input_vars =.*/max_input_vars = 5000/' /etc/php/8.3/cli/php.ini
echo "* * * * * www-data /var/www/moodle/admin/cli/cron.php >/dev/null" | sudo tee -a /etc/crontab
5 Get the https protocol
NOTE: A domain name is required to get https in this step. If sensitive student and academic data will not be on the server, this step is not necessary. Go to step 6 to create a test or development Moodle site.
Using HTTPS over HTTP on a Moodle site provides the critical security benefits of encrypted data transmission and compliance with privacy regulations and some features in Moodle may not function properly or may be blocked if the site is using a HTTP connection.
- Open the /etc/apache2/sites-available/000-default.conf file with a text editor
- Set the server name to your domain
- Set the server alias to www.(your domain)
- Call the certbot and enter the admin email, answer
- Restart Apache
sudo sed -i '/ServerName/c\ ServerName $WEBSITE_ADDRESS' /etc/apache2/sites-available/000-default.conf
sudo sed -i '/ServerAlias/c\ ServerAlias www.$WEBSITE_ADDRESS' /etc/apache2/sites-available/000-default.conf
sudo certbot --apache
sudo systemctl reload apache2
PROTOCOL="https://";
6 Database and user creation
Create the user and database moodle will use
- Create a new database named moodle with the utf8mb4 character set and utf8mb4_unicode_ci collation.
- Create a new MySQL user moodleuser with a password
- Grant privileges on the moodle database to the moodleuser to allow localhost access.
MYSQL_MOODLEUSER_PASSWORD=$(openssl rand -base64 6)
sudo mysql -e "CREATE DATABASE moodle DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
sudo mysql -e "CREATE USER 'moodleuser'@'localhost' IDENTIFIED BY '$MYSQL_MOODLEUSER_PASSWORD';"
sudo mysql -e "GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, CREATE TEMPORARY TABLES, DROP, INDEX, ALTER ON moodle.* TO 'moodleuser'@'localhost';"
echo "Your Moodle user password is $MYSQL_MOODLEUSER_PASSWORD. Write this down as you will need it in a web browser install"
7 Moodle configuration
A script in the moodle/admin directory will complete the Moodle installation.
- Go to your domain/moodle on a web browser and use the web browser to complete the moodle install.
prompt | Required |
---|---|
Web Address | http://your_web_address/moodle |
Moodle Directory | /var/www/html/moodle |
Data Directory | /var/www/moodledata |
Database type | mariadb |
Database host | localhost |
Database name | moodle |
Database user | moodleuser |
Database password | Created in step 4r |
Command Line Installation
MOODLE_ADMIN_PASSWORD=$(openssl rand -base64 6)
sudo -u www-data /usr/bin/php /var/www/html/moodle/admin/cli/install.php --non-interactive --lang=en --wwwroot="$PROTOCOL$WEBSITE_ADDRESS/moodle" --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
echo "Moodle installation completed successfully. You can now log on to your new Moodle at $PROTOCOL$WEBSITE_ADDRESS/moodle as admin with $MOODLE_ADMIN_PASSWORD and complete your site registration"
8 SQL Backups
Daily automated date marked sql backups should be set up on a production Moodle. Dumps can be large and need to be deleted periodically.
- Create MySQL backup user and grant privileges to lock tables (better security than using root or moodleuser roles)
- Create a configuration file for root with the backup user credentials (to avoid the password being visible in the SQL backup call).
- Set the configuration file permissions to read and write for root only
- Setup backup directory with read, write and execute permissions for root only
- Set up two daily cron jobs, one to dump the database and the other to remove dumps more than a set number of days old.
BACKUP_USER_PASSWORD=$(openssl rand -base64 6)
mysql <<EOF
CREATE USER 'backupuser'@'localhost' IDENTIFIED BY '${BACKUP_USER_PASSWORD}';
GRANT LOCK TABLES, SELECT ON moodle.* TO 'backupuser'@'localhost';
FLUSH PRIVILEGES;
EOF
cat > /root/.my.cnf <<EOF
[client]
user=backupuser
password=${BACKUP_USER_PASSWORD}
EOF
chmod 600 /root/.my.cnf
mkdir -p /var/backups/moodle && chmod 700 /var/backups/moodle && chown root:root /var/backups/moodle
(crontab -l 2>/dev/null; echo "0 2 * * * mysqldump --defaults-file=/root/.my.cnf moodle > /var/backups/moodle/moodle_backup_\$(date +\%F).sql") | crontab -
(crontab -l 2>/dev/null; echo "0 3 * * * find /var/backups/moodle -name \"moodle_backup_*.sql\" -type f -mtime +7 -delete") | crontab -
9 Security
These steps are essential for a production server but can be skipped for a Moodle used only for yourself.
- Reset the permissions on /var/www/html/moodle directories to read, write and execute for the webserver, read and execute for group and others
- Reset the permissions on /var/www/html/moodle files to read, write for the webserver, read only for group and other
- Run the mariadb-secure-installation script to strengthen security by setting a root password, removing anonymous users, disabling remote root login, deleting the test database, and reloading privileges.
- Configure and enable firewall
- Allow SSH (port 22) for remote access
- Enable the UFW firewall with confirmation
- Set default policy to deny all incoming connections
- Set default policy to allow all outgoing connections
- Allow HTTP traffic on port 80
- Allow full access for Apache (HTTP and HTTPS)
sudo find /var/www/html/moodle -type d -exec chmod 755 {} \;
sudo find /var/www/html/moodle -type f -exec chmod 644 {} \;
sudo mariadb-secure-installation
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'
Why use Ubuntu
Obtaining Ubuntu
Setting up antivirus on the server
In order to have your Moodle server scan uploaded files for viruses, you can set up Antivirus plugins.
ClamAV® is available to be installed in Ubuntu. Run the following command in Ubuntu to install the antivirus server:
# sudo apt install -y clamav
This installs the clam scanner for scanning files one-by-one. To activate it, go to Site Administration > Plugins > Antivirus plugins > Manage antivirus plugins > ClamAV antivirus and 'enable' the plugin by opening the eye.
Add this command to the 'Settings' for ClamAV®:
/usr/bin/clamscan
Note: This scanner launches the ClamAV® process once for each file uploaded. If you have a lot of files being uploaded simultaneously on your Moodle site, you may wish to activate the ClamAV® daemon process. To do that, install the ClamAV® daemon:
# sudo apt install -y clamav-daemon
Once the daemon process is running on the site, you can change the ClamAV® command in the Moodle settings to:
/usr/bin/clamdscan
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