Launch Your Online School with Moodle
Self-host a Moodle LMS with courses, quizzes, and certificates.
Introduction
30 Second Summary
Imagine running your own online school where anyone can sign up, watch video lessons, take quizzes, and earn a certificate. No monthly fees to a platform company. No content restrictions. Just your server, your courses, and your students.
In this project, you will install and configure Moodle on your own Ubuntu server, creating a fully functional online school where students register with their email, take self-paced courses with video lessons and quizzes, and earn completion certificates.
What You'll Build
You'll have a live online school that you can open in any browser, create a free student account on the spot, enroll in a course, watch video lessons, pass a quiz, and download a PDF certificate proving you completed it.
By the end of this project, you'll have:
- A live Moodle site running on your own server where students visit, create accounts, and browse a course catalog from any browser on your network.
- A complete course with organized video lessons, study resources, and quizzes that students must pass before moving forward.
- An automatic certificate system that generates a downloadable PDF the moment a student completes all course requirements.
- A self-service enrollment flow where anyone with an email address can sign up and start learning immediately, no admin approval needed.
- Secret Mission: Customize your school's visual theme and homepage to make it look like a professional academy instead of default Moodle.
Are there any prerequisites?
You need physical access to an Ubuntu 26.04 server with sudo privileges. This can be a spare computer, a dedicated machine, or a virtual machine running Ubuntu 26.04.
You should also have VS Code installed on a separate machine for reference. No prior experience with web servers or databases is required.
Before We Start
Before we dive into installing software on your server, let's lock in what you're about to build and why it matters. Taking a moment to commit to your goal makes the technical steps ahead feel purposeful.
Install the LAMP Stack with PHP 8.3
Moodle needs three things to run: a web server to handle browser requests, a database to store courses and student data, and PHP to execute the application code. Together, these form what is called a LAMP stack (Linux, Apache, MariaDB, PHP).
There is a catch. Ubuntu 26.04 ships PHP 8.5 by default, but Moodle 4.5 LTS only supports PHP 8.1 to 8.3. Installing the default PHP would cause Moodle to fail during setup. You need to add a third-party repository and install PHP 8.3 specifically.
In this step, get ready to:
- Add the Sury PHP repository and install PHP 8.3 with all required extensions, Apache2, MariaDB, and Git.
- Secure MariaDB and create a dedicated database and user for Moodle.
- Configure PHP settings for Moodle compatibility.
Add the Sury PHP repository and install PHP 8.3
Ubuntu 26.04 defaults to PHP 8.5, which Moodle cannot use. The Sury repository (packages.sury.org) provides PHP 8.3 packages for Ubuntu.
- Open the terminal on your Ubuntu server and check what PHP version is currently installed by running:
php -v
✔️ I see PHP 8.3.x
PHP 8.3 is already installed on your server. Skip ahead to the package installation command below.
ⓧ I see a different version
Your server has a PHP version that Moodle cannot use. You need to add the Sury repository and install PHP 8.3.
- Download and install the Sury repository keyring by running these commands:
curl -sSLo /tmp/debsuryorg-archive-keyring.deb https://packages.sury.org/debsuryorg-archive-keyring.deb
sudo dpkg -i /tmp/debsuryorg-archive-keyring.deb
- Add the Sury PHP repository to your system's package sources by running:
echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/php-sury.list
- Update your package lists so the system knows about the new repository by running:
sudo apt update
ⓧ Command not found
PHP is not installed yet. You need to add the Sury repository before you can install PHP 8.3.
- Download and install the Sury repository keyring by running these commands:
curl -sSLo /tmp/debsuryorg-archive-keyring.deb https://packages.sury.org/debsuryorg-archive-keyring.deb
sudo dpkg -i /tmp/debsuryorg-archive-keyring.deb
- Add the Sury PHP repository to your system's package sources by running:
echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/php-sury.list
- Update your package lists so the system knows about the new repository by running:
sudo apt update
Why a third-party repository?
Ubuntu freezes its default PHP version at release time for stability. Moodle 4.5 LTS explicitly requires PHP 8.1 to 8.3, so the default 8.5 is too new. The Sury repository is maintained by a Debian Developer and is the standard way to install specific PHP versions on Ubuntu.
- Install Apache2, MariaDB, Git, PHP 8.3, and all required PHP extensions by running:
sudo apt install -y apache2 mariadb-server mariadb-client git \
php8.3 php8.3-mysql php8.3-curl php8.3-gd php8.3-intl \
php8.3-xml php8.3-xmlrpc php8.3-zip php8.3-soap \
php8.3-mbstring php8.3-ldap libapache2-mod-php8.3
What does this command do?
This single command installs everything Moodle needs to run:
- apache2 is the web server that handles HTTP requests from browsers.
- mariadb-server and mariadb-client provide the database engine and command-line tools.
- git is used to download Moodle source code in the next step.
- The php8.3-* packages provide extensions Moodle requires for database access, image processing, internationalization, and more.
- libapache2-mod-php8.3 connects PHP 8.3 to Apache so it can process .php files.
- Verify PHP 8.3 is now active by running:
php -v
You should see output starting with PHP 8.3 followed by a version number.
- Confirm Apache and MariaDB are both running by running:
sudo systemctl status apache2 --no-pager
sudo systemctl status mariadb --no-pager
Both services should show active (running) in green text.
Not seeing PHP 8.3?
If php -v still shows 8.5, the system default is taking priority over the Sury package. Run sudo update-alternatives --set php /usr/bin/php8.3 to switch the active PHP version to 8.3.
If Apache or MariaDB show inactive, start them manually with sudo systemctl start apache2 and sudo systemctl start mariadb.
help me debug my PHP or Apache installation
Secure MariaDB and create the Moodle database
MariaDB is running, but you need to lock down its default configuration and create a dedicated database for Moodle to use.
- Run the MariaDB security script by running:
sudo mysql_secure_installation
How do I answer the security prompts?
This interactive script walks you through several security questions. Since MariaDB on Ubuntu uses unix_socket authentication by default, you do not need a root password.
- When asked for the current root password, press Enter (no password is set on a fresh install).
- When asked about switching to unix_socket authentication, type n (it is already active).
- When asked about changing the root password, type n (unix_socket handles authentication).
- When asked about removing anonymous users, type Y.
- When asked about disallowing root login remotely, type Y.
- When asked about removing the test database, type Y.
- When asked about reloading privilege tables, type Y.
- Log into MariaDB to create the Moodle database by running:
sudo mariadb
- Create the Moodle database with proper encoding by running this SQL command:
CREATE DATABASE moodle DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
You should see Query OK, 1 row affected confirming the database was created.
- Create a dedicated database user for Moodle and grant the required privileges by running these SQL commands:
CREATE USER 'moodleuser'@'localhost' IDENTIFIED BY 'your-secure-password-here';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, CREATE TEMPORARY TABLES, DROP, INDEX, ALTER ON moodle.* TO 'moodleuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
What do these SQL commands do?
CREATE DATABASE sets up an empty database named moodle with utf8mb4 encoding, which supports all Unicode characters including emojis.
CREATE USER makes a dedicated moodleuser account that can only connect from the local machine. The GRANT statement gives it exactly the permissions Moodle needs and nothing more.
Remember your database password
Replace your-secure-password-here with a strong password of your choice and write it down. You will need this password again when running the Moodle installer in the next step.
- Verify the database was created by logging in as the new user:
mariadb -u moodleuser -p -e "SHOW DATABASES;"
Enter the password you just set when prompted. You should see moodle listed in the output.
Access denied for moodleuser?
If you see an access denied error, the password you typed does not match what you set in the CREATE USER command. Log back in as root with sudo mariadb and run DROP USER 'moodleuser'@'localhost'; then re-create the user with the correct password.
help me fix my MariaDB moodleuser access issue
Configure PHP settings for Moodle
Moodle forms submit large amounts of data when you create quizzes and courses. PHP's default limit for form input variables is too low and will cause silent data loss.
- Open the PHP configuration file in a text editor by running:
sudo nano /etc/php/8.3/apache2/php.ini
- Press Ctrl+W to open the search bar in nano.
- Type max_input_vars and press Enter to jump to that setting.
- You will see a line that reads ;max_input_vars = 1000 (the semicolon means it is commented out).
- Remove the semicolon at the beginning of the line and change 1000 to 5000 so it reads:
max_input_vars = 5000
- Save the file by pressing Ctrl+O then Enter.
- Exit nano by pressing Ctrl+X.
- Restart Apache so the new PHP setting takes effect by running:
sudo systemctl restart apache2
Before you verify, what do you think the output of checking max_input_vars will show now?
- Confirm the setting was applied by running:
php -c /etc/php/8.3/apache2/php.ini -r "echo ini_get('max_input_vars');"
You should see 5000 printed to the terminal.
Still seeing 1000?
Make sure you edited the correct file at /etc/php/8.3/apache2/php.ini (not the CLI config at /etc/php/8.3/cli/php.ini). Also confirm you removed the semicolon from the beginning of the line.
help me fix my PHP max_input_vars setting
Your server now has everything Moodle needs to run. Next up, you will download Moodle itself and see your school live in a browser for the first time.
Install Moodle and See Your School Live
Your LAMP stack is up and running. Apache serves web pages, MariaDB stores data, and PHP 8.3 is ready to execute application code.
Now you need the application itself. In this step, you will download Moodle 4.5 LTS using Git, run its command-line installer to build all the database tables, and see your school's homepage live in a browser for the first time.
In this step, get ready to:
- Clone Moodle 4.5 LTS from the official Git repository into your web root.
- Run the Moodle CLI installer to create database tables and generate your site configuration.
- Set up a cron job and lock down file permissions so Moodle runs securely.
Clone Moodle into your web root
Moodle's source code lives in a public Git repository. Cloning it means future upgrades are a single git pull command instead of downloading and extracting ZIP files.
- Clone the Moodle 4.5 LTS stable branch into your web root by running this command:
sudo git clone -b MOODLE_405_STABLE git://git.moodle.org/moodle.git /var/www/html/moodle
What does this command do?
- git clone downloads the full repository to your server.
- -b MOODLE_405_STABLE selects the long-term support branch that receives security fixes until October 2027.
- /var/www/html/moodle places the code inside Apache's document root so it is accessible at http://your-server-ip/moodle.
- Confirm the clone succeeded by listing the new directory:
ls /var/www/html/moodle
You should see Moodle's files and folders, including admin, lib, course, and version.php.
Clone failing or taking too long?
- If you see a connection error, make sure your server has internet access. Try ping google.com to check.
- The Moodle repository is large (several hundred MB). On a slow connection it can take 5-10 minutes. Let it finish.
- help me troubleshoot the git clone failing
- Create the Moodle data directory and set ownership so the web server can write to it:
sudo mkdir /var/www/moodledata
sudo chown www-data:www-data /var/www/moodledata
Why a separate data directory?
Moodle stores uploaded files, session data, and cache outside the web root for security. Placing /var/www/moodledata one level above /var/www/html means browsers cannot directly access student uploads or internal cache files.
- Verify the directory exists and is owned by www-data:
ls -ld /var/www/moodledata
You should see www-data www-data in the ownership columns.
Run the Moodle CLI installer
The installer creates all of Moodle's database tables, generates the config.php file, and sets your school name and admin credentials in one command.
- Before the installer can write config.php, the web server user needs temporary write access to the Moodle directory. Grant it by running:
sudo chown www-data /var/www/html/moodle
- Run the Moodle CLI installer as the www-data user by running this command:
sudo -u www-data /usr/bin/php /var/www/html/moodle/admin/cli/install.php \
--wwwroot=http://[[SERVER_IP="your server's IP address"]]/moodle \
--dataroot=/var/www/moodledata \
--dbtype=mariadb \
--dbhost=localhost \
--dbname=moodle \
--dbuser=moodleuser \
--dbpass=your-database-password-here \
--fullname="[[SCHOOL_NAME="your school name, e.g. Liberty Academy"]]" \
--shortname="[[SCHOOL_SHORT="a short version, e.g. Liberty"]]" \
--adminuser=admin \
--adminpass=your-admin-password-here \
--agree-license \
--non-interactive
What do these flags mean?
- --wwwroot is the URL students will use to reach your site.
- --dataroot points to the data directory you just created.
- --dbtype=mariadb tells Moodle you are using MariaDB (not MySQL or PostgreSQL).
- --dbuser and --dbpass are the credentials you created in Step 1 for moodleuser.
- --fullname is the name that displays at the top of your site. Pick something meaningful to you.
- --agree-license accepts the Moodle GPL license so the install can proceed without prompting.
- --non-interactive runs the installer silently with no prompts.
Choose a strong admin password
Your admin password must contain at least 8 characters, including uppercase, lowercase, a digit, and a special character. Moodle enforces this by default and the installer will fail if your password is too weak.
The installer takes 1-2 minutes as it creates hundreds of database tables. When it finishes, you will see a success message ending with the URL of your new site.
Installer showing an error?
- If you see a database connection error, double-check that the --dbpass value matches the password you set for moodleuser in Step 1.
- If you see a permissions error on config.php, make sure you ran the chown www-data /var/www/html/moodle command before the installer.
- If it says the password policy is not met, choose a stronger admin password with mixed case, a number, and a symbol.
- help me fix the Moodle CLI installer error
- Confirm the installation created config.php by running:
ls /var/www/html/moodle/config.php
You should see the file path printed with no error. This file holds your database connection details and site settings.
Set up the cron job and lock down file permissions
Moodle relies on a scheduled task runner (cron) for sending emails, cleaning up sessions, and processing grades. Without it, your site will display a warning and many features will not work.
- First, lock down file ownership so that the Moodle application code is read-only for the web server. This prevents a compromised plugin from modifying core files:
sudo chown -R root:root /var/www/html/moodle
- Verify the ownership changed by running:
ls -ld /var/www/html/moodle
You should see root root in the ownership columns. The web server can still read the files, but cannot write to them.
- Set up the Moodle cron job to run every minute by running:
sudo crontab -e
What will crontab -e show?
This opens the root user's cron table in a text editor. If prompted to choose an editor, select nano (usually option 1) as it is the simplest.
- Add this line at the bottom of the file, then save and exit (in nano: Ctrl+O, Enter, Ctrl+X):
* * * * * /usr/bin/php /var/www/html/moodle/admin/cli/cron.php
What does this cron line do?
- * * * * * means "every minute of every hour of every day."
- The command executes Moodle's scheduled task processor. It handles email queues, grade calculations, course backups, and dozens of other background jobs.
- Verify the cron job was saved by running:
sudo crontab -l
You should see your new cron line in the output: * * * * * /usr/bin/php /var/www/html/moodle/admin/cli/cron.php.
Cron line not showing up?
- If crontab -l shows nothing, re-run sudo crontab -e and make sure you saved the file before exiting (Ctrl+O in nano).
- Make sure you typed the full path /usr/bin/php and not just php. Cron does not use your shell's PATH variable.
- help me set up the Moodle cron job
Before you open your browser, what do you think you will see when you visit your Moodle URL for the first time?
- Open a browser on any computer on the same network as your server.
- Navigate to http://your server's IP address/moodle.
You should see the Moodle dashboard with your school name displayed at the top. You are logged in as the admin user you created during installation.
Seeing a blank page or error in the browser?
- Make sure Apache is running: sudo systemctl status apache2. If it is not active, start it with sudo systemctl start apache2.
- Double-check you are using the correct IP address. Run hostname -I on your server to confirm.
- If you see a PHP error about missing extensions, verify all PHP 8.3 extensions are installed from Step 1.
- help me access my Moodle site in the browser
Your online school is live. Next up, you will fill it with real course content so students have something to learn.
Create Your First Course with Video Lessons
Your school is live and accessible in a browser, but right now it is an empty platform with nothing for students to learn.
A school without courses is just an empty website. In this step, you will create your first real course with organized topics and embedded video content, giving students something to actually learn from.
In this step, get ready to:
- Create a course category and a new course with the Topics format.
- Add video lessons and text study guides to each topic.
- Set a course description and image so it displays attractively in the catalog.
Create a course category and course
Courses in Moodle are organized into categories, similar to how subjects are grouped in a school curriculum. You will create a category first, then create a course inside it.
- In your browser, make sure you are logged into your Moodle site as the admin.
- Click Site administration in the left navigation panel.
- Click the Courses tab.
- Click Manage courses and categories.
- Click the Create new category link.
- Enter Core Subjects as the category name.
- Click Create category.
You should now see Core Subjects listed in the category panel on the left side of the page.
- Click on Core Subjects to select it.
- Click New course in the course listing panel on the right.
- In the Course full name field, enter Introduction to American History.
- In the Course short name field, enter HIST101.
- Scroll down to the Course format section and expand it.
- Set the Format dropdown to Topics.
- Set the Number of sections to 2 (one per lesson).
- Scroll to the bottom and click Save and display.
You land on the course enrollment page. Click Proceed to course content to view your new course.
You should see your course page with two empty topic sections, ready for content.
What is the Topics format?
The Topics format organizes your course into numbered sections (Topic 1, Topic 2, etc.) that you can rename to match your lessons. Each topic acts as a container for activities and resources like videos, readings, and quizzes.
Don't see your course?
Make sure you clicked Save and display (not Save and return). If you saved and returned, navigate back to Site administration > Courses > Manage courses and categories, click Core Subjects, and then click on your course name to open it.
help me find my course in Moodle after creating it
Add video and text resources to Topic 1
Each topic in your course needs learning content. You will add a URL resource pointing to a video and a Page resource with a text study guide.
- On your course page, enable editing by clicking the Edit mode toggle at the top right of the page.
- In Topic 1, click Add an activity or resource.
- Select URL from the activity chooser.
- In the Name field, enter a title for the video lesson (e.g., Lesson 1: The Founding Era).
- In the External URL field, paste the full URL of a video. Use any YouTube video URL or other hosted video link.
- Click Save and return to course.
You should see your URL resource appear in Topic 1 with a link icon next to its name.
- In Topic 1 again, click Add an activity or resource.
- Select Page from the activity chooser.
- In the Name field, enter a title (e.g., Study Guide: The Founding Era).
- In the Page content editor, type a brief summary of the lesson. Include key points, important dates, or discussion questions that relate to the video.
- Click Save and return to course.
Topic 1 now has both a video link and a text study guide. You should see two items listed under Topic 1.
Why use URL and Page resources?
A URL resource links to external video content (YouTube, Vimeo, or your own hosted video) without requiring you to upload large video files to your server. A Page resource lets you create formatted text directly in Moodle using the built-in editor.
This combination mirrors how professional online schools like Hillsdale Online Courses deliver content: a video lecture paired with a written study guide for each lesson.
- Now repeat the process for Topic 2. Click Add an activity or resource in Topic 2.
- Select URL and enter a name for your second video lesson (e.g., Lesson 2: The Constitutional Convention).
- Paste a video URL in the External URL field and click Save and return to course.
- Click Add an activity or resource in Topic 2 again.
- Select Page, enter a name (e.g., Study Guide: The Constitutional Convention), add summary text to the content editor, and click Save and return to course.
Both Topic 1 and Topic 2 now have a video lesson and a study guide. You should see two items listed under each topic.
Not seeing the Add an activity or resource link?
Make sure Edit mode is enabled (the toggle at the top right should be turned on). The link to add resources only appears when editing is active.
help me enable editing mode in my Moodle course
Add a course description and image
Your course has content, but it needs a description and an image to look attractive in the course catalog. This is what students see before they decide to enroll.
- On your course page, click Settings in the course navigation (or go to the gear icon and select Edit settings).
- Scroll down to the Description section and expand it.
- In the Course summary editor, write a brief description of your course. For example: "Explore the key events and ideas that shaped the founding of America, from colonial times through the ratification of the Constitution."
- In the Course image area, upload an image file (a photo, illustration, or graphic related to American history). Drag and drop an image file into the upload area, or click to browse your files.
- Scroll to the bottom and click Save and display.
Finding a course image
You can use any image file from your computer. Search for a public domain image of a historical document, the Constitution, or an American flag. The image appears as a banner on your course card in the catalog.
Before you check the catalog, take a moment to predict what you expect to see. Do you think your course will appear with the image and description you just set?
- Click Home in the top navigation to return to the site homepage.
- Navigate to the course listing. You should see your course card showing the course name, your uploaded image, and the description text.
Your course now appears in the catalog exactly as a student would see it, with an image and description that communicates what the course is about.
Course image not showing?
Make sure you uploaded an image in a supported format (JPG, PNG, or GIF). If you used a very large file, try a smaller image (under 2MB). Also confirm you clicked Save and display after uploading.
help me troubleshoot my course image not displaying in Moodle
Your first course is built. It has organized topics, video lessons, study guides, and an attractive catalog listing. Next up, you will enable students to actually sign up and enroll themselves.
Enable Student Self-Enrollment
Your course has video lessons, study resources, and a polished description in the catalog. It looks great. But right now, only you can access it.
By default, Moodle requires an admin to manually create every student account and enroll them into each course. In this step, you'll open your school to the public by enabling self-registration and self-enrollment so anyone can sign up and start learning on their own.
In this step, get ready to:
- Enable email-based self-registration so visitors can create their own accounts.
- Add self-enrollment to your course so students can join without admin approval.
- Test the full student flow from account creation to course access.
Enable email-based self-registration
Before changing any settings, let's see what your school looks like to a brand new visitor right now.
- Click your user icon in the top-right corner of the Moodle dashboard.
- Click Log out.
Before you look at the login page, what do you think a new visitor sees? Is there a way for them to create an account?
Look at the login page now. You see username and password fields, but there is no "Create new account" button anywhere. A new visitor has no way to sign up. That is the gap. Every single student would need you to manually create their account before they could access anything.
Why is registration locked by default?
Moodle ships with self-registration disabled to prevent spam accounts. For a private school platform, this makes sense. For your public school where you want anyone to enroll freely, you need to explicitly open it up.
Now let's fix this. Log back in with your admin credentials.
- Enter your admin username and password, then click Log in.
- Click Site administration in the left navigation menu.
- Click the Plugins tab.
- Scroll to the Authentication section and click Manage authentication.
- Find Email-based self-registration in the list of authentication plugins.
- Click the crossed-out eye icon next to it to enable the plugin. The icon changes to an open eye.
- Scroll down on the same page to the Common settings section.
- Find the Self registration dropdown and select Email-based self-registration.
- Click Save changes.
Why are there two settings?
Enabling the plugin allows existing self-registered users to log in. Setting it as the self-registration method allows new visitors to create accounts. You need both for the full flow to work.
After saving, the login page now displays "Is this your first time here?" instructions and a Create new account button.
Don't see the Self registration dropdown?
Make sure you scrolled past all the authentication plugins. The Common settings section is further down the same page, underneath the full plugin list.
help me find the Self registration dropdown in Moodle's Manage authentication page
Add self-enrollment to your course
Visitors can now create accounts on your site. But creating an account does not automatically give them access to courses. You need to enable self-enrollment on each course individually.
- Click Site administration in the left navigation menu, or use the site home link to return to the dashboard.
- Navigate to your Introduction to American History course by clicking on it from the course list or the dashboard.
- Click Participants in the course navigation menu.
- Click the dropdown menu and select Enrolment methods.
- Find Self enrolment (Student) in the list.
- Click the eye icon next to it to enable self-enrollment. The icon changes to an open eye.
What about an enrolment key?
An enrolment key acts like a course password. Only students who know the key can enroll themselves. For a free, open school where anyone can join, leave the key blank. If you want to restrict access to a specific group, click the settings (gear) icon next to Self enrolment and add a key there.
Don't see Self enrolment (Student) in the list?
The Self enrolment plugin must be enabled at the site level. Go to Site administration > Plugins > Enrolments > Manage enrol plugins and make sure Self enrolment has an open eye icon.
help me enable the Self enrolment plugin site-wide in Moodle
Test the full student flow
Both settings are now in place. Time to walk through the experience exactly as a new student would.
- Open a private or incognito browser window. This ensures you are not logged in.
- Navigate to your Moodle site at http://your-server-ip/moodle.
- On the login page, look for the "Is this your first time here?" section.
- Click Create new account.
What about email confirmation?
Moodle normally sends a confirmation email before activating the account. On a local server without a mail server configured, the email will not send. If prompted to confirm your email, log back in as admin and manually confirm the test user from Site administration > Users > Browse list of users. Find the new account and click Confirm.
- Fill in the registration form with a test username, password, email, first name, and last name.
- Click Create my new account.
- Once the account is active (either via email confirmation or manual admin confirmation), log in as the test student.
- From the dashboard or site home, find Introduction to American History in the course catalog.
- Click the course name.
- Click Enrol me (or the self-enrollment button that appears).
What do you think you will see after clicking Enrol me? Will you have access to the video lessons and study guides from Step 3?
You land on the course page. You can see both topics with their video links and Page resources, exactly as you created them. Your test student is now enrolled and can view all course content.
Course not showing in the catalog?
Make sure you set the course to be visible. Go back to your admin account and check the course settings. Under Course visibility, ensure it is set to Show.
help me make my Moodle course visible in the catalog
Your school is now open for business. Anyone can visit, create a free account, and enroll in your course. Next up, you'll add quizzes and a completion certificate to turn your course into a real educational experience with measurable outcomes.
Add Quizzes and a Completion Certificate
In the previous step, you opened your course to the world by enabling self-registration and self-enrollment. Students can now sign up, browse your catalog, and start learning.
But right now, your course is just a playlist of videos with no way to measure learning or motivate students to finish. Adding quizzes and a completion certificate transforms it into a structured educational experience where students prove mastery and walk away with tangible proof of what they learned.
In this step, get ready to:
- Add quiz activities with multiple choice questions and a 70% passing grade.
- Enable completion tracking so Moodle knows when a student finishes.
- Install and configure a certificate that generates automatically as a PDF.
Add a quiz to Topic 1
Quizzes in Moodle are activity modules that pull questions from a Question Bank. You create the quiz activity first, then add questions to it.
- Navigate to your Introduction to American History course.
- Click the Edit mode toggle in the top-right corner to turn editing on.
- In Topic 1, click Add an activity or resource.
- Select Quiz from the activity chooser.
- Enter a name for the quiz, such as Topic 1 Quiz.
- Expand the Grade section.
- Set the Grade to pass field to 70.
- Click Save and display.
You now see the empty quiz page with an Add question button.
- Click Add question.
- Click + a new question.
- Select Multiple choice as the question type, then click Add.
- Fill in the question name, question text, and answer choices. Give the correct answer a grade of 100% and leave incorrect answers at None.
- Click Save changes.
- Repeat the process to add 2 more multiple choice questions (3 total for this quiz).
What does the 70% passing grade mean?
With 3 questions worth 1 point each, the quiz maximum grade is 3. A 70% pass threshold means a student needs to score at least 2.1 out of 3 (effectively getting 3 out of 3 correct, since partial marks are not awarded on standard multiple choice).
If you add 5 questions instead, students would need 4 out of 5 correct to pass. More questions give you a more meaningful pass threshold.
You should see your quiz with 3 questions listed and a total maximum grade displayed at the top.
Not seeing the question type selector?
Make sure you clicked + a new question (not + from question bank). The type selector only appears when creating a new question.
Help me fix the question type selector not appearing.
Add a quiz to Topic 2
- Click on your course name in the breadcrumb navigation to return to the course page.
- In Topic 2, click Add an activity or resource.
- Select Quiz from the activity chooser.
- Enter a name such as Topic 2 Quiz.
- Expand the Grade section and set Grade to pass to 70.
- Click Save and display.
- Click Add question, then + a new question.
- Add 3 multiple choice questions related to Topic 2 content, giving each correct answer 100%.
- Click Save changes after each question.
Return to your course page. You should now see both Topic 1 and Topic 2 each showing a Quiz activity alongside the existing video and page resources.
Enable completion tracking and set conditions
Completion tracking tells Moodle how to determine when a student has finished each activity. Without it, Moodle has no way to know whether a student watched a video or passed a quiz.
- Go to Site administration in the left sidebar.
- Click Advanced features.
- Confirm that Enable completion tracking is ticked. If not, tick it and click Save changes.
Why enable completion at the site level first?
Completion tracking must be enabled in two places: once at the site level (which you just confirmed) and once in your course settings. The site-level setting unlocks the feature, and the course-level setting activates it for your specific course.
- Navigate back to your Introduction to American History course.
- Click the gear icon or go to Settings in the course navigation.
- Expand the Completion tracking section.
- Set Enable completion tracking to Yes.
- Click Save and display.
Now you need to set completion conditions on each activity in the course.
- On your course page, click on your Topic 1 video URL resource.
- Click Settings (gear icon) to open the activity settings.
- Expand the Activity completion section.
- Set Completion tracking to Show activity as complete when conditions are met.
- Tick Require view so the activity completes when a student views it.
- Click Save and return to course.
- Repeat for the Topic 2 video URL resource with the same view condition.
Next, set the completion conditions for your quizzes.
- Click on your Topic 1 Quiz activity.
- Open its Settings (gear icon).
- Expand the Activity completion section.
- Set Completion tracking to Show activity as complete when conditions are met.
- Tick Require grade.
- Tick Require passing grade.
- Click Save and return to course.
- Repeat for the Topic 2 Quiz with the same grade and passing grade conditions.
On your course page, you should now see small circles (completion indicators) next to each activity, showing that completion tracking is active.
Don't see completion indicators on the course page?
Make sure you enabled completion tracking at both levels: the site level (Site administration then Advanced features) and the course level (course Settings then Completion tracking set to Yes). Both must be enabled for the indicators to appear.
Help me troubleshoot completion tracking not appearing on my course page.
Install the Course Certificate plugin and configure certificates
Moodle does not include certificates out of the box. You need to install two plugins: the Certificate manager (tool_certificate) for designing templates, and the Course certificate activity (mod_coursecertificate) for issuing them to students.
- In your browser, go to Site administration in the left sidebar.
- Click Plugins.
- Click Install plugins.
- Click the Install plugins from the Moodle plugins directory button.
- Search for tool_certificate and click Install on the Certificate manager plugin.
- Confirm the installation request and wait for the validation report.
- Click Continue to finalize the installation.
What if Install plugins is not available?
If your Moodle installation does not allow installing plugins from the web interface (for example, the web server user does not have write access to the plugin directories), you can install manually. Download the plugin ZIP from moodle.org/plugins, copy it to your server, and extract it into the correct directory. For tool_certificate, extract into /var/www/html/moodle/admin/tool/. For mod_coursecertificate, extract into /var/www/html/moodle/mod/. Then visit Site administration then Notifications to complete the database upgrade.
- Return to Site administration then Plugins then Install plugins.
- Click Install plugins from the Moodle plugins directory again.
- Search for mod_coursecertificate and click Install on the Workplace course certificate plugin.
- Confirm the installation and click Continue.
- Moodle detects the new plugins and displays an upgrade page. Click Upgrade Moodle database now.
- Wait for the upgrade to complete, then click Continue.
You should see a success message confirming both plugins are installed.
What do these two plugins do together?
The Certificate manager (tool_certificate) lets you design certificate templates with dynamic fields like the student's name, the course name, and completion date.
The Course certificate activity (mod_coursecertificate) is what you add to a course. It automatically issues a PDF certificate to students who satisfy the access restrictions you configure.
Now create a certificate template.
- Go to Site administration then Certificates.
- Click New certificate template.
- Enter a name such as Course Completion Certificate.
- Click Save.
- On the template editor page, add elements such as the student's full name, course name, and date issued using the Add element dropdown.
- Click Save when your template looks good.
You should see a preview of your certificate template with the dynamic fields displayed.
Finally, add the certificate activity to your course with the correct access restriction.
- Navigate back to your Introduction to American History course.
- Turn editing on if it is not already on.
- Below the last topic, click Add an activity or resource.
- Select Course certificate from the activity chooser.
- Select your Course Completion Certificate template from the dropdown.
- Expand the Restrict access section.
- Click Add restriction.
- Select Activity completion.
- Add a restriction for each activity in your course (both video resources and both quizzes), requiring each to show as complete.
- Click Save and return to course.
Why restrict access based on activity completion?
The access restriction makes the certificate invisible until a student has completed every other activity. This prevents students from downloading a certificate without actually finishing the course.
Once all activities show as complete, the certificate activity appears and automatically generates a personalized PDF.
Your course page should now show the Course certificate activity at the bottom, grayed out with a message indicating the access restrictions.
Certificate activity not showing up in the activity chooser?
Make sure both plugins installed successfully. Go to Site administration then Plugins then Plugins overview and search for certificate. You should see both tool_certificate and mod_coursecertificate listed as enabled.
Help me troubleshoot the Course Certificate plugin not appearing in my Moodle activity chooser.
Test the full student experience
Before you consider this step done, you need to verify the entire flow works from a student's perspective. What do you think will happen when your test student views the videos and passes both quizzes?
- Open a private or incognito browser window.
- Navigate to your Moodle site and log in with your test student account.
- Open the Introduction to American History course.
- Click on the Topic 1 video resource to mark it as viewed.
- Click on the Topic 2 video resource to mark it as viewed.
- Attempt the Topic 1 Quiz and answer enough questions correctly to pass (70% or higher).
- Attempt the Topic 2 Quiz and pass it as well.
- Return to the course page. The Course certificate activity should now be visible (no longer grayed out).
Cron must run for completion to update
Moodle updates completion status via its cron job, which you configured to run every minute. If the certificate does not appear immediately after passing the quizzes, wait 1-2 minutes for the cron to process the completion events, then refresh the page.
- Click on the certificate activity. You should be able to download a PDF certificate with your student name and course details.
You now see a completion certificate available for download as a PDF. Your course is a complete, structured learning experience with assessments and proof of completion.
Your online school now mirrors the Hillsdale model: students sign up, watch lessons, pass quizzes, and earn a certificate. Next up, you'll customize the look and feel of your school so it feels like a professional academy instead of default Moodle.
Secret mission
Customize Your School's Theme and Homepage
Your school works perfectly, but it still looks like default Moodle with generic branding. A professional online academy needs a distinctive look that makes students feel they're at YOUR school. In this mission, you'll brand your site with a custom logo, color scheme, welcome message, and clean footer.
Clean Up Your Resources
Clean Up Your Resources
This project runs entirely on your own Ubuntu server, so there are no ongoing cloud costs or subscription fees. Decide whether to keep your resources running, pause them to come back later, or delete them entirely.
Resources you used:
- Apache2 web server running on port 80.
- MariaDB database server with the moodle database and moodleuser account.
- Moodle application files at /var/www/html/moodle.
- Moodle data directory at /var/www/moodledata.
- Cron job running every minute for Moodle scheduled tasks.
- PHP 8.3 and extensions installed from the Sury repository.
Keep everything running
No action needed. Choose this if your school is live and you want students to continue accessing courses.
- Your school remains accessible at http://your-server-ip/moodle.
- Students can continue to register, enroll, take quizzes, and earn certificates.
- Consider setting up a domain name and an SSL certificate (Let's Encrypt via certbot) to make your school publicly accessible with HTTPS.
- PHP 8.3, Git, and the Sury PHP repository will remain installed on the server.
Pause - I'll come back to this later
Stop the web server and database to free up system resources while keeping all your files, courses, and configuration intact.
- Stop Apache and MariaDB by running:
sudo systemctl stop apache2 mariadb
- Your school will be inaccessible until you start the services again.
- When you're ready to resume, start them again by running:
sudo systemctl start apache2 mariadb
- All your courses, student accounts, quiz results, and certificates are preserved in the database and data directory.
Delete - I don't want to use this again
Remove all Moodle files, drop the database, remove the cron job, and uninstall the packages. This cannot be undone.
- Remove the Moodle cron job by running:
sudo crontab -u www-data -r
- Remove the Moodle application files and data directory by running:
sudo rm -rf /var/www/html/moodle /var/www/moodledata
- Drop the Moodle database and remove the database user by running:
sudo mysql -e "DROP DATABASE moodle;"
sudo mysql -e "DROP USER 'moodleuser'@'localhost';"
- Uninstall Apache, MariaDB, PHP 8.3, and related packages by running:
sudo apt purge apache2 mariadb-server mariadb-client php8.3* libapache2-mod-php8.3 git -y
sudo apt autoremove -y
- Optionally remove the Sury PHP repository by running:
sudo rm /etc/apt/sources.list.d/php.list
sudo apt update
Nice Work!
Nice Work!
You just built a fully functional online school from scratch on your own server. Students can visit your site, create an account, enroll in courses, watch video lessons, pass quizzes, and download a completion certificate.
You've learned how to:
- Install a complete LAMP stack with PHP 8.3 on Ubuntu 26.04, working around the default PHP 8.5 incompatibility by adding the Sury repository.
- Deploy Moodle 4.5 LTS from Git and configure a production-grade LMS with self-registration, self-enrollment, and a structured course containing video lessons, quizzes, and resources.
- Build automated assessments with pass thresholds, completion tracking across all activities, and automatic certificate generation so students earn a downloadable PDF when they finish the course.
- Secret Mission: Branded your school with custom colors, a logo, and a configured homepage layout so it looks like a professional academy instead of default Moodle.
Ready to quiz yourself?