Lewati ke isi

Backup & Restore SOP - Scola ERP System

Version: 1.0
Date: March 1, 2026
Scope: Production database and file storage backup/restore procedures
RTO (Recovery Time Objective): < 1 hour
RPO (Recovery Point Objective): < 15 minutes


1. Overview

This document outlines the Standard Operating Procedures (SOP) for backing up and restoring the Scola ERP system, including: - PostgreSQL database backups - File storage backups (attachments, uploads) - Automated backup schedules - Disaster recovery procedures


2. Backup Strategy

2.1 Backup Types

Type Frequency Retention Storage Location
Full Database Daily (2 AM) 30 days /backups/database/ + S3
Incremental DB Every 6 hours 7 days /backups/database/incremental/
File Storage Daily (3 AM) 30 days /backups/filestore/ + S3
Transaction Logs Continuous 7 days /backups/wal/

2.2 Backup Components

Database: - PostgreSQL database dump (pg_dump) - All Odoo databases (scola_production, scola_test) - Database roles and permissions

File Storage: - Odoo filestore (/opt/odoo/.local/share/Odoo/filestore/) - Uploaded attachments - Generated reports - Session files

Configuration: - Odoo configuration files (odoo.conf) - Nginx configuration - SSL certificates - Environment variables


3. Database Backup Procedures

3.1 Manual Full Backup

#!/bin/bash
# Manual database backup script

# Configuration
DB_NAME="scola_production"
BACKUP_DIR="/backups/database"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${TIMESTAMP}.dump"

# Create backup directory if not exists
mkdir -p ${BACKUP_DIR}

# Perform backup
echo "Starting backup of ${DB_NAME}..."
pg_dump -U odoo -F c -b -v -f ${BACKUP_FILE} ${DB_NAME}

# Verify backup
if [ $? -eq 0 ]; then
    echo "Backup successful: ${BACKUP_FILE}"

    # Compress backup
    gzip ${BACKUP_FILE}
    echo "Compressed: ${BACKUP_FILE}.gz"

    # Calculate checksum
    md5sum ${BACKUP_FILE}.gz > ${BACKUP_FILE}.gz.md5
    echo "Checksum created: ${BACKUP_FILE}.gz.md5"

    # Upload to S3 (optional)
    # aws s3 cp ${BACKUP_FILE}.gz s3://scola-backups/database/

else
    echo "Backup failed!"
    exit 1
fi

# Clean up old backups (keep last 30 days)
find ${BACKUP_DIR} -name "*.dump.gz" -mtime +30 -delete
echo "Old backups cleaned up"

Usage:

sudo -u odoo /opt/odoo/scripts/backup_database.sh

3.2 Automated Daily Backup (Cron)

# Add to crontab: sudo crontab -e -u odoo
0 2 * * * /opt/odoo/scripts/backup_database.sh >> /var/log/odoo/backup.log 2>&1

3.3 Incremental Backup (WAL Archiving)

Enable WAL archiving in PostgreSQL:

# Edit postgresql.conf
sudo nano /etc/postgresql/14/main/postgresql.conf

# Add/modify:
wal_level = replica
archive_mode = on
archive_command = 'test ! -f /backups/wal/%f && cp %p /backups/wal/%f'
archive_timeout = 300  # 5 minutes

Restart PostgreSQL:

sudo systemctl restart postgresql


4. File Storage Backup Procedures

4.1 Manual Filestore Backup

#!/bin/bash
# Manual filestore backup script

# Configuration
FILESTORE_PATH="/opt/odoo/.local/share/Odoo/filestore/scola_production"
BACKUP_DIR="/backups/filestore"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/filestore_${TIMESTAMP}.tar.gz"

# Create backup directory
mkdir -p ${BACKUP_DIR}

# Perform backup
echo "Starting filestore backup..."
tar -czf ${BACKUP_FILE} -C /opt/odoo/.local/share/Odoo/filestore scola_production

# Verify backup
if [ $? -eq 0 ]; then
    echo "Filestore backup successful: ${BACKUP_FILE}"

    # Calculate checksum
    md5sum ${BACKUP_FILE} > ${BACKUP_FILE}.md5

    # Upload to S3 (optional)
    # aws s3 cp ${BACKUP_FILE} s3://scola-backups/filestore/

else
    echo "Filestore backup failed!"
    exit 1
fi

# Clean up old backups (keep last 30 days)
find ${BACKUP_DIR} -name "filestore_*.tar.gz" -mtime +30 -delete

Usage:

sudo /opt/odoo/scripts/backup_filestore.sh

4.2 Automated Daily Backup (Cron)

# Add to crontab: sudo crontab -e
0 3 * * * /opt/odoo/scripts/backup_filestore.sh >> /var/log/odoo/backup.log 2>&1

5. Restore Procedures

5.1 Database Restore

Prerequisites: - Stop Odoo service - Ensure sufficient disk space - Verify backup integrity (checksum)

