PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchTo install Moodle on a VPS, prepare a supported Linux web stack, create a dedicated database, keep moodledata outside the public web root, run Moodle’s installer, and finish with HTTPS, permissions, cron, backups, and updates. The exact PHP and database versions depend on the Moodle branch you choose.
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
The current official downloads page identifies Moodle 5.3 as the latest update. Moodle 4.5.15 is listed as a security-supported release, with PHP 8.1 or newer and specific database minimums. Check the requirements for your selected branch before installing packages.
As an Amazon Associate I earn from qualifying purchases.
1. Choose the Moodle release and plan the VPS
Moodle is a PHP application that uses a relational database and a web server. Your VPS must provide all three components, plus enough storage and memory for course files, concurrent users, database queries, scheduled tasks, and backups. There is no universal “minimum VPS size”: a small private course and a busy school have very different workloads.
Check release-specific requirements first
Requirements change between branches. The Moodle 4.5 server-requirements documentation specifies PHP 8.1.0 as the minimum. The security-supported Moodle 4.5.15 listing also specifies MariaDB 10.6.7 or MySQL 8.0, PostgreSQL 13, Microsoft SQL Server 2017, or Oracle 19c as supported database baselines. Moodle’s current downloads page identifies Moodle 5.3 as the latest update, so do not assume that a 4.5 package’s requirements apply to 5.3.
#1 Best Overall
Use the Moodle 4.5 server requirements page when installing 4.5, and consult the corresponding requirements for any other branch. Select one PHP version and use that same version for both the command-line interface and PHP-FPM.
| Item | Known requirement or guidance | Qualification |
|---|---|---|
| Moodle 4.5 PHP | PHP 8.1.0 minimum | Applies to the 4.5 branch; later branches may require newer PHP. |
| Moodle 4.5.15 databases | MariaDB 10.6.7, MySQL 8.0, PostgreSQL 13, SQL Server 2017, or Oracle 19c | Versions listed for the security-supported 4.5.15 release. |
| Latest official download-page update | Moodle 5.3 | Verify its server requirements before provisioning. |
| Web server | Apache or Nginx | Install and configure one, not both. |
| Data directory | moodledata outside the document root |
Must be writable by the web-server account and inaccessible to browsers. |
Prepare access and naming
- A fresh Ubuntu VPS with sudo or root access.
- A DNS name such as
moodle.example.com, or a temporary IP address for initial testing. - A plan for off-site backups of the database,
moodledata, andconfig.php. - Enough disk space for uploaded files, the database, temporary backups, and future upgrades. Monitor usage rather than relying on a generic disk figure.
2. Update Ubuntu and apply basic network controls
Connect over SSH as a sudo-capable account. The commands below assume a current Ubuntu Server installation without a desktop environment.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitches- Update package indexes and installed packages:
sudo apt update sudo apt -y full-upgradeReboot if the kernel or core libraries were upgraded, then reconnect.
- Install common utilities used during the deployment:
sudo apt install -y ca-certificates curl unzip tar git ufw - Allow SSH and web traffic before enabling the firewall. If your SSH service uses a non-standard port, allow that port instead of
OpenSSH:sudo ufw allow OpenSSH sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable sudo ufw status verbose - Point your DNS A/AAAA record at the VPS. Keep the time-to-live low while testing, then raise it after the address is stable.
Do not expose MariaDB, MySQL, or PostgreSQL directly to the internet unless a documented remote-access design requires it. Moodle and the database can communicate over the VPS’s local socket or loopback interface.
3. Install PHP, extensions, and a database
Install the PHP version required by your branch
Ubuntu package names vary by release and by the PHP version in use. Install the default packages only after confirming that Ubuntu’s default PHP satisfies Moodle’s requirement; otherwise use your organization’s approved repository for the required version.
sudo apt install -y php-fpm php-cli
php-curl php-zip php-gd php-xml php-intl php-mbstring
php-soap php-bcmath php-exif php-ldap php-mysql php-opcache
Moodle’s Ubuntu installation guidance also lists XML-RPC among the extensions used by its example. On newer PHP releases, an XML-RPC package may be unavailable or supplied differently, so follow the selected branch’s extension list rather than forcing an obsolete package. Confirm both PHP interfaces:
php -v
php -m
systemctl status php*-fpm --no-pager
Check that the command-line PHP version and the FPM service version match. Raise upload and execution limits in the active FPM and web-server configuration when your courses contain large files, then restart PHP-FPM. Moodle’s administration screens will report settings that are too low for your workload.
Recommended Free Tools
Rank #2
Install MariaDB (or use another supported database)
The example below uses MariaDB, which is a straightforward local database choice on Ubuntu. A supported MySQL, PostgreSQL, SQL Server, or Oracle installation is also possible when it meets the release requirements and you adapt the driver and commands.
sudo apt install -y mariadb-server mariadb-client
sudo systemctl enable --now mariadb
sudo mariadb-secure-installation
Use the secure-installation prompts to remove anonymous users, disallow remote root login, remove the test database, and reload privilege tables. Then create a database with UTF-8 support and a separate account for Moodle:
sudo mariadb
CREATE DATABASE moodle DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'moodleuser'@'localhost' IDENTIFIED BY 'replace-with-a-long-random-password';
GRANT ALL PRIVILEGES ON moodle.* TO 'moodleuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Store the database password in a password manager. Do not reuse the VPS administrator password, and do not grant the Moodle account global privileges.
4. Select and configure one web server
Apache and Nginx are both valid Moodle choices. Apache has extensive Moodle community documentation and familiar per-directory tooling. Nginx can be efficient for busier sites, but its PHP-FPM and fallback configuration must be written explicitly. Operational familiarity, expected traffic, logging, and your team’s existing tooling matter more than a generic performance claim.
| Decision point | Apache | Nginx |
|---|---|---|
| PHP integration | Enable proxy modules and pass PHP files to PHP-FPM. | Configure a FastCGI location and the correct PHP-FPM socket. |
| Rewrite and fallback | Use a virtual host and Moodle’s directory rules. | Use try_files so non-file requests reach index.php. |
| Administration | Often easier for teams already using Apache modules and virtual hosts. | Often preferred by teams standardizing on Nginx configuration and centralized proxying. |
| Logging | Separate access and error logs per virtual host. | Separate access and error logs per server block. |
| Installation rule | Install and expose one web server, not both on ports 80 and 443. | |
Option A: Apache with PHP-FPM
sudo apt install -y apache2 libapache2-mod-fcgid
sudo a2enmod proxy_fcgi setenvif rewrite headers env dir mime
sudo a2enconf php8.1-fpm
Replace php8.1-fpm with the FPM configuration that matches your installed PHP version. Create a virtual host such as /etc/apache2/sites-available/moodle.conf:
<VirtualHost *:80>
ServerName moodle.example.com
DocumentRoot /var/www/moodle
<Directory /var/www/moodle>
Options FollowSymLinks
AllowOverride None
Require all granted
</Directory>
<FilesMatch .php$>
SetHandler 'proxy:unix:/run/php/php8.1-fpm.sock|fcgi://localhost/'
</FilesMatch>
ErrorLog ${APACHE_LOG_DIR}/moodle-error.log
CustomLog ${APACHE_LOG_DIR}/moodle-access.log combined
</VirtualHost>
Change the socket path to the file present under /run/php/. Enable the site and test the syntax:
Rank #3
- Used Book in Good Condition
sudo a2dissite 000-default.conf
sudo a2ensite moodle.conf
sudo apachectl configtest
sudo systemctl reload apache2
Option B: Nginx with PHP-FPM
sudo apt install -y nginx
sudo systemctl enable --now nginx
Create /etc/nginx/sites-available/moodle. The socket name must match your installed FPM version:
server {
listen 80;
listen [::]:80;
server_name moodle.example.com;
root /var/www/moodle;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ [^/].php(/|$) {
fastcgi_split_path_info ^(.+?.php)(/.+)$;
try_files $fastcgi_script_name =404;
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
location ~ /. {
deny all;
}
access_log /var/log/nginx/moodle-access.log;
error_log /var/log/nginx/moodle-error.log;
}
sudo ln -s /etc/nginx/sites-available/moodle /etc/nginx/sites-enabled/moodle
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx
Keep moodledata outside /var/www/moodle; the Nginx rule above is not a substitute for that separation.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →5. Download Moodle and place the code safely
Obtain the archive for the branch you selected from Moodle’s official downloads page, or obtain the branch through Moodle’s documented Git distribution. Verify the version and, where available, the archive checksum before unpacking it.
One safe layout is:
/var/www/moodle— Moodle application code and the generatedconfig.php./var/moodledata— uploaded files, caches, sessions, and other data; never a public web directory.
sudo mkdir -p /var/www/moodle /var/moodledata
sudo tar -xzf /tmp/moodle-release.tar.gz --strip-components=1 -C /var/www/moodle
sudo chown -R www-data:www-data /var/www/moodle /var/moodledata
sudo chmod 770 /var/moodledata
The archive filename in the command is an example; use the file you actually downloaded. If your web server runs as a different account, substitute that account for www-data. During installation the web process must be able to create config.php and write to moodledata.
After installation, reduce write access to the code tree. A common production baseline is root ownership with the web-server group able to read, directories at 755, and files at 644:
sudo chown -R root:www-data /var/www/moodle
sudo find /var/www/moodle -type d -exec chmod 755 {} ;
sudo find /var/www/moodle -type f -exec chmod 644 {} ;
sudo chown -R www-data:www-data /var/moodledata
sudo find /var/moodledata -type d -exec chmod 770 {} ;
Do not make the entire web root world-writable. If you use a web-based upgrade workflow, follow Moodle’s documented ownership requirements for that workflow rather than broadly relaxing permissions.
Rank #4
6. Run the Moodle installer
Use the command-line installer
The CLI installer is predictable and works well over SSH. Run it as the web-server account so generated files have appropriate ownership:
sudo -u www-data /usr/bin/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='replace-with-a-long-random-password'
--fullname='Example Learning Site'
--shortname='Example'
--adminuser='admin'
--adminpass='replace-with-a-unique-admin-password'
--adminemail='[email protected]'
--non-interactive
--agree-license
Use the final HTTPS URL only after HTTPS will be available, or begin with the temporary HTTP URL and update Moodle’s stored URL during the HTTPS migration. The administrator password should be long, unique, and stored in a password manager.
Use the browser installer instead
- Browse to the server name or temporary IP address.
- Choose the language and confirm the detected paths.
- Set the data directory to
/var/moodledata, not a directory under the document root. - Select the database driver, then enter the database name, user, host, and password created earlier.
- Review the environment check. Resolve missing extensions, unsupported PHP versions, writable-path errors, and database collation warnings before continuing.
- Enter the site name and administrator account, then let Moodle write
config.php.
If the installer cannot write config.php, temporarily correct ownership on that file’s parent directory, rerun the installer, and apply the production permissions immediately afterward.
7. Enable HTTPS and finish hardening
Plain HTTP exposes login credentials and session cookies. Obtain a certificate for the real hostname with Certbot after DNS points to the VPS and the chosen web server answers on port 80.
Apache certificate
sudo apt install -y certbot python3-certbot-apache
sudo certbot --apache -d moodle.example.com
Nginx certificate
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d moodle.example.com
Follow the prompts to redirect HTTP to HTTPS, then test renewal:
sudo certbot renew --dry-run
After changing the site from HTTP to HTTPS, make sure Moodle’s configured $CFG->wwwroot uses the HTTPS URL. If you changed it manually in config.php, clear Moodle caches from the CLI:
Best Value
sudo -u www-data php /var/www/moodle/admin/cli/purge_caches.php
Review these production controls:
- Allow only required inbound ports through the VPS firewall.
- Keep the database bound to local access unless remote administration is explicitly required and protected.
- Use separate, strong credentials for SSH, the database, and Moodle administrators.
- Keep Ubuntu, PHP, the web server, the database, and Moodle on supported security branches.
- Inspect web-server and PHP-FPM logs after each configuration change.
- Protect backups from the web root and restrict their permissions.
8. Configure Moodle’s cron task
Moodle needs its scheduled task runner for message delivery, enrolment synchronization, cache cleanup, backups, and other background work. Run it at least once per minute as the web-server account. Create /etc/cron.d/moodle:
Free tools Windows power users keep installed
One-click scans. No signup required.
* * * * * www-data /usr/bin/php /var/www/moodle/admin/cli/cron.php >/dev/null
Use the absolute PHP path and confirm the command works manually:
sudo -u www-data /usr/bin/php /var/www/moodle/admin/cli/cron.php
In Moodle administration, check the scheduled-task status and investigate tasks that remain overdue. A cron process that runs as root can create files the web process cannot modify, so keep the account consistent.
9. Back up and test recovery
A VPS snapshot alone is not a complete Moodle backup. Preserve three items together:
- The database, exported with the database’s native dump tool.
- The complete
/var/moodledatadirectory, including uploaded course files. /var/www/moodle/config.phpand your deployment notes, including the Moodle branch and PHP version.
Store encrypted copies off the VPS, retain more than one restore point, and test restoring to a separate staging VPS. A backup that has never been restored is only an assumption. Schedule database dumps during a period of low activity and monitor backup jobs for failures and insufficient disk space.
10. Common installation failures
| Symptom | Likely cause | Fix |
|---|---|---|
| Environment check reports an unsupported PHP version | The VPS installed Ubuntu’s default PHP, which is older than the Moodle branch requires. | Install a supported PHP version, matching CLI and FPM, then restart FPM and reload the web server. |
| Blank page or “502 Bad Gateway” | PHP-FPM is stopped, or the configured socket path is wrong. | Check systemctl status php*-fpm, inspect /run/php/, correct the Apache or Nginx socket, test configuration, and reload. |
Installer says moodledata is not writable |
The directory belongs to the wrong account or has restrictive permissions. | Give the web-server account ownership of /var/moodledata and use a private mode such as 770; never move it into the public root. |
| “Database connection failed” | Wrong host, database name, password, driver, or missing PHP database extension. | Log in with the Moodle database account from the VPS, verify the database exists, and confirm the matching PHP driver is loaded. |
| Every URL returns the home page or 404 errors | Fallback/rewrite rules are missing or the virtual host points at the wrong directory. | For Apache, verify the active virtual host and rewrite handling. For Nginx, verify try_files, root, and the PHP location, then run the server’s config test. |
| Users are redirected between HTTP and HTTPS | Moodle’s configured site URL and the certificate-enabled URL do not match. | Set the canonical HTTPS URL in config.php, purge caches, and remove conflicting proxy redirects. |
| Scheduled tasks remain overdue | Cron is absent, runs under the wrong user, or calls a different PHP version. | Run the CLI cron command manually, inspect cron logs, and keep the task under the web-server account every minute. |
| Updates fail after permissions were tightened | The deployment account cannot replace read-only Moodle code. | Use a controlled maintenance procedure that temporarily grants the required ownership, performs the upgrade, and reapplies 755/644 production permissions. |
11. Decide whether self-hosting is appropriate
A VPS gives you control over the operating system, PHP version, database, web server, network location, backups, and maintenance schedule. It also makes you responsible for patching every layer, monitoring disk and memory, renewing certificates, testing restores, and responding to outages.
If you do not want to maintain that stack, a managed Moodle provider or MoodleCloud can remove much of the server administration. Confirm that the service supports your chosen Moodle release, required plugins, data-residency needs, backup/restore workflow, user volume, and upgrade policy. The trade-off is less low-level control and a recurring service cost.
For a self-managed VPS, the installation is complete only when the selected release passes its environment checks, the site is reachable over HTTPS, moodledata is private, cron runs successfully, and a tested backup exists.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.

