Configure MongoDB 8.0 backup automation with systemd timers and compression

Intermediate 45 min Apr 11, 2026 874 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Set up automated MongoDB 8.0 backups with systemd timers, compression, and retention policies. Includes monitoring and alerting for backup failures across Ubuntu, Debian, AlmaLinux, and Rocky Linux systems.

Prerequisites

  • Root or sudo access
  • MongoDB 8.0 installed
  • At least 2GB free disk space
  • Email server for alerts

What this solves

MongoDB databases require regular backups to prevent data loss, but manual backups are unreliable and time-consuming. This tutorial shows you how to create automated MongoDB 8.0 backup scripts with compression and rotation, schedule them using systemd timers, and set up monitoring to alert you when backups fail. You'll have a production-ready backup system that runs automatically and stores compressed backups with configurable retention policies.

Step-by-step installation

Update system packages and install dependencies

Start by updating your system and installing required packages for backup operations and compression.

sudo apt update && sudo apt upgrade -y
sudo apt install -y gzip bzip2 xz-utils mailutils postfix
sudo dnf update -y
sudo dnf install -y gzip bzip2 xz mailx postfix

Install MongoDB 8.0 with authentication

Install MongoDB 8.0 and configure it with authentication enabled for secure backup operations.

curl -fsSL https://www.mongodb.org/static/pgp/server-8.0.asc | sudo gpg -o /usr/share/keyrings/mongodb-server-8.0.gpg --dearmor
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/8.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list
sudo apt update
sudo apt install -y mongodb-org
sudo tee /etc/yum.repos.d/mongodb-org-8.0.repo << 'EOF'
[mongodb-org-8.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/9/mongodb-org/8.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-8.0.asc
EOF
sudo dnf install -y mongodb-org

Configure MongoDB with authentication

Enable authentication in MongoDB configuration and create backup user credentials.

storage:
  dbPath: /var/lib/mongodb
  journal:
    enabled: true

systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

net:
  port: 27017
  bindIp: 127.0.0.1

processManagement:
  timeZoneInfo: /usr/share/zoneinfo

security:
  authorization: enabled

Start MongoDB and create admin user

Start MongoDB service and create the initial admin user for database administration.

sudo systemctl enable --now mongod
sudo systemctl status mongod

# Connect to MongoDB and create admin user
mongosh --eval '
use admin
db.createUser({
  user: "admin",
  pwd: "SecureAdminPass123!",
  roles: ["userAdminAnyDatabase", "readWriteAnyDatabase", "dbAdminAnyDatabase", "clusterAdmin"]
})
'

Create backup user with minimal privileges

Create a dedicated backup user with only the permissions needed for database backups.

mongosh -u admin -p SecureAdminPass123! --authenticationDatabase admin --eval '
use admin
db.createUser({
  user: "backupuser",
  pwd: "SecureBackupPass123!",
  roles: ["backup", "clusterMonitor"]
})
'

Create backup directory structure

Set up directories for storing backups with proper permissions and ownership.

sudo mkdir -p /opt/mongodb-backups/{scripts,logs,data}
sudo mkdir -p /opt/mongodb-backups/data/{daily,weekly,monthly}
sudo useradd --system --home-dir /opt/mongodb-backups --shell /bin/bash mongobackup
sudo chown -R mongobackup:mongobackup /opt/mongodb-backups
sudo chmod 750 /opt/mongodb-backups
sudo chmod 755 /opt/mongodb-backups/data
Note: Never use chmod 777 for backup directories. The 750 permission gives the backup user full access while preventing other users from reading sensitive backup data.

Create backup script with compression and rotation

Create the main backup script that handles database dumps, compression, and automatic cleanup of old backups.

#!/bin/bash

# MongoDB Backup Script with Compression and Rotation
# Author: MongoDB Backup System
# Version: 1.0

set -euo pipefail

# Configuration
BACKUP_DIR="/opt/mongodb-backups/data"
LOG_DIR="/opt/mongodb-backups/logs"
SCRIPT_NAME="mongodb-backup"
DATE=$(date +%Y%m%d_%H%M%S)
LOG_FILE="$LOG_DIR/${SCRIPT_NAME}_${DATE}.log"

# MongoDB Connection Details
MONGO_HOST="localhost"
MONGO_PORT="27017"
MONGO_USER="backupuser"
MONGO_PASS="SecureBackupPass123!"
MONGO_AUTH_DB="admin"

# Retention Policy (days)
DAILY_RETENTION=7
WEEKLY_RETENTION=30
MONTHLY_RETENTION=365

# Email Configuration
EMAIL_TO="admin@example.com"
EMAIL_FROM="mongodb-backup@example.com"

# Logging function
log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Error handling
error_exit() {
    log "ERROR: $1"
    echo "MongoDB backup failed on $(hostname) at $(date)" | mail -s "MongoDB Backup Failure" -r "$EMAIL_FROM" "$EMAIL_TO"
    exit 1
}

# Check if mongodump is available
if ! command -v mongodump &> /dev/null; then
    error_exit "mongodump command not found. Please install MongoDB tools."
fi

# Create backup type directory
BACKUP_TYPE="daily"
if [ "$(date +%u)" -eq 7 ]; then
    BACKUP_TYPE="weekly"
fi
if [ "$(date +%d)" -eq 01 ]; then
    BACKUP_TYPE="monthly"
fi

BACKUP_PATH="$BACKUP_DIR/$BACKUP_TYPE"
mkdir -p "$BACKUP_PATH"

log "Starting MongoDB backup ($BACKUP_TYPE)"
log "Backup directory: $BACKUP_PATH"

# Create temporary directory for backup
TEMP_DIR=$(mktemp -d)
trap "rm -rf $TEMP_DIR" EXIT

# Perform backup
BACKUP_NAME="mongodb_backup_${DATE}"
DUMP_DIR="$TEMP_DIR/$BACKUP_NAME"

log "Creating database dump..."
if ! mongodump --host="$MONGO_HOST:$MONGO_PORT" \
    --username="$MONGO_USER" \
    --password="$MONGO_PASS" \
    --authenticationDatabase="$MONGO_AUTH_DB" \
    --out="$DUMP_DIR" \
    --gzip 2>> "$LOG_FILE"; then
    error_exit "mongodump failed"
fi

# Create compressed archive
log "Compressing backup..."
COMPRESSED_BACKUP="$BACKUP_PATH/${BACKUP_NAME}.tar.xz"
if ! tar -cJf "$COMPRESSED_BACKUP" -C "$TEMP_DIR" "$BACKUP_NAME" 2>> "$LOG_FILE"; then
    error_exit "Backup compression failed"
fi

# Verify backup integrity
log "Verifying backup integrity..."
if ! tar -tJf "$COMPRESSED_BACKUP" >/dev/null 2>> "$LOG_FILE"; then
    error_exit "Backup verification failed"
fi

# Get backup size
BACKUP_SIZE=$(du -h "$COMPRESSED_BACKUP" | cut -f1)
log "Backup completed successfully. Size: $BACKUP_SIZE"

# Cleanup old backups based on retention policy
log "Cleaning up old backups..."

# Daily cleanup
find "$BACKUP_DIR/daily" -name "mongodb_backup_*.tar.xz" -type f -mtime +$DAILY_RETENTION -delete 2>> "$LOG_FILE" || true

# Weekly cleanup
find "$BACKUP_DIR/weekly" -name "mongodb_backup_*.tar.xz" -type f -mtime +$WEEKLY_RETENTION -delete 2>> "$LOG_FILE" || true

# Monthly cleanup
find "$BACKUP_DIR/monthly" -name "mongodb_backup_*.tar.xz" -type f -mtime +$MONTHLY_RETENTION -delete 2>> "$LOG_FILE" || true

# Log cleanup
find "$LOG_DIR" -name "${SCRIPT_NAME}_*.log" -type f -mtime +30 -delete 2>/dev/null || true

log "Backup process completed successfully"

# Send success notification
echo "MongoDB backup completed successfully on $(hostname) at $(date). Backup size: $BACKUP_SIZE" | \
mail -s "MongoDB Backup Success" -r "$EMAIL_FROM" "$EMAIL_TO"

Create backup restore script

Create a companion script for restoring backups when needed.

#!/bin/bash

# MongoDB Restore Script
# Usage: ./mongodb-restore.sh /path/to/backup.tar.xz [target_database]

set -euo pipefail

if [ $# -lt 1 ]; then
    echo "Usage: $0 

Set proper script permissions

Make the backup scripts executable and secure them with appropriate permissions.

sudo chmod 750 /opt/mongodb-backups/scripts/*.sh
sudo chown mongobackup:mongobackup /opt/mongodb-backups/scripts/*.sh
sudo chmod 640 /opt/mongodb-backups/scripts/*.sh
sudo chmod u+x /opt/mongodb-backups/scripts/*.sh

Create systemd service for backup execution

Create a systemd service that will execute the backup script with proper user context and logging.

[Unit]
Description=MongoDB Backup Service
Wants=network-online.target
After=network-online.target mongod.service
Requires=mongod.service

[Service]
Type=oneshot
User=mongobackup
Group=mongobackup
ExecStart=/opt/mongodb-backups/scripts/mongodb-backup.sh
WorkingDirectory=/opt/mongodb-backups
StandardOutput=journal
StandardError=journal
SyslogIdentifier=mongodb-backup
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/mongodb-backups
NoNewPrivileges=true
TimeoutSec=3600

Create systemd timer for automated scheduling

Create a systemd timer that will run the backup service automatically on a daily schedule.

[Unit]
Description=MongoDB Backup Timer
Requires=mongodb-backup.service

[Timer]
OnCalendar=daily
RandomizedDelaySec=1800
Persistent=true

[Install]
WantedBy=timers.target

Enable and start the backup timer

Reload systemd configuration and enable the backup timer to start automatically.

sudo systemctl daemon-reload
sudo systemctl enable mongodb-backup.timer
sudo systemctl start mongodb-backup.timer
sudo systemctl status mongodb-backup.timer

Create backup monitoring script

Create a monitoring script that checks backup health and sends alerts for missing or failed backups.

#!/bin/bash

# MongoDB Backup Monitor Script
# Checks for successful backups and alerts on failures

set -euo pipefail

BACKUP_DIR="/opt/mongodb-backups/data/daily"
LOG_DIR="/opt/mongodb-backups/logs"
EMAIL_TO="admin@example.com"
EMAIL_FROM="mongodb-monitor@example.com"
MAX_AGE_HOURS=25  # Alert if backup is older than 25 hours

# Find the most recent backup
LATEST_BACKUP=$(find "$BACKUP_DIR" -name "mongodb_backup_*.tar.xz" -type f -printf '%T@ %p\n' | sort -rn | head -n1 | cut -d' ' -f2-)

if [ -z "$LATEST_BACKUP" ]; then
    echo "CRITICAL: No MongoDB backups found in $BACKUP_DIR" | \
    mail -s "MongoDB Backup Monitor: No Backups Found" -r "$EMAIL_FROM" "$EMAIL_TO"
    exit 1
fi

# Check backup age
BACKUP_TIME=$(stat -c %Y "$LATEST_BACKUP")
CURRENT_TIME=$(date +%s)
AGE_SECONDS=$((CURRENT_TIME - BACKUP_TIME))
AGE_HOURS=$((AGE_SECONDS / 3600))

if [ $AGE_HOURS -gt $MAX_AGE_HOURS ]; then
    echo "WARNING: Latest MongoDB backup is $AGE_HOURS hours old (threshold: $MAX_AGE_HOURS hours)" | \
    mail -s "MongoDB Backup Monitor: Backup Too Old" -r "$EMAIL_FROM" "$EMAIL_TO"
    exit 1
fi

# Verify backup integrity
if ! tar -tJf "$LATEST_BACKUP" >/dev/null 2>&1; then
    echo "CRITICAL: Latest MongoDB backup file is corrupted: $LATEST_BACKUP" | \
    mail -s "MongoDB Backup Monitor: Corrupted Backup" -r "$EMAIL_FROM" "$EMAIL_TO"
    exit 1
fi

# Check recent logs for errors
RECENT_LOG=$(find "$LOG_DIR" -name "mongodb-backup_*.log" -type f -mtime -1 | head -n1)
if [ -n "$RECENT_LOG" ] && grep -q "ERROR" "$RECENT_LOG"; then
    echo "WARNING: Errors found in recent backup log: $RECENT_LOG" | \
    mail -s "MongoDB Backup Monitor: Backup Errors" -r "$EMAIL_FROM" "$EMAIL_TO"
fi

echo "MongoDB backup monitoring passed. Latest backup: $(basename "$LATEST_BACKUP") (${AGE_HOURS}h old)"

Create monitoring service and timer

Set up systemd service and timer for automated backup monitoring.

[Unit]
Description=MongoDB Backup Monitor Service
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
User=mongobackup
Group=mongobackup
ExecStart=/opt/mongodb-backups/scripts/mongodb-backup-monitor.sh
WorkingDirectory=/opt/mongodb-backups
StandardOutput=journal
StandardError=journal
SyslogIdentifier=mongodb-backup-monitor
[Unit]
Description=MongoDB Backup Monitor Timer
Requires=mongodb-backup-monitor.service

[Timer]
OnCalendar=hourly
RandomizedDelaySec=300
Persistent=true

[Install]
WantedBy=timers.target

Enable monitoring and configure email alerts

Enable the monitoring timer and configure postfix for email notifications.

sudo chmod 750 /opt/mongodb-backups/scripts/mongodb-backup-monitor.sh
sudo chown mongobackup:mongobackup /opt/mongodb-backups/scripts/mongodb-backup-monitor.sh

sudo systemctl daemon-reload
sudo systemctl enable mongodb-backup-monitor.timer
sudo systemctl start mongodb-backup-monitor.timer

# Configure postfix for local delivery
sudo postconf -e 'myhostname = mongodb-server.example.com'
sudo postconf -e 'mydestination = $myhostname, localhost.localdomain, localhost'
sudo systemctl enable --now postfix

Test the backup system

Run a manual backup test to verify the entire system works correctly.

sudo systemctl start mongodb-backup.service
sudo systemctl status mongodb-backup.service
sudo journalctl -u mongodb-backup.service -f

Verify your setup

Check that your MongoDB backup automation is working correctly with these verification commands.

# Check timer status
sudo systemctl list-timers | grep mongodb-backup

# Verify backup files were created
ls -la /opt/mongodb-backups/data/daily/

# Check backup logs
tail -f /opt/mongodb-backups/logs/mongodb-backup_*.log

# Test backup integrity
tar -tJf /opt/mongodb-backups/data/daily/mongodb_backup_*.tar.xz

# Check monitoring status
sudo systemctl status mongodb-backup-monitor.timer

# View systemd journal for backup services
sudo journalctl -u mongodb-backup.service -u mongodb-backup-monitor.service --since "1 hour ago"

Common issues

Symptom Cause Fix
Authentication failed during backup Incorrect MongoDB credentials Verify credentials with mongosh -u backupuser -p
Permission denied on backup directory Incorrect file permissions sudo chown -R mongobackup:mongobackup /opt/mongodb-backups
Backup service fails to start MongoDB service not running sudo systemctl start mongod then retry backup
Email alerts not sending Postfix not configured Configure postfix with sudo dpkg-reconfigure postfix
Backup files consuming too much disk Retention policy too long Adjust retention days in backup script configuration
Timer not running automatically Timer not enabled sudo systemctl enable mongodb-backup.timer

Next steps

Automated install script

Run this to automate the entire setup

Prefere não gerir isto sozinho?

Gerimos a infraestrutura de empresas que dependem do tempo de atividade. Totalmente gerida, com um contacto fixo que conhece o seu ambiente.

Tem um contacto fixo que conhece o seu ambiente

Na secretária em Roterdão 15:33 · acessível por mensagem, sem formulário de tickets