How to Set Up Automated MongoDB Backup to AWS S3 on Ubuntu (Production Ready)
Step-by-step guide to scheduling daily MongoDB backups, uploading them to AWS S3, and managing local retention — production-ready and battle-tested.
Running MongoDB in production without an automated, off-site backup is asking for a very bad day. This guide walks through the exact setup I've been running on Ubuntu servers: mongodump → gzip archive → AWS S3, on a daily cron, with local retention cleanup.
Goal
- Automated MongoDB backup
- Upload to AWS S3
- Run daily at 2 AM IST
- Retain only the last 7 days locally
- Production-safe cron execution
Architecture
MongoDB
↓
mongodump (gzip archive)
↓
AWS S3 upload
↓
Local retention cleanup1. Install AWS CLI on Ubuntu
Install via Snap (easiest, auto-updates):
sudo snap install aws-cli --classicVerify:
aws --version2. Create an IAM User (S3 access only)
In the AWS Console:
- Go to IAM → Users → Create User
- Enable programmatic access
- Attach a policy
For quick setup you can use the managed policy AmazonS3FullAccess, but for production use a scoped policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:PutObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::your-bucket-name",
"arn:aws:s3:::your-bucket-name/*"
]
}
]
}Save the Access Key and Secret Key — you'll need them in the next step.
3. Configure AWS on the server
aws configureEnter:
Access Key
Secret Key
Region (e.g. ap-south-1)
Output format: json4. Create the backup script
nano /home/ubuntu/mongo-backup.shPaste:
#!/bin/bash
# === MongoDB Daily Backup Script ===
set -e
MONGO_URI="mongodb://localhost:27017/mydatabase"
BACKUP_DIR="/home/ubuntu/bkp"
DATE=$(date +"%Y-%m-%d_%H-%M-%S")
S3_BUCKET="s3://your-bucket-name"
BACKUP_NAME="backup-$DATE.gz"
RETENTION_DAYS=7
LOG_FILE="/home/ubuntu/mongo-backup.log"
mkdir -p "$BACKUP_DIR"
echo "Starting backup: $DATE" >> "$LOG_FILE"
# Dump database
/usr/bin/mongodump --uri="$MONGO_URI" \
--archive="$BACKUP_DIR/$BACKUP_NAME" --gzip >> "$LOG_FILE" 2>&1
# Upload to S3
/snap/bin/aws s3 cp "$BACKUP_DIR/$BACKUP_NAME" "$S3_BUCKET/" >> "$LOG_FILE" 2>&1
# Cleanup old local backups
find "$BACKUP_DIR" -type f -mtime +$RETENTION_DAYS -delete
echo "Backup completed successfully: $BACKUP_NAME" >> "$LOG_FILE"Make it executable and run once manually to confirm everything wires up:
chmod +x /home/ubuntu/mongo-backup.sh
/home/ubuntu/mongo-backup.sh5. Set up the cron job (2 AM IST)
If your server is on UTC, 2 AM IST = 20:30 UTC the previous day.
crontab -eAdd:
30 20 * * * /home/ubuntu/mongo-backup.sh >> /home/ubuntu/mongo-backup.log 2>&16. Add an S3 lifecycle rule (highly recommended)
In the S3 console: Bucket → Management → Lifecycle Rules → Create rule. Delete objects after 30 days. This stops storage from growing forever.
Production recommendations
- Use an IAM role instead of access keys if running on EC2
- Restrict S3 permissions to a specific bucket
- Enable S3 versioning
- Enable server-side encryption (SSE-S3 or SSE-KMS)
- Periodically test the restore — a backup you've never restored is not a backup
What's next
Backups without monitoring are risky. If mongodump or the S3 upload silently fails, you only find out the day you need the backup. In the next post I wire Amazon SES failure alerts into this exact script so a broken backup pages me by email.