Skip to content
Infrastructure Tutorial3 min read

Moodle Migration Zero-Downtime Checklist (VPS + CloudPanel)

Roomi Kh

Published February 18, 2026Reviewed July 3, 2026

Moodle zero-downtime migration checklist illustration for VPS and CloudPanel

Use this when migrating a live Moodle LMS from shared hosting to VPS.

Related deep-dive: The Real-World Moodle Migration Playbook.

Zero-Downtime Migration Goals

A Moodle migration is not done when the homepage loads. It is done when learners, instructors, scheduled tasks, uploads, email, reports, and backups all behave correctly on the new host.

For a low-risk cutover, define the acceptance criteria before touching DNS:

  • users can log in with existing accounts
  • active courses, assignments, quizzes, grades, and media load correctly
  • Moodle cron runs without fatal errors
  • email notifications still leave the server
  • moodledata permissions are correct and not web-accessible
  • backups exist on both source and target before cutover
  • rollback is possible if the new server fails acceptance testing

Prerequisites

  • Full backup access on source server
  • Target VPS (Ubuntu + PHP 8.2 + MariaDB)
  • Maintenance/cutover window

Cutover Risk Matrix

| Risk | Symptom | Prevention | Rollback Trigger | | --- | --- | --- | --- | | DNS cache delay | Some users hit old server | Lower TTL 24-48 hours early | Traffic split causes data divergence | | Missing moodledata files | Broken course media or uploads | Dry-run rsync and final rsync | Course files unavailable after cutover | | PHP extension mismatch | HTTP 500 or blank pages | Compare Moodle environment report | Upgrade script fails on target | | Cron failure | Delayed emails, stale completion data | Run cron manually before DNS switch | Cron errors continue after fix attempt | | Permission error | Uploads fail or cache cannot write | Verify ownership and dataroot path | Users cannot submit files |

For high-traffic learning portals, put the source in maintenance mode for the final database export. That short freeze is often safer than accepting writes on two servers.

Step-by-Step

Step 1: Export source database

BASH
mysqldump -u USER -p DBNAME > moodle.sql

Step 2: Import into target database

BASH
mysql -u USER -p DBNAME < moodle.sql

Step 3: Sync moodledata and permissions

BASH
rsync -avz /old/moodledata/ /new/moodledata/
chown -R www-data:www-data /new/moodledata
chmod -R 755 /new/moodledata

Step 4: Update config.php

PHP
$CFG->wwwroot  = 'https://yourdomain.com';
$CFG->dataroot = '/home/user/moodledata';
$CFG->dbname   = 'dbname';
$CFG->dbuser   = 'dbuser';
$CFG->dbpass   = 'dbpass';

Step 5: Install required PHP extensions

BASH
apt install -y php8.2-xml php8.2-mysql php8.2-gd php8.2-curl \
  php8.2-zip php8.2-mbstring php8.2-intl php8.2-soap
systemctl restart php8.2-fpm

Step 6: Run Moodle CLI maintenance

BASH
php admin/cli/upgrade.php
php admin/cli/purge_caches.php
php admin/cli/cron.php

Step 7: Cutover sync and DNS switch

BASH
mysqldump -u USER -p live_db > final.sql
mysql -u USER -p new_db < final.sql
rsync -avz /old/moodledata/ /new/moodledata/

Switch DNS only after login, courses, upload, and cron are verified.

DNS and Communication Timeline

Use a simple launch timeline:

  1. 48 hours before: lower DNS TTL, confirm backups, and announce a maintenance window.
  2. 24 hours before: complete a dry-run import and compare Moodle environment checks.
  3. Cutover start: enable source maintenance mode and take the final database export.
  4. Cutover validation: run login, course, file upload, quiz, gradebook, and cron checks.
  5. DNS switch: update the record only after the target passes validation.
  6. First 24 hours: monitor logs, cron, email delivery, and helpdesk reports.

Keep one person responsible for the technical cutover and one person responsible for stakeholder updates. Mixing those roles during a live LMS migration creates avoidable mistakes.

Rollback Plan

Rollback should be written before the move begins.

The basic rollback path is:

  • keep the source server unchanged until the target is accepted
  • keep DNS records and provider access documented
  • retain source database and moodledata backups
  • if target validation fails, point DNS back to the source
  • communicate that the migration is paused, not partially complete

Do not continue troubleshooting on the new host while learners are blocked unless the fix is clearly faster than rollback.

Fast Troubleshooting

  • HTTP 500: re-check config.php, PHP extensions, and permissions.
  • Missing courses/media: re-sync moodledata, then purge caches.
  • Theme issues: deploy theme code, rerun upgrade + purge.
  • Login loops: confirm $CFG->wwwroot, HTTPS proxy settings, and session storage.
  • Email failures: verify SMTP settings, SPF/DKIM alignment, and outbound mail rules.

For migration implementation support, see Custom Web Development or Contact ValeoFX.

Keep the Thread Going

Continue Reading

Keep moving from insight to action

Use the next article, service, or case study to keep building the thread instead of bouncing back to the index.

Related Tutorials