1Why Cloud Backups for Odoo?
Storing Odoo backups in cloud object storage provides enterprise-grade durability, geographic redundancy, and automated lifecycle management. Whether you're running Odoo with Docker or a traditional deployment, cloud backups are essential in 2026:
Disaster Recovery
Recover from server failures, ransomware, or data corruption with off-site backups
Compliance Requirements
Meet GDPR, SOC 2, and industry regulations requiring data retention and backup policies
Geographic Redundancy
Store backups in multiple regions to protect against regional outages
Long-term Retention
Keep yearly backups indefinitely with cost-effective cold storage tiers
Cost Efficiency
Pay only for storage used with automatic tiering to reduce costs
Automation
Set-and-forget with scheduled backups and automatic retention management
Learn More
For complete disaster recovery procedures and restoration guides, see our Backup and Recovery Guide.
2Storage Options Comparison
OEC.sh supports 7 backup destinations. Choose based on your budget, compliance needs, and existing infrastructure:
AWS S3
~$0.023/GB storage + egressIndustry standard, enterprise-grade object storage
Pros
- Widest integration support
- 99.999999999% durability
- Advanced security features
Cons
- Egress fees can add up
- Complex pricing structure
Best for: Enterprise, AWS ecosystem
Cloudflare R2
$0.015/GB storage, $0 egressS3-compatible storage with zero egress fees
Pros
- No egress fees
- S3-compatible API
- Global edge network
Cons
- Newer service
- Fewer regions than S3
Best for: High-download workloads
Backblaze B2
$0.006/GB storageLowest cost cloud storage option
Pros
- Lowest storage cost
- Simple pricing
- S3-compatible API
Cons
- Lower egress cap
- Fewer features
Best for: Budget-conscious, archival
MinIO
Free (infrastructure costs)Self-hosted S3-compatible object storage
Pros
- Self-hosted control
- No vendor lock-in
- S3-compatible
Cons
- Requires infrastructure
- Self-managed
Best for: On-premise, compliance
FTP/SFTP
Varies by providerTraditional file transfer protocol
Pros
- Simple setup
- Works anywhere
- No special client
Cons
- Less scalable
- Manual management
Best for: Legacy systems, simple needs
WebDAV
Varies by providerWeb-based file access protocol
Pros
- HTTP-based
- Easy firewall traversal
- Wide support
Cons
- Slower than native protocols
- Variable performance
Best for: Web-integrated workflows
| Provider | Storage/GB | Egress/GB | 100GB/mo |
|---|---|---|---|
| AWS S3 Standard | $0.023 | $0.09 | $2.30 |
| Cloudflare R2 | $0.015 | $0.00 | $1.50 |
| Backblaze B2 | $0.006 | $0.01 | $0.60 |
| MinIO (Self-hosted) | Infra cost | Infra cost | Variable |
All OEC.sh plans include automated backups to your choice of cloud storage. Compare pricing plans to find the right fit for your backup needs.
3What to Backup
A complete Odoo backup requires multiple components. Missing any of these can result in an incomplete or unusable restore:
PostgreSQL Database
The core database containing all Odoo data: users, products, orders, accounting, etc. Use pg_dump for reliable backups.
Typical size: 1GB - 50GB depending on usage
Filestore (Attachments)
Binary files stored on disk: email attachments, uploaded documents, product images, reports. Located in ~/.local/share/Odoo/filestore/.
Typical size: 5GB - 200GB+ depending on attachments
Custom Modules (Git-controlled)
Your custom Odoo modules should be version-controlled in Git. Include them in deployment, not necessarily in daily backups.
Best practice: Store in Git repository with tags for each deployment
Configuration Files
Odoo configuration (odoo.conf), nginx config, systemd units. Critical for restoring the exact server state.
Typical size: A few KB - best kept in version control
4Complete Backup Scripts
Copy-paste ready scripts for backing up Odoo to various cloud storage providers. Each script includes database backup, filestore archiving, and upload.
Complete Backup Script (pg_dump + Filestore)
1#!/bin/bash2# Odoo Backup Script - Database + Filestore3# Usage: ./odoo-backup.sh database_name45set -e67# Configuration8DB_NAME="${1:-odoo}"9BACKUP_DIR="/var/backups/odoo"10FILESTORE_PATH="/opt/odoo/.local/share/Odoo/filestore/${DB_NAME}"11TIMESTAMP=$(date +%Y%m%d_%H%M%S)12BACKUP_NAME="odoo_${DB_NAME}_${TIMESTAMP}"1314# Create backup directory15mkdir -p "${BACKUP_DIR}"1617echo "Starting backup for database: ${DB_NAME}"1819# Backup PostgreSQL database20echo "Backing up PostgreSQL database..."21pg_dump -Fc -f "${BACKUP_DIR}/${BACKUP_NAME}.dump" "${DB_NAME}"2223# Backup filestore24echo "Backing up filestore..."25tar -czf "${BACKUP_DIR}/${BACKUP_NAME}_filestore.tar.gz" -C "${FILESTORE_PATH}" .2627# Create manifest file28echo "Creating manifest..."29cat > "${BACKUP_DIR}/${BACKUP_NAME}_manifest.json" << EOF30{31 "database": "${DB_NAME}",32 "timestamp": "${TIMESTAMP}",33 "odoo_version": "$(odoo --version 2>/dev/null || echo 'unknown')",34 "db_size": "$(du -h ${BACKUP_DIR}/${BACKUP_NAME}.dump | cut -f1)",35 "filestore_size": "$(du -h ${BACKUP_DIR}/${BACKUP_NAME}_filestore.tar.gz | cut -f1)"36}37EOF3839echo "Backup completed: ${BACKUP_DIR}/${BACKUP_NAME}"40echo "Database: ${BACKUP_DIR}/${BACKUP_NAME}.dump"41echo "Filestore: ${BACKUP_DIR}/${BACKUP_NAME}_filestore.tar.gz"Upload to AWS S3
#!/bin/bash# Upload Odoo backup to AWS S3S3_BUCKET="your-odoo-backups"S3_PATH="backups/production"BACKUP_DIR="/var/backups/odoo"BACKUP_NAME="$1"# Install AWS CLI if not present# pip3 install awscli# Configure AWS credentials (run once)# aws configure# Upload backup filesecho "Uploading to S3..."aws s3 cp "${BACKUP_DIR}/${BACKUP_NAME}.dump" "s3://${S3_BUCKET}/${S3_PATH}/" --storage-class STANDARD_IAaws s3 cp "${BACKUP_DIR}/${BACKUP_NAME}_filestore.tar.gz" "s3://${S3_BUCKET}/${S3_PATH}/" --storage-class STANDARD_IAaws s3 cp "${BACKUP_DIR}/${BACKUP_NAME}_manifest.json" "s3://${S3_BUCKET}/${S3_PATH}/"# Verify uploadaws s3 ls "s3://${S3_BUCKET}/${S3_PATH}/${BACKUP_NAME}"echo "Upload complete!"Upload to Cloudflare R2 with rclone
#!/bin/bash# Upload Odoo backup to Cloudflare R2 using rclone# First, configure rclone for R2 (run once):# rclone config# Choose: New remote -> name: r2 -> type: s3# Provider: Cloudflare# Access Key ID: <your R2 access key># Secret Access Key: <your R2 secret># Endpoint: https://<account-id>.r2.cloudflarestorage.comR2_REMOTE="r2:odoo-backups"BACKUP_DIR="/var/backups/odoo"BACKUP_NAME="$1"echo "Uploading to Cloudflare R2..."rclone copy "${BACKUP_DIR}/${BACKUP_NAME}.dump" "${R2_REMOTE}/backups/"rclone copy "${BACKUP_DIR}/${BACKUP_NAME}_filestore.tar.gz" "${R2_REMOTE}/backups/"rclone copy "${BACKUP_DIR}/${BACKUP_NAME}_manifest.json" "${R2_REMOTE}/backups/"# Verifyrclone ls "${R2_REMOTE}/backups/" | grep "${BACKUP_NAME}"echo "R2 upload complete!"Upload to Backblaze B2
#!/bin/bash# Upload Odoo backup to Backblaze B2# Install B2 CLI: pip3 install b2# Authorize: b2 authorize-account <applicationKeyId> <applicationKey>B2_BUCKET="odoo-backups"BACKUP_DIR="/var/backups/odoo"BACKUP_NAME="$1"echo "Uploading to Backblaze B2..."b2 upload-file "${B2_BUCKET}" "${BACKUP_DIR}/${BACKUP_NAME}.dump" "backups/${BACKUP_NAME}.dump"b2 upload-file "${B2_BUCKET}" "${BACKUP_DIR}/${BACKUP_NAME}_filestore.tar.gz" "backups/${BACKUP_NAME}_filestore.tar.gz"b2 upload-file "${B2_BUCKET}" "${BACKUP_DIR}/${BACKUP_NAME}_manifest.json" "backups/${BACKUP_NAME}_manifest.json"# List recent uploadsb2 ls "${B2_BUCKET}" backups/ | tail -5echo "B2 upload complete!"All-in-One Script (Backup + Upload)
1#!/bin/bash2# Complete Odoo Backup Script with S3 Upload3# Run daily via cron45set -e67# Configuration8DB_NAME="odoo_production"9BACKUP_DIR="/var/backups/odoo"10FILESTORE_PATH="/opt/odoo/.local/share/Odoo/filestore/${DB_NAME}"11S3_BUCKET="your-odoo-backups"12S3_PATH="backups/production"13RETENTION_DAYS=714TIMESTAMP=$(date +%Y%m%d_%H%M%S)15BACKUP_NAME="odoo_${DB_NAME}_${TIMESTAMP}"1617# Create backup directory18mkdir -p "${BACKUP_DIR}"1920# Start backup21echo "[$(date)] Starting Odoo backup..."2223# 1. Backup database24echo "Step 1/4: Backing up PostgreSQL..."25pg_dump -Fc -f "${BACKUP_DIR}/${BACKUP_NAME}.dump" "${DB_NAME}"2627# 2. Backup filestore28echo "Step 2/4: Backing up filestore..."29tar -czf "${BACKUP_DIR}/${BACKUP_NAME}_filestore.tar.gz" -C "${FILESTORE_PATH}" .3031# 3. Upload to S332echo "Step 3/4: Uploading to S3..."33aws s3 cp "${BACKUP_DIR}/${BACKUP_NAME}.dump" "s3://${S3_BUCKET}/${S3_PATH}/" --storage-class STANDARD_IA34aws s3 cp "${BACKUP_DIR}/${BACKUP_NAME}_filestore.tar.gz" "s3://${S3_BUCKET}/${S3_PATH}/" --storage-class STANDARD_IA3536# 4. Clean up local backups older than retention period37echo "Step 4/4: Cleaning up old local backups..."38find "${BACKUP_DIR}" -name "odoo_*.dump" -mtime +${RETENTION_DAYS} -delete39find "${BACKUP_DIR}" -name "odoo_*_filestore.tar.gz" -mtime +${RETENTION_DAYS} -delete4041echo "[$(date)] Backup completed successfully!"42echo "Backup size: $(du -h ${BACKUP_DIR}/${BACKUP_NAME}.dump | cut -f1) (DB) + $(du -h ${BACKUP_DIR}/${BACKUP_NAME}_filestore.tar.gz | cut -f1) (Filestore)"5Retention Policies
A good retention policy balances recovery flexibility with storage costs. Here is our recommended policy:
Daily Backups
Keep for 7 days
One backup per day, typically run at night during low-traffic hours.
Weekly Backups
Keep for 4 weeks
Sunday backup promoted to weekly. Useful for recovering from issues discovered late.
Monthly Backups
Keep for 12 months
First backup of each month. Critical for compliance and long-term recovery.
Yearly Backups
Keep forever
January 1st backup archived to cold storage. Essential for legal and audit purposes.
S3 Lifecycle Policy
{ "Rules": [ { "ID": "DailyBackupRetention", "Filter": { "Prefix": "backups/daily/" }, "Status": "Enabled", "Expiration": { "Days": 7 } }, { "ID": "WeeklyBackupRetention", "Filter": { "Prefix": "backups/weekly/" }, "Status": "Enabled", "Expiration": { "Days": 30 } }, { "ID": "MonthlyBackupToGlacier", "Filter": { "Prefix": "backups/monthly/" }, "Status": "Enabled", "Transitions": [ { "Days": 30, "StorageClass": "GLACIER" } ], "Expiration": { "Days": 365 } }, { "ID": "YearlyToDeepArchive", "Filter": { "Prefix": "backups/yearly/" }, "Status": "Enabled", "Transitions": [ { "Days": 30, "StorageClass": "DEEP_ARCHIVE" } ] } ]}Apply this policy with: aws s3api put-bucket-lifecycle-configuration --bucket your-bucket --lifecycle-configuration file://s3-lifecycle-policy.json
6Automation
Automate backups using cron, systemd timers, or OEC.sh built-in scheduling. Never rely on manual backups for production.
Cron Job Setup
# Edit crontab for the odoo usersudo crontab -u odoo -e# Add these lines:# Daily backup at 2:00 AM0 2 * * * /opt/odoo/scripts/odoo-backup-full.sh >> /var/log/odoo-backup.log 2>&1# Weekly backup on Sunday at 3:00 AM (promoted to weekly folder)0 3 * * 0 /opt/odoo/scripts/odoo-backup-weekly.sh >> /var/log/odoo-backup.log 2>&1# Monthly backup on 1st of month at 4:00 AM0 4 1 * * /opt/odoo/scripts/odoo-backup-monthly.sh >> /var/log/odoo-backup.log 2>&1Systemd Timer (Recommended)
[Unit]Description=Daily Odoo Backup Timer[Timer]OnCalendar=*-*-* 02:00:00Persistent=trueRandomizedDelaySec=300[Install]WantedBy=timers.target[Unit]Description=Odoo Backup ServiceAfter=postgresql.service[Service]Type=oneshotUser=odooExecStart=/opt/odoo/scripts/odoo-backup-full.shStandardOutput=journalStandardError=journal[Install]WantedBy=multi-user.target# Enable and start the timersudo systemctl daemon-reloadsudo systemctl enable odoo-backup.timersudo systemctl start odoo-backup.timer# Check timer statussudo systemctl list-timers | grep odoo# View backup logssudo journalctl -u odoo-backup.serviceOEC.sh Built-in Scheduling
OEC.sh provides built-in backup scheduling with no manual configuration required:
- Schedule backups every 15 minutes, hourly, or daily
- Configure retention policies via dashboard
- Email notifications on backup success/failure
- One-click restore to any environment
7Testing Restores
Critical: A backup that cannot be restored is worthless
Schedule monthly restore tests to a staging environment. Document and time the entire process.
Complete Restore Script
1#!/bin/bash2# Odoo Restore Script3# Usage: ./odoo-restore.sh backup_name target_database45set -e67BACKUP_NAME="$1"8TARGET_DB="${2:-odoo_restored}"9BACKUP_DIR="/var/backups/odoo"10FILESTORE_PATH="/opt/odoo/.local/share/Odoo/filestore"1112if [ -z "$BACKUP_NAME" ]; then13 echo "Usage: ./odoo-restore.sh backup_name [target_database]"14 exit 115fi1617echo "Restoring ${BACKUP_NAME} to database ${TARGET_DB}..."1819# 1. Stop Odoo service (for safety)20echo "Step 1/5: Stopping Odoo service..."21sudo systemctl stop odoo2223# 2. Create target database24echo "Step 2/5: Creating target database..."25sudo -u postgres dropdb --if-exists "${TARGET_DB}"26sudo -u postgres createdb -O odoo "${TARGET_DB}"2728# 3. Restore database from pg_dump29echo "Step 3/5: Restoring PostgreSQL database..."30pg_restore -d "${TARGET_DB}" -O -x "${BACKUP_DIR}/${BACKUP_NAME}.dump"3132# 4. Restore filestore33echo "Step 4/5: Restoring filestore..."34mkdir -p "${FILESTORE_PATH}/${TARGET_DB}"35tar -xzf "${BACKUP_DIR}/${BACKUP_NAME}_filestore.tar.gz" -C "${FILESTORE_PATH}/${TARGET_DB}/"36chown -R odoo:odoo "${FILESTORE_PATH}/${TARGET_DB}"3738# 5. Restart Odoo39echo "Step 5/5: Starting Odoo service..."40sudo systemctl start odoo4142echo ""43echo "Restore completed successfully!"44echo "Database: ${TARGET_DB}"45echo "Filestore: ${FILESTORE_PATH}/${TARGET_DB}"46echo ""47echo "Next steps:"48echo "1. Update odoo.conf to use database: ${TARGET_DB}"49echo "2. Test login and verify data integrity"50echo "3. Check attachments and uploaded files"Download from S3 and Restore
#!/bin/bash# Download backup from S3 and restoreS3_BUCKET="your-odoo-backups"S3_PATH="backups/production"BACKUP_NAME="$1"BACKUP_DIR="/var/backups/odoo"# Download from S3echo "Downloading backup from S3..."aws s3 cp "s3://${S3_BUCKET}/${S3_PATH}/${BACKUP_NAME}.dump" "${BACKUP_DIR}/"aws s3 cp "s3://${S3_BUCKET}/${S3_PATH}/${BACKUP_NAME}_filestore.tar.gz" "${BACKUP_DIR}/"# Run restore script./odoo-restore.sh "${BACKUP_NAME}"Verification Checklist
OEC.sh Backup Features
Skip the manual configuration. OEC.sh provides enterprise-grade backup features out of the box. Explore all features:
7 Backup Destinations
- AWS S3
- Cloudflare R2
- Backblaze B2
- MinIO (self-hosted)
- FTP/SFTP
- WebDAV
- Local storage
Scheduling Options
- Every 15 minutes
- Hourly backups
- Daily backups
- Weekly snapshots
- Monthly archives
- Custom schedules
- End-to-end encryption for all backup data
- One-click restore to production or staging
- Point-in-time recovery with WAL archiving
- Cross-region backup replication
- Email/Slack notifications on backup events
- Backup integrity verification
9Frequently Asked Questions
Related Guides
Backup and Recovery Guide
Complete disaster recovery procedures for Odoo.
Deploy Odoo on Cloud Server
Complete guide to deploying Odoo on any VPS or cloud server.
Odoo Docker Deployment
Production-ready Docker Compose setup for Odoo.
Performance Optimization
Tune PostgreSQL and Odoo for maximum performance.