Overview
A comprehensive backup strategy for ipMoodle includes three critical components: the Moodle codebase, user data files, and the PostgreSQL database. This guide covers backup and restore procedures for all components.
What to Backup
ipMoodle stores data in three primary locations:
Moodle Code ./html - Moodle application files, themes, and plugins
User Data ./moodledata - Uploaded files, course content, user files
Database ./db_data - PostgreSQL data directory
All three components must be backed up together to ensure a consistent restore point. A database backup without corresponding moodledata files will result in broken file references.
Full System Backup
Manual Backup
Enable maintenance mode
Prevent changes during backup: docker exec moodle_app /usr/local/bin/php /var/www/html/admin/cli/maintenance.php --enable
Create database dump
Export the PostgreSQL database: docker exec moodle_db pg_dump -U moodle -d moodle -F c -f /tmp/moodle_backup.dump
docker cp moodle_db:/tmp/moodle_backup.dump ./backups/moodle_db_ $( date +%Y%m%d_%H%M%S ) .dump
Backup volumes
Archive the Moodle directories: tar -czf ./backups/moodle_html_ $( date +%Y%m%d_%H%M%S ) .tar.gz ./html
tar -czf ./backups/moodle_data_ $( date +%Y%m%d_%H%M%S ) .tar.gz ./moodledata
Disable maintenance mode
Resume normal operations: docker exec moodle_app /usr/local/bin/php /var/www/html/admin/cli/maintenance.php --disable
Automated Backup Script
Create a backup script for scheduled execution:
#!/bin/bash
# backup_moodle.sh
BACKUP_DIR = "/opt/backups/moodle"
DATE = $( date +%Y%m%d_%H%M%S )
# Create backup directory
mkdir -p $BACKUP_DIR
# Enable maintenance mode
docker exec moodle_app /usr/local/bin/php /var/www/html/admin/cli/maintenance.php --enable
# Database backup
docker exec moodle_db pg_dump -U moodle -d moodle -F c -f /tmp/backup_ $DATE .dump
docker cp moodle_db:/tmp/backup_ $DATE .dump $BACKUP_DIR /db_ $DATE .dump
docker exec moodle_db rm /tmp/backup_ $DATE .dump
# Volume backups
tar -czf $BACKUP_DIR /html_ $DATE .tar.gz -C /opt/moodleip ./html
tar -czf $BACKUP_DIR /moodledata_ $DATE .tar.gz -C /opt/moodleip ./moodledata
# Disable maintenance mode
docker exec moodle_app /usr/local/bin/php /var/www/html/admin/cli/maintenance.php --disable
# Remove backups older than 30 days
find $BACKUP_DIR -type f -mtime +30 -delete
echo "Backup completed: $DATE "
Make the script executable and schedule it:
chmod +x backup_moodle.sh
# Add to crontab (daily at 2 AM)
echo "0 2 * * * /opt/moodleip/backup_moodle.sh" | crontab -
The backup script automatically removes backups older than 30 days to manage disk space. Adjust the retention period based on your requirements.
Database-Only Backup
For quick database snapshots without volume backups:
# Create backup
docker exec moodle_db pg_dump -U moodle -d moodle > moodle_db_ $( date +%Y%m%d ) .sql
# Compressed backup
docker exec moodle_db pg_dump -U moodle -d moodle | gzip > moodle_db_ $( date +%Y%m%d ) .sql.gz
Restore Procedures
Full System Restore
Restore volumes
Extract backed-up volumes: # Backup existing data (safety measure)
mv ./html ./html.old
mv ./moodledata ./moodledata.old
mv ./db_data ./db_data.old
# Restore from backup
tar -xzf ./backups/moodle_html_TIMESTAMP.tar.gz
tar -xzf ./backups/moodle_data_TIMESTAMP.tar.gz
Restore database
Start only the database container: docker compose up -d db
# Wait for database to be ready
sleep 10
# Drop and recreate database
docker exec moodle_db psql -U moodle -c "DROP DATABASE IF EXISTS moodle;"
docker exec moodle_db psql -U moodle -c "CREATE DATABASE moodle;"
# Restore from dump
docker cp ./backups/moodle_db_TIMESTAMP.dump moodle_db:/tmp/restore.dump
docker exec moodle_db pg_restore -U moodle -d moodle -F c /tmp/restore.dump
Verify restoration
Check that Moodle is accessible and data is intact: docker logs moodle_app
docker exec moodle_app /usr/local/bin/php /var/www/html/admin/cli/check_database_schema.php
Always verify your backups by performing test restores in a separate environment. A backup is only as good as your ability to restore from it.
Database-Only Restore
To restore just the database:
# From SQL dump
docker exec -i moodle_db psql -U moodle -d moodle < moodle_db_backup.sql
# From compressed dump
gunzip -c moodle_db_backup.sql.gz | docker exec -i moodle_db psql -U moodle -d moodle
# From custom format dump
docker cp moodle_db_backup.dump moodle_db:/tmp/restore.dump
docker exec moodle_db pg_restore -U moodle -d moodle -c /tmp/restore.dump
Offsite Backup Storage
Using rsync for Remote Backups
Sync backups to a remote server:
# Sync to remote server
rsync -avz --delete /opt/backups/moodle/ user@backup-server:/backups/moodle/
# Add to backup script
echo "rsync -avz /opt/backups/moodle/ user@backup-server:/backups/moodle/" >> backup_moodle.sh
Cloud Storage Integration
# Install AWS CLI
apt-get install awscli
# Upload to S3
aws s3 sync /opt/backups/moodle/ s3://your-bucket/moodle-backups/
# Add to backup script
echo "aws s3 sync /opt/backups/moodle/ s3://your-bucket/moodle-backups/" >> backup_moodle.sh
# Install gsutil
curl https://sdk.cloud.google.com | bash
# Upload to GCS
gsutil -m rsync -r /opt/backups/moodle/ gs://your-bucket/moodle-backups/
Backup Verification
Regularly verify backup integrity:
# Test database dump
docker exec moodle_db pg_restore --list /tmp/backup.dump
# Verify archive integrity
tar -tzf moodle_html_backup.tar.gz > /dev/null && echo "Archive OK"
# Check backup size
ls -lh /opt/backups/moodle/
Disaster Recovery Checklist
Assess damage
Determine what data was lost or corrupted
Identify recovery point
Choose the most recent clean backup
Provision clean environment
Ensure server has required resources and Docker installed
Restore from backups
Follow the full system restore procedure
Verify data integrity
Test critical functionality and check data consistency
Update DNS if needed
Point domain to new server if recovering on different hardware
Monitor system
Watch logs for errors and performance issues
Backup Best Practices
3-2-1 Rule
Keep 3 copies of your data
Store copies on 2 different media types
Keep 1 copy offsite
For production environments, implement automated backups with at least daily frequency and store copies in geographically separate locations.