Moodle LMS on AWS User Guide
Overview
This image runs Moodle behind nginx, with PHP FPM 8.3 and OPcache enabled. Content and grade data are stored in PostgreSQL 16 on the same instance, bound to the loopback interface only. Moodle scheduled tasks run every minute through a systemd timer so course backups, message delivery, badge issuing, and other lifecycle jobs fire without manual intervention.
Moodle administrator and PostgreSQL credentials are generated on the first boot of every deployed instance. Two instances launched from the same Amazon Machine Image never share passwords. The initial administrator password and the PostgreSQL role password are written to /root/moodle-credentials.txt with mode 0600 so that only the root user can read them.
Moodle reads the HTTP Host header of every request, so the site automatically adopts whatever public DNS name or IP address learners reach the instance on. There is no instance metadata lookup and no value to edit on first boot — deployments behind an Application Load Balancer, a private subnet, or a custom domain all work without changes.
Prerequisites
Before you deploy this image you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network and inbound ports 80 and 443 from the networks your learners will use
- The AWS CLI (version 2) installed locally if you plan to deploy from the command line
Step 1: Launch the Instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for Moodle LMS. Select the cloudimg listing and choose Select, then Continue on the subscription summary.
Pick an instance type of m5.large or larger — the Moodle workload is PHP and PostgreSQL heavy. Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that allows inbound port 22 from your management network and inbound ports 80 and 443 from the networks your learners use. Leave the root volume at the default size or larger.
Select Launch instance. First boot initialisation takes approximately one minute after the instance state becomes Running and the status checks pass.
Step 2: Launch the Instance from the AWS CLI
The following block launches an instance from the cloudimg Moodle Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens ports 22, 80, and 443 as described above.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":64,"VolumeType":"gp3"}}]' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=moodle-lms-01}]'
The command prints a JSON document on success. Note the instance ID, then retrieve its public address once it is running with aws ec2 describe-instances --instance-ids <instance-id> --query "Reservations[].Instances[].PublicIpAddress" --output text.
Step 3: Connect and Retrieve Initial Credentials
Connect over SSH with the key pair you selected and the public IP address from step 2. The SSH login user depends on the operating system of the AMI variant you launched:
| AMI variant | SSH login user |
|---|---|
| Moodle 5.2 on Ubuntu 24.04 | ubuntu |
| Moodle 5.2 on Rocky Linux 9 | ec2-user |
The first boot service runs before the SSH daemon becomes ready, so the credentials file is always in place when you log in for the first time.
ssh <login-user>@<public-ip>
sudo cat /root/moodle-credentials.txt
You will see a plain text file containing the Moodle URL, the administrator username (admin), the administrator password, and the PostgreSQL role, database name, and password. Copy these values somewhere secure (a password manager or encrypted vault). Do not commit them to source control.
From the same SSH session you can confirm the deployment is healthy:
curl -fsS -o /dev/null -w 'login page HTTP %{http_code}\n' http://127.0.0.1/login/index.php
A login page HTTP 200 response confirms the full stack — nginx, PHP and PostgreSQL — is serving Moodle.
Step 4: First Login to the Moodle Web Interface
Open a web browser and navigate to http://<public-ip>/. Moodle redirects the front page to the login form when no session cookie is present.

Enter the administrator username admin and the administrator password from /root/moodle-credentials.txt. Select Log in. On the first successful sign in Moodle records your session and takes you to the administrator dashboard.
Step 5: Administrator Dashboard
The dashboard at /my/ is the starting point for managing your Moodle site. The top navigation bar gives you Dashboard for a personalised view and Site administration for global settings. The Course overview block prompts you to create your first course, and the Timeline block shows upcoming activities. Notifications and messages live in the top right, and the user menu lets you sign out or open your profile and preferences.