Restore Steps:

#!/bin/bash
# Database restore script

# Configuration
DB_NAME="scola_production"
BACKUP_FILE="/backups/database/scola_production_20260301_020000.dump.gz"

# 1. Stop Odoo service
echo "Stopping Odoo service..."
sudo systemctl stop odoo

# 2. Verify backup checksum
echo "Verifying backup integrity..."
md5sum -c ${BACKUP_FILE}.md5
if [ $? -ne 0 ]; then
    echo "Backup checksum verification failed!"
    exit 1
fi

# 3. Decompress backup
echo "Decompressing backup..."
gunzip -c ${BACKUP_FILE} > /tmp/restore.dump

# 4. Drop existing database (CAUTION!)
echo "Dropping existing database..."
sudo -u postgres psql -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '${DB_NAME}';"
sudo -u postgres dropdb ${DB_NAME}

# 5. Create new database
echo "Creating new database..."
sudo -u postgres createdb -O odoo ${DB_NAME}

# 6. Restore backup
echo "Restoring database..."
pg_restore -U odoo -d ${DB_NAME} -v /tmp/restore.dump

# 7. Verify restore
if [ $? -eq 0 ]; then
    echo "Database restore successful!"

    # Clean up temp file
    rm /tmp/restore.dump

    # Start Odoo service
    echo "Starting Odoo service..."
    sudo systemctl start odoo

    # Wait for service to start
    sleep 10

    # Check service status
    sudo systemctl status odoo

else
    echo "Database restore failed!"
    exit 1
fi

Usage:

sudo /opt/odoo/scripts/restore_database.sh

5.2 Filestore Restore

#!/bin/bash
# Filestore restore script

# Configuration
FILESTORE_PATH="/opt/odoo/.local/share/Odoo/filestore/scola_production"
BACKUP_FILE="/backups/filestore/filestore_20260301_030000.tar.gz"

# 1. Stop Odoo service
echo "Stopping Odoo service..."
sudo systemctl stop odoo

# 2. Verify backup checksum
echo "Verifying backup integrity..."
md5sum -c ${BACKUP_FILE}.md5
if [ $? -ne 0 ]; then
    echo "Backup checksum verification failed!"
    exit 1
fi

# 3. Backup current filestore (just in case)
echo "Backing up current filestore..."
mv ${FILESTORE_PATH} ${FILESTORE_PATH}.old.$(date +%Y%m%d_%H%M%S)

# 4. Restore filestore
echo "Restoring filestore..."
mkdir -p /opt/odoo/.local/share/Odoo/filestore
tar -xzf ${BACKUP_FILE} -C /opt/odoo/.local/share/Odoo/filestore

# 5. Set correct permissions
echo "Setting permissions..."
chown -R odoo:odoo ${FILESTORE_PATH}
chmod -R 750 ${FILESTORE_PATH}

# 6. Start Odoo service
echo "Starting Odoo service..."
sudo systemctl start odoo

# 7. Verify
if [ $? -eq 0 ]; then
    echo "Filestore restore successful!"
    sudo systemctl status odoo
else
    echo "Filestore restore failed!"
    exit 1
fi

6. Disaster Recovery Scenarios

6.1 Complete System Failure

