User talk:James Steerpike

From MoodleDocs

{{#section:Cron|Scheduling_tasks}} {{#section:Cron|Scheduling tasks}}


The RedHat family

Redhat is a proprietary subscription-based licensed version of Linux. Open sourced RHEL-compatible alternatives include AlmaLinux, Rocky Linux (stable and production ready), CentOS Stream (suitable for production but more adventurous) and Fedora (cutting-edge features more for developers). The Redhat family is used for many Moodle installations but Ubuntu may be more suitable for lower powered servers and inexperienced users.

These instructions have been tested on Alma and RoclyLinux 9 using 1 CPU and 1 gB of RAM, the mimimum configuration specified for Moodle. Such a low powered server is suitable for development or a pilot site if an extra 1 Gb of swopspace is set.

This guide requires a Linux Alma 9 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 the RedHat family of servers 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 the package lists and then upgrade all installed packages to the latest available versions.
  • Install epel-release, a community-based repository that provides additional packages not available in the base CentOS/RHEL repositories.
  • Install remi-release-9.rpm, an RPM package with more recent versions of PHP and related software.
  • Install a collection of utilities that extend the functionality of dnf, the Dandified YUM package manager.
  • Module enable tells dnf that you want to use the PHP 8.2 packages provided by Remi.
  • Create a new repository configuration file called MariaDB.repo in /etc/yum.repos.d/, the standard directory for YUM repository configurations. This allows installation of MariaDB 10.6 from the official MariaDB repository.
sudo fallocate -l 1G /swapfile   # Allocate 1GB swap file
sudo chmod 600 /swapfile         # Set proper permissions
sudo mkswap /swapfile            # Setup the swap space
sudo swapon /swapfile            # Enable the swap file
echo '/swapfile swap swap defaults 0 0' | sudo tee -a /etc/fstab



sudo dnf update -y && sudo dnf upgrade -y
sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
sudo dnf makecache
-- sudo dnf install epel-release
sudo dnf install https://rpms.remirepo.net/enterprise/remi-release-9.rpm
sudo dnf install dnf-utils
sudo dnf module enable php:remi-8.2 -y
  • Create a new repository configuration file called MariaDB.repo in /etc/yum.repos.d/, the standard directory for YUM repository configurations. This allows installation of MariaDB 10.6 from the official MariaDB repository.
  • Note this a SINGLE command so copy and paste ALL lines before executing.
echo "# MariaDB 10.6 CentOS / RHEL / Rocky Linux / AlmaLinux 9 - x86_64
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.6/rhel9-amd64
gpgkey = https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck = 1
enabled = 1" > /etc/yum.repos.d/MariaDB.repo
  • Clean the dnf cache, removing cached packages and metadata to reclaim disk space and resolve package conflicts
  • Download fresh metadata from enabled repositories and store this information locally for faster future operations
  • Install the MariaDB database server and client
sudo dnf clean all
sudo dnf makecache
sudo dnf install -y MariaDB-server MariaDB-client
  • Enable and start MariaDB service
sudo systemctl enable mariadb
sudo systemctl start mariadb
  • Performs a system-wide update of all installed packages on your system. It checks for available updates, downloads them, and installs them automatically without prompting for confirmation due to the -y flag
  • Enable the CRB repository, which provides additional packages and development tools. Many EPEL packages depend on CRB,
  • Install all other required packages including git, a text editor, the Apache HTTP Server (httpd) and php extensions required for Moodle
if grep -q "Red Hat Enterprise Linux" /etc/os-release; then
    sudo subscription-manager repos --enable codeready-builder-for-rhel-9-$(arch)-rpms
else
    sudo dnf config-manager --set-enabled crb
fi
sudo dnf update -y
sudo dnf install -y httpd php php-mysqlnd graphviz aspell git clamav php-pspell php-curl php-gd php-intl ghostscript php-xml  php-ldap  php-xmlrpc php-zip php-soap php-mbstring unzip  certbot python3-certbot-apache firewalld nano
  • Enable the Apache web server (httpd), MariaDB database, and firewalld services to start automatically on system boot
  • Start the Apache web server, MariaDB database, and firewalld services in the current session
  • Permanently add the HTTP service and HTTPS service (ports 80, 443) to the firewall rules, allowing incoming traffic
  • Reload the firewall configuration, applying the changes made to the firewall rules
sudo systemctl enable httpd mariadb firewalld
sudo systemctl start httpd mariadb firewalld
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload



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 apache:apache /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.ini
echo "* * * * * apache /var/www/moodle/admin/cli/cron.php >/dev/null 2>&1" | 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.

  • Set the variables for the virtual host file and the document root containing Moodle code
  • Create the virtual host file
  • Set the owner of the Moodle code to be the apache webserver
  • Set the Moodle code to have read, write, and execute for Apache and read, execute for all others on the system
  • Restart the webserver after the changes


# Create the virtual host configuration file
CONF_DIR="/etc/httpd/conf.d"
DOC_ROOT="/var/www/moodle"  # Updated to point to Moodle's directory

cat << EOF > "${CONF_DIR}/${WEBSITE_ADDRESS}.conf"
<VirtualHost *:80>
    ServerAdmin webmaster@${WEBSITE_ADDRESS}
    ServerName ${WEBSITE_ADDRESS}
    ServerAlias www.${WEBSITE_ADDRESS}
    DocumentRoot ${DOC_ROOT}
    ErrorLog /var/log/httpd/${WEBSITE_ADDRESS}-error.log
    CustomLog /var/log/httpd/${WEBSITE_ADDRESS}-access.log combined
</VirtualHost>
EOF
 
chown -R apache:apache ${DOC_ROOT}  
chmod -R 755 ${DOC_ROOT}
systemctl restart httpd
  • Call the Certbot to create a SSL certificate for encrypted https (requires a Fully Qualified Domain Name)
  • Set the protocol to https if certbot succeeds
CERTBOT_OUTPUT=$(sudo certbot --apache --non-interactive --agree-tos -d ${WEBSITE_ADDRESS} -d www.${WEBSITE_ADDRESS} 2>&1)
# Check if Certbot succeeded
if echo "$CERTBOT_OUTPUT" | grep -q "Congratulations! Your certificate and chain have been saved at:"; then
    echo "Certbot succeeded. SSL certificate installed."
    PROTOCOL="https://"
else
    echo "Certbot failed. Falling back to HTTP."
    PROTOCOL="http://"
fi

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


Command Line Installation

MOODLE_ADMIN_PASSWORD=$(openssl rand -base64 6)
sudo -u apache /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.
# Create Ubuntu system user for backups
sudo adduser --disabled-password --gecos "" backupsys

# Generate a password for the SQL backup user
SQL_BACKUP_PASSWORD=$(openssl rand -base64 12)

# Create SQL backup user and grant permissions
sudo mysql <<EOF
CREATE USER 'sqlbackup'@'localhost' IDENTIFIED BY '${SQL_BACKUP_PASSWORD}';
GRANT LOCK TABLES, SELECT ON moodle.* TO 'sqlbackup'@'localhost';
FLUSH PRIVILEGES;
EOF

# Create .my.cnf file for the Ubuntu system user
sudo -u backupsys bash -c "cat > /home/backupsys/.my.cnf <<EOF
[client]
user=sqlbackup
password=${SQL_BACKUP_PASSWORD}
EOF"
sudo chmod 600 /home/backupsys/.my.cnf

# Set up backup directory
sudo mkdir -p /var/backups/moodle
sudo chmod 700 /var/backups/moodle
sudo chown backupsys:backupsys /var/backups/moodle

# Set up cron jobs for the Ubuntu system user
echo "0 2 * * * mysqldump --defaults-file=/home/backupsys/.my.cnf moodle > /var/backups/moodle/moodle_backup_\$(date +\%F).sql" | sudo crontab -u backupsys -
echo "0 3 * * * find /var/backups/moodle -name \"moodle_backup_*.sql\" -type f -mtime +7 -delete" | sudo crontab -u backupsys -

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

es:Guia de instalacion paso-a-paso para Ubuntu


Longer Explanation

The steps are designed to be run by even a new user but understanding Linux will be invaluable when fixing problems.

=== Introduction to Linux === 

For a Windows user, the file system uses drive letters (e.g., C:, D:). Programs are generally installed as standalone executables using .exe or .msi installers from many sources. The user decides where to put them and configuration uses GUI tools and settings menus.

Linux has a single directory tree starting from / (root) , and software is open source, installed and managed using the system’s package manager. Each package has a predetermined location and configuration is done by editing text-based configuration files. File permissions are more restictive and secure than Windows.
=== Linux Commands === 

The ten basic commands used in Linux are shown here in https://www.redhat.com/en/blog/basic-linux-commands.

Ubuntu.org has all the software required as packages on their servers with their location listed in the repositories of the /etc/apt/sources.list and in the /etc/apt/sources.list.d/ directory. The package manager utility apt first uses update to check if newer versions of installed software exists, then uses upgrade to obtain these versions. The upgrade after install can take a few minutes and it is safe to accept any defaults when asked. The next step is to install all the packages required for Moodle. Unlike Windows, you will not be asked where to put these files as the package already has a defined place in the Linux file hierarchy. Ubuntu 24 has a default php version of 8.3, suitable for Moodle 4.5. If another php version is required, another source would need to be added to the repositories. To learn more about apt, see https://phoenixnap.com/kb/apt-package-manage


git is the easiest way to get the latest version of Moodle and keep it up to date. First, we use clone which downloads a copy of the repository from(https://github.com/moodle/moodle.git into a new folder named moodle. After switching to this newly created folder, the stable branch of moolde is checked out. Allowing only fast-forward merges when pulling updates allows updated Moolde source code to be either merged with local customisations or flag a conflict. https://youtu.be/xnR0dlOqNVE

Moodle requires creating a moodledata directory to store sensitive data. Linux protects sensitive data by controlling who can access the data and what can be done with it.

Each Linux server has a list of users. Some are people who log in, others are users set up to run processes. An example is www-data, created during the installation of Apache as the default account to run web servers. Users are organised into groups, able to do similar actions and every file has an owner and a group. The chown step makes the moodledata directory owned by www-data user and www-data group.

sudo find /var/www/moodledata -type d -exec chmod u=rwx,g=,o= {} \; sudo find /var/www/moodledata -type f -exec chmod u=rw,g=,o= {} \;


Files and folders can be marked to show if they can be read, written or executed and this can be set differently for the owner (u), the group (g), and every other user on the system (o). The chmod command will mean for the moodledata folder (type f) only the moodledata owner (www_data ) can read (allows listing the contents of the folder), write (allows creating, modifying, or deleting files in the folder) and execute (allows entering the folder using cd and accessing its contents). The files (type d) in the folder can be read and written only but not executed as a program to steal data or cause damage. The group owner and other users have no access rights to moodledata. By setting restrictive permissions, even if the moodledata directory is accidentally exposed to the web, no one but the web server can access its contents. To understand ownership and file permissions, refer to https://www.digitalocean.com/community/tutorials/an-introduction-to-linux-permissions. That will also cover the octal notation (ie 700, 600) often used as a shortcut in chmod.

Ownership and permissions are why we use sudo to run commands that require administrative privileges. Even if we are the root user, sudo keeps an audit trail available in /var/log/auth.log.




then sets the owner to www-data (user and group created during the installation of Apache as the default account to run web servers). chmod sets the permissions for directories to read, write, and execute for the owner (www_data) and read and write for the files in the moodledata directory. By setting restrictive permissions, even if the moodledata directory is accidentally exposed to the web, no one but the web server can access its contents. To understand ownership and file permissions, refer to https://www.digitalocean.com/community/tutorials/an-introduction-to-linux-permissions

In Linux, configuration files are used to manage and customize the behavior of the operating system, software applications, services, and hardware. Configuration files are text files and a text editor such as nano can be used to make changes. You will need to use sudo to find the max_input_vars line in /etc/php/8.3/apache2/php.ini and /etc/php/8.3/cli/php.ini, change it to 5000 as this is teh php configuration required by the Moodle instalation. The command line utility can this all this from the command line.

You will need to restart apache for these changes to take effect. sudo systemctl reload apache2 Other apache commands sudo systemctl stop apache2 sudo systemctl start apache2 sudo systemctl status apache2


A https connection is essentail for any moodle containing student data. Obtaining a certbot certificate is free but requires a domain name. This step edits the default virtual host configuration file with the domain name and sets up the certbot certificate. Ubuntu expects the webserver files to be found in the /var/www/html folder and that is where we placed moodle to login to moodle as https://mydomain/moodle. By changing the dataroot in the default virtual host configuration file, you can access moodle directly at https://mydomain.


The echo command adds a line to the end of a text file called crontab which sets up a job run by the we bserver called cron.php found  in the /var/www/moodle/admin/cli/ to run every minute. To find out more about cron, see https://ostechnix.com/a-beginners-guide-to-cron-jobs/
Software Compatibility Table
Moodle PHP MariaDB MySQL
4.5 8.1 10.6.7 8.0
4.1 7.3 10.2.29 5.7
3.9 7.2 10.2.29 5.6
3.5 7.0 5.5.31 5.5.31
3.1 5.4.4 5.5.31 5.5.31
2.7 5.4.4 5.5.31 5.5.31