Step 6: Change the Administrator Password
For a production deployment rotate the administrator password that was generated on first boot. Select the user menu in the top right of the dashboard, choose Preferences, then User account then Change password. Enter the current password from /root/moodle-credentials.txt, pick a new one that satisfies the Moodle password policy, and select Save changes.
From the command line the same thing can be done with Moodle's CLI tool:
sudo -u www-data php /var/www/moodle/admin/cli/reset_password.php \
--username=admin \
--password='<new-password>' \
--ignore-password-policy
Step 7: Site Administration
Select Site administration in the top navigation bar and then Plugins to review the components installed on your site. The Plugins overview page lists the activity modules, authentication plugins, enrolment plugins, blocks, filters, themes, and local plugins that ship with Moodle. Use the Settings link next to each module to tailor behaviour.

Other frequently used pages under Site administration include Users then Authentication (manual accounts, email signup, LDAP, SAML2), Courses then Course categories (top level structure), and Server then System paths.
Step 8: Create Your First Course
Select Site administration then Courses then Manage courses and categories, choose a category (Moodle ships with a default Category 1), then select Create new course. Enter a course full name, a short name, and confirm the course category. Use Save and display to create the course and open it.

From the course page you can add sections, activities (quizzes, assignments, forums, SCORM packages, H5P), and resources (files, pages, URLs, books). Use Enrolled users under the course Participants menu to add teachers and students.
Step 9: Configure Outbound Email (SMTP)
By default Moodle attempts to send mail through the local sendmail binary. For reliable delivery on a cloud instance configure an external SMTP provider such as Amazon SES, SendGrid, or Mailgun.
Select Site administration then Server then Email then Outgoing mail configuration. Populate the SMTP hosts field with your provider's endpoint (for Amazon SES, email-smtp.<region>.amazonaws.com:587), set SMTP security to TLS, set SMTP authentication type to LOGIN, and enter the SMTP username and password issued by your provider. Set the No-reply address to an address your provider lets you send from. Save and then use Site administration then Server then Test outgoing mail configuration to send a test message.
Step 10: Enable HTTPS with Let's Encrypt
For any production Moodle deployment serve the site over HTTPS so session cookies and authentication tokens cannot be intercepted. The image ships with nginx, which certbot can configure automatically.
The following assumes you have a DNS record pointing your fully qualified domain name at the instance's public IP address.
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d moodle.your-domain.example \
--non-interactive --agree-tos -m you@your-domain.example \
--redirect
After certbot finishes, run sudo -u www-data php /var/www/moodle/admin/cli/purge_caches.php so Moodle rebuilds its theme cache under the new HTTPS base URL.
Step 11: Backups and Maintenance
Moodle has two data sources that must be backed up together: the PostgreSQL database and the moodledata directory at /var/www/moodledata (course files, user files, session data, caches).
sudo -u postgres pg_dump -Fc moodle > /var/backups/moodle-db-$(date +%F).dump
sudo tar --acls --xattrs -czf /var/backups/moodle-data-$(date +%F).tgz -C /var/www moodledata
Ship both artifacts to an Amazon S3 bucket or another object store. The Moodle cron timer installed with the image also triggers scheduled course backups if you enable them under Site administration then Courses then Backups.
For kernel and package updates, Ubuntu's unattended-upgrades is enabled by default — security patches apply automatically. To install non security upgrades run sudo apt-get update && sudo apt-get -y upgrade.
Step 12: Scaling Beyond a Single Instance
For larger deployments decouple Moodle from the single instance pattern:
- Move PostgreSQL to Amazon RDS for PostgreSQL and update
$CFG->dbhostand$CFG->dbpassin/var/www/moodle/config.php - Put the Moodle web tier behind an Application Load Balancer and scale horizontally with an Auto Scaling group, with
/var/www/moodledataon Amazon EFS shared storage - Offload session storage to Amazon ElastiCache for Redis via Moodle's
session_handler_classsetting - Push static assets to Amazon S3 via the Moodle
tool_objectfsplugin
Each of these is documented in the official Moodle admin documentation at https://docs.moodle.org/ under "Performance recommendations".
Support
cloudimg provides 24/7/365 expert technical support for this image. Guaranteed response within 24 hours, one hour average for critical issues. Contact support@cloudimg.co.uk.
For general Moodle administration questions consult the community forums at https://moodle.org/ and the documentation at https://docs.moodle.org/.