Recovery Steps:

  1. Provision new server (same specs as production)
  2. Install base system:

    # Install PostgreSQL
    sudo apt install postgresql-14
    
    # Install Odoo dependencies
    sudo apt install python3-pip python3-dev libxml2-dev libxslt1-dev \
                     libldap2-dev libsasl2-dev libjpeg-dev zlib1g-dev
    

  3. Restore database:

    # Copy backup from S3
    aws s3 cp s3://scola-backups/database/latest.dump.gz /tmp/
    
    # Restore
    /opt/odoo/scripts/restore_database.sh
    

  4. Restore filestore:

    # Copy backup from S3
    aws s3 cp s3://scola-backups/filestore/latest.tar.gz /tmp/
    
    # Restore
    /opt/odoo/scripts/restore_filestore.sh
    

  5. Restore configuration:

    # Copy odoo.conf
    sudo cp /backups/config/odoo.conf /etc/odoo/
    
    # Copy SSL certificates
    sudo cp -r /backups/ssl/* /etc/ssl/
    

  6. Start services:

    sudo systemctl start postgresql
    sudo systemctl start odoo
    sudo systemctl start nginx
    

  7. Verify system:

    # Check services
    sudo systemctl status postgresql odoo nginx
    
    # Test web access
    curl -I https://scola.example.com
    
    # Check logs
    tail -f /var/log/odoo/odoo-server.log
    

Expected RTO: 45-60 minutes

6.2 Database Corruption

Recovery Steps:

  1. Stop Odoo service
  2. Identify corruption (check PostgreSQL logs)
  3. Attempt database repair:
    sudo -u postgres reindexdb -d scola_production
    sudo -u postgres vacuumdb --full --analyze scola_production
    
  4. If repair fails, restore from latest backup
  5. Verify data integrity
  6. Resume operations

Expected RTO: 15-30 minutes

6.3 Accidental Data Deletion

Recovery Steps:

  1. Identify deletion timestamp
  2. Find nearest backup before deletion
  3. Restore to temporary database:
    pg_restore -U odoo -d scola_temp /backups/database/backup.dump
    
  4. Extract deleted data:
    -- Example: Restore deleted student records
    INSERT INTO scola_production.op_student
    SELECT * FROM scola_temp.op_student
    WHERE id IN (123, 456, 789);
    
  5. Verify restored data
  6. Drop temporary database

Expected RTO: 10-20 minutes


7. Backup Verification

7.1 Monthly Restore Test

Schedule: First Sunday of each month

Procedure: 1. Select random backup from previous month 2. Restore to test environment 3. Verify data integrity: - Check record counts - Verify file attachments - Test critical workflows 4. Document results 5. Update procedures if issues found

7.2 Backup Integrity Checks

Daily automated checks:

#!/bin/bash
# Verify backup integrity

BACKUP_DIR="/backups/database"
LATEST_BACKUP=$(ls -t ${BACKUP_DIR}/*.dump.gz | head -1)

# Check file exists
if [ ! -f "${LATEST_BACKUP}" ]; then
    echo "ERROR: Latest backup not found!"
    # Send alert
    exit 1
fi

# Verify checksum
md5sum -c ${LATEST_BACKUP}.md5
if [ $? -ne 0 ]; then
    echo "ERROR: Backup checksum verification failed!"
    # Send alert
    exit 1
fi

# Check file size (should be > 100MB for production)
FILE_SIZE=$(stat -f%z "${LATEST_BACKUP}" 2>/dev/null || stat -c%s "${LATEST_BACKUP}")
if [ ${FILE_SIZE} -lt 104857600 ]; then
    echo "WARNING: Backup file size suspiciously small!"
    # Send alert
fi

echo "Backup integrity check passed"


8. Monitoring & Alerts

8.1 Backup Monitoring

Metrics to monitor: - Backup completion status - Backup file size - Backup duration - Storage space usage - Checksum verification status

Alert triggers: - Backup failed - Backup file size < expected - Backup duration > 2x normal - Storage space < 20% free - Checksum verification failed

8.2 Alert Channels


9. Backup Storage Management

9.1 Local Storage

Location: /backups/

Retention: - Database: 30 days - Filestore: 30 days - WAL logs: 7 days

Cleanup script:

#!/bin/bash
# Clean up old backups

find /backups/database -name "*.dump.gz" -mtime +30 -delete
find /backups/filestore -name "*.tar.gz" -mtime +30 -delete
find /backups/wal -name "*.wal" -mtime +7 -delete

9.2 Off-site Storage (S3)

Bucket: s3://scola-backups/

Retention: - Daily backups: 90 days - Monthly backups: 1 year - Yearly backups: 7 years

Lifecycle policy:

{
  "Rules": [
    {
      "Id": "DeleteOldDailyBackups",
      "Status": "Enabled",
      "Prefix": "database/daily/",
      "Expiration": {
        "Days": 90
      }
    },
    {
      "Id": "TransitionMonthlyToGlacier",
      "Status": "Enabled",
      "Prefix": "database/monthly/",
      "Transitions": [
        {
          "Days": 30,
          "StorageClass": "GLACIER"
        }
      ],
      "Expiration": {
        "Days": 365
      }
    }
  ]
}


10. Checklist

Pre-Backup Checklist

  • [ ] Verify sufficient disk space (>50GB free)
  • [ ] Check PostgreSQL service status
  • [ ] Verify backup scripts are executable
  • [ ] Confirm S3 credentials are valid

Post-Backup Checklist

  • [ ] Verify backup file created
  • [ ] Check backup file size (>100MB)
  • [ ] Verify checksum file created
  • [ ] Confirm S3 upload successful (if enabled)
  • [ ] Review backup logs for errors

Pre-Restore Checklist

  • [ ] Verify backup integrity (checksum)
  • [ ] Confirm sufficient disk space
  • [ ] Notify users of maintenance window
  • [ ] Stop Odoo service
  • [ ] Backup current state (just in case)

Post-Restore Checklist

  • [ ] Verify database connectivity
  • [ ] Check critical tables (students, courses, exams)
  • [ ] Test file attachments
  • [ ] Verify user logins
  • [ ] Check system logs for errors
  • [ ] Notify users of completion

11. Contact Information

Primary Contact: - Name: System Administrator - Email: [email protected] - Phone: +62-xxx-xxxx-xxxx

Backup Contact: - Name: DevOps Engineer - Email: [email protected] - Phone: +62-xxx-xxxx-xxxx

Escalation: - CTO: [email protected]


Document Version: 1.0
Last Updated: March 1, 2026
Next Review: June 1, 2026