What Needs to Be Backed Up
An Odoo backup has two parts — miss either one and your backup is incomplete:
| Component | Contains | Location |
|---|---|---|
| Database | All business data, configurations, users, settings | PostgreSQL |
| Filestore | Attachments, images, PDFs, uploaded documents | /var/lib/odoo/filestore/dbname/ |
Common mistake: Backing up only the database. Without the filestore, all attachments, product images, and uploaded documents are lost.
Backup Methods
Method 1: pg_dump + tar (Recommended)
#!/bin/bash
# backup.sh — run daily via cron
DATE=$(date +%Y%m%d_%H%M%S)
DB_NAME="production"
BACKUP_DIR="/opt/backups"
FILESTORE="/var/lib/odoo/filestore/$DB_NAME"
mkdir -p $BACKUP_DIR
# Database backup (compressed)
pg_dump -U odoo $DB_NAME | gzip > "$BACKUP_DIR/db_${DATE}.sql.gz"
# Filestore backup (compressed)
tar czf "$BACKUP_DIR/filestore_${DATE}.tar.gz" -C "$FILESTORE" .
# Verify backup files exist and have reasonable size
DB_SIZE=$(stat -f%z "$BACKUP_DIR/db_${DATE}.sql.gz" 2>/dev/null || stat -c%s "$BACKUP_DIR/db_${DATE}.sql.gz")
if [ "$DB_SIZE" -lt 1000 ]; then
echo "WARNING: Database backup suspiciously small ($DB_SIZE bytes)"
fi
echo "Backup completed: db_${DATE}.sql.gz + filestore_${DATE}.tar.gz"Method 2: Odoo Built-in Backup
# Via Odoo database manager (if enabled)
# /web/database/manager → Backup → Select database → Download
# Via command line
curl -X POST http://localhost:8069/web/database/backup \
-d "master_pwd=admin_password&name=production&backup_format=zip"The built-in backup creates a ZIP with both database dump and filestore. Convenient but slower than pg_dump for large databases.
Method 3: Docker Volume Backup
# Stop containers for consistent backup
docker compose stop odoo
# Backup database
docker compose exec -T db pg_dump -U odoo production | gzip > backup_db.sql.gz
# Backup filestore volume
docker run --rm -v deploymonkey_odoo-data:/data -v $(pwd):/backup \
alpine tar czf /backup/filestore.tar.gz -C /data .
# Restart
docker compose start odooOffsite Storage
# Upload to S3 (AWS, Wasabi, MinIO)
aws s3 cp $BACKUP_DIR/db_${DATE}.sql.gz s3://your-bucket/odoo-backups/
aws s3 cp $BACKUP_DIR/filestore_${DATE}.tar.gz s3://your-bucket/odoo-backups/
# Upload to Google Cloud Storage
gsutil cp $BACKUP_DIR/db_${DATE}.sql.gz gs://your-bucket/odoo-backups/
# Upload to Backblaze B2 (cheapest)
b2 upload-file your-bucket $BACKUP_DIR/db_${DATE}.sql.gz odoo-backups/db_${DATE}.sql.gzRetention Policy
# Recommended retention:
# Daily backups: keep 30 days
# Weekly backups: keep 12 weeks (3 months)
# Monthly backups: keep 12 months
# Yearly backups: keep 5 years
# Simple daily retention (30 days):
find $BACKUP_DIR -name "*.gz" -mtime +30 -deleteAutomated Backup with Cron
# crontab -e (as root or odoo user)
# Daily at 2:00 AM
0 2 * * * /opt/scripts/backup.sh >> /var/log/odoo-backup.log 2>&1Restore Process
# 1. Stop Odoo
systemctl stop odoo
# 2. Drop existing database (CAREFUL!)
sudo -u postgres dropdb production
sudo -u postgres createdb -O odoo production
# 3. Restore database
gunzip -c db_20260322.sql.gz | sudo -u postgres psql production
# 4. Restore filestore
rm -rf /var/lib/odoo/filestore/production/*
tar xzf filestore_20260322.tar.gz -C /var/lib/odoo/filestore/production/
chown -R odoo:odoo /var/lib/odoo/filestore/production/
# 5. Start Odoo
systemctl start odooBackup Verification
- Weekly: Check backup file sizes — compare against expected range
- Monthly: Restore to a test database and verify data integrity
- After major changes: Take a manual backup before module upgrades
The 3-2-1 Rule
- 3 copies of your data (production + local backup + offsite)
- 2 different storage types (disk + cloud object storage)
- 1 offsite copy (S3, GCS, or Backblaze)
DeployMonkey Backups
DeployMonkey handles all of this automatically: scheduled backups, multi-region offsite storage, retention policies, integrity verification, one-click restore, and AI-powered backup monitoring. Included in every plan, including free.