feat: add backup and email configuration scripts and environment files

- Introduced backup scripts for S3 and Google Drive, including cron job setup for automated backups.
- Added email configuration script to set up SMTP settings for ERPNext.
- Created environment files for backup configurations (backup.env, gdrive-backup.env, email.env).
- Updated docker-compose files to support new backup services and configurations.
This commit is contained in:
Tushar 2025-03-20 09:17:35 +00:00
parent 973eafff69
commit 56cef5fe68
14 changed files with 245 additions and 1 deletions

8
backup.env Normal file
View file

@ -0,0 +1,8 @@
# Backup schedule in cron format (every 6 hours by default)
BACKUP_CRONSTRING=@every 6h
# Optional: AWS S3 configuration if you want to push backups to S3
# AWS_ACCESS_KEY_ID=your_access_key
# AWS_SECRET_ACCESS_KEY=your_secret_key
# S3_BUCKET=your_bucket_name
# S3_REGION=your_region

18
backup.log Normal file
View file

@ -0,0 +1,18 @@
open /home/alsodev/compose.yaml: no such file or directory
open /home/alsodev/compose.yaml: no such file or directory
open /home/alsodev/compose.yaml: no such file or directory
open /home/alsodev/compose.yaml: no such file or directory
open /home/alsodev/compose.yaml: no such file or directory
Backup completed at ./backups/20250319_180001
open /home/alsodev/compose.yaml: no such file or directory
open /home/alsodev/compose.yaml: no such file or directory
open /home/alsodev/compose.yaml: no such file or directory
open /home/alsodev/compose.yaml: no such file or directory
open /home/alsodev/compose.yaml: no such file or directory
Backup completed at ./backups/20250320_000001
open /home/alsodev/compose.yaml: no such file or directory
open /home/alsodev/compose.yaml: no such file or directory
open /home/alsodev/compose.yaml: no such file or directory
open /home/alsodev/compose.yaml: no such file or directory
open /home/alsodev/compose.yaml: no such file or directory
Backup completed at ./backups/20250320_060002

26
backup.sh Executable file
View file

@ -0,0 +1,26 @@
#!/bin/bash
# Path to your docker-compose files
COMPOSE_FILES="-f compose.yaml -f overrides/compose.mariadb.yaml -f overrides/compose.redis.yaml -f overrides/compose.https.yaml"
# Create backup with files
docker compose $COMPOSE_FILES exec backend bench --site all backup --with-files
# Optional: Copy backups to a local directory outside the Docker volume
# Create a backups directory if it doesn't exist
mkdir -p ./backups
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
docker compose $COMPOSE_FILES exec backend mkdir -p /home/frappe/frappe-bench/backups-export
docker compose $COMPOSE_FILES exec backend cp -r /home/frappe/frappe-bench/sites/*/backup/* /home/frappe/frappe-bench/backups-export/
# Copy the backups from the container to the host
docker compose $COMPOSE_FILES cp backend:/home/frappe/frappe-bench/backups-export/ ./backups/$TIMESTAMP
# Cleanup the temporary directory in the container
docker compose $COMPOSE_FILES exec backend rm -rf /home/frappe/frappe-bench/backups-export
echo "Backup completed at ./backups/$TIMESTAMP"
# Optional: Implement backup rotation/cleanup to prevent using too much disk space
# Keep only the last 7 days of backups
find ./backups -type d -mtime +7 -exec rm -rf {} \; 2>/dev/null || true

29
create-site.yaml Normal file
View file

@ -0,0 +1,29 @@
services:
create-site:
image: frappe/erpnext:v15.54.4
entrypoint:
- bash
- -c
command:
- >
wait-for-it -t 120 db:3306;
wait-for-it -t 120 redis-cache:6379;
wait-for-it -t 120 redis-queue:6379;
export start=`date +%s`;
until [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".db_host // empty"` ]] && \
[[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".redis_cache // empty"` ]] && \
[[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".redis_queue // empty"` ]];
do
echo "Waiting for sites/common_site_config.json to be created";
sleep 5;
if (( `date +%s`-start > 120 )); then
echo "could not find sites/common_site_config.json with required keys";
exit 1
fi
done;
echo "sites/common_site_config.json found";
rm -rf sites/erpnext.appsatile.com;
mysql -h db -uroot -p123 -e "DROP DATABASE IF EXISTS _1a2a97c0df78d27f";
bench new-site --mariadb-root-username=root --db-root-password=123 --admin-password=admin123 --db-host=db --mariadb-user-host-login-scope=% --install-app erpnext erpnext.appsatile.com;
volumes:
- sites:/home/frappe/frappe-bench/sites

8
email.env Normal file
View file

@ -0,0 +1,8 @@
# Email configuration
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USE_TLS=1
MAIL_LOGIN=your-email@gmail.com
MAIL_PASSWORD=your-app-password
MAIL_EMAIL_ID=your-email@gmail.com
MAIL_SENDER_NAME=ERPNext Administrator

10
gdrive-backup.env Normal file
View file

@ -0,0 +1,10 @@
# Google Drive rclone configuration
# You'll need to generate this token using rclone setup on your local machine first
RCLONE_GDRIVE_TOKEN={"access_token":"YOUR_ACCESS_TOKEN","token_type":"Bearer","refresh_token":"YOUR_REFRESH_TOKEN","expiry":"EXPIRY_TIMESTAMP"}
# Optional: If using a Team Drive (Google Workspace)
RCLONE_TEAM_DRIVE_ID=
# Optional: If you want to use a specific folder within your Google Drive
# Get this ID from the URL when you're in the folder: https://drive.google.com/drive/folders/YOUR_FOLDER_ID
RCLONE_FOLDER_ID=

52
gdrive-backup.yaml Normal file
View file

@ -0,0 +1,52 @@
services:
backup:
image: frappe/erpnext:v15.54.4
entrypoint: ["bash", "-c"]
command:
- |
# Install rclone if not already installed
if ! command -v rclone &> /dev/null; then
echo "Installing rclone..."
curl https://rclone.org/install.sh | bash
fi
# Create a backup of all sites with files
echo "Creating backup..."
bench --site all backup --with-files
# Configure rclone for Google Drive if not already configured
if [ ! -f /root/.config/rclone/rclone.conf ]; then
mkdir -p /root/.config/rclone/
echo "Creating rclone config from environment variables..."
cat > /root/.config/rclone/rclone.conf << EOF
[gdrive]
type = drive
token = ${RCLONE_GDRIVE_TOKEN}
team_drive = ${RCLONE_TEAM_DRIVE_ID}
root_folder_id = ${RCLONE_FOLDER_ID}
EOF
fi
# Upload backups to Google Drive
echo "Uploading backups to Google Drive..."
TODAY=$(date +%Y-%m-%d)
for site_path in /home/frappe/frappe-bench/sites/*/; do
site=$(basename "$site_path")
if [ "$site" != "assets" ] && [ -d "${site_path}backup" ]; then
echo "Pushing backup for $site to Google Drive..."
rclone copy ${site_path}backup gdrive:ERPNext_Backups/$site/$TODAY/ --progress
fi
done
# Cleanup old backups (keeping last 7 days)
echo "Cleaning up old local backups..."
find /home/frappe/frappe-bench/sites/*/backup -type f -mtime +7 -delete
volumes:
- sites:/home/frappe/frappe-bench/sites
- rclone-config:/root/.config/rclone
volumes:
sites:
external: true
name: frappe_docker_sites
rclone-config:

View file

@ -125,7 +125,7 @@ services:
- sites:/home/frappe/frappe-bench/sites
- logs:/home/frappe/frappe-bench/logs
ports:
- "8080:8080"
- "80:8080"
queue-long:
image: frappe/erpnext:v15.54.5

7
run-backup-cron.sh Executable file
View file

@ -0,0 +1,7 @@
#!/bin/bash
# Path to your docker-compose files
COMPOSE_FILES="-f compose.yaml -f overrides/compose.mariadb.yaml -f overrides/compose.redis.yaml -f overrides/compose.https.yaml -f overrides/compose.backup-cron.yaml"
# Start the backup cron service
docker compose --env-file backup.env $COMPOSE_FILES up -d cron

9
run-gdrive-backup.sh Executable file
View file

@ -0,0 +1,9 @@
#!/bin/bash
# Path to your Google Drive backup configuration
GDRIVE_BACKUP_FILE="gdrive-backup.yaml"
# Run the backup with Google Drive environment variables
docker compose -f $GDRIVE_BACKUP_FILE --env-file gdrive-backup.env up backup
echo "Google Drive backup completed at $(date)"

9
run-s3-backup.sh Executable file
View file

@ -0,0 +1,9 @@
#!/bin/bash
# Path to your S3 backup configuration
S3_BACKUP_FILE="s3-backup.yaml"
# Run the backup with appropriate environment variables
docker compose -f $S3_BACKUP_FILE --env-file backup.env up backup
echo "S3 backup completed at $(date)"

34
s3-backup.yaml Normal file
View file

@ -0,0 +1,34 @@
services:
backup:
image: frappe/erpnext:v15.54.4
entrypoint: ["bash", "-c"]
command:
- |
# Create a backup of all sites with files
bench --site all backup --with-files
# Upload backups to S3
for site_path in /home/frappe/frappe-bench/sites/*/; do
site=$(basename "$site_path")
if [ -d "${site_path}backup" ]; then
echo "Pushing backup for $site to S3..."
cd "${site_path}backup"
# Use aws cli to sync backups to S3
aws s3 sync . s3://${S3_BUCKET}/${site}/$(date +%Y-%m-%d)/
fi
done
# Cleanup old backups (keeping last 7 days)
find /home/frappe/frappe-bench/sites/*/backup -type f -mtime +7 -delete
environment:
- AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
- AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
- S3_BUCKET=${S3_BUCKET}
- AWS_DEFAULT_REGION=${S3_REGION}
volumes:
- sites:/home/frappe/frappe-bench/sites
volumes:
sites:
external: true
name: frappe_docker_sites

21
setup-email.sh Executable file
View file

@ -0,0 +1,21 @@
#!/bin/bash
# Read email configuration
source email.env
# Path to your docker-compose files
COMPOSE_FILES="-f compose.yaml -f overrides/compose.mariadb.yaml -f overrides/compose.redis.yaml -f overrides/compose.https.yaml"
# Configure email settings
docker compose $COMPOSE_FILES exec backend bench --site erpnext.appsatile.com set-config -g mail_server "$MAIL_HOST"
docker compose $COMPOSE_FILES exec backend bench --site erpnext.appsatile.com set-config -g mail_port "$MAIL_PORT"
docker compose $COMPOSE_FILES exec backend bench --site erpnext.appsatile.com set-config -g use_tls "$MAIL_USE_TLS"
docker compose $COMPOSE_FILES exec backend bench --site erpnext.appsatile.com set-config -g mail_login "$MAIL_LOGIN"
docker compose $COMPOSE_FILES exec backend bench --site erpnext.appsatile.com set-config -g mail_password "$MAIL_PASSWORD"
docker compose $COMPOSE_FILES exec backend bench --site erpnext.appsatile.com set-config -g auto_email_id "$MAIL_EMAIL_ID"
docker compose $COMPOSE_FILES exec backend bench --site erpnext.appsatile.com set-config -g email_sender_name "$MAIL_SENDER_NAME"
# Make these configurations take effect
docker compose $COMPOSE_FILES restart backend
echo "Email configuration completed"

13
setup-gdrive-backup-cron.sh Executable file
View file

@ -0,0 +1,13 @@
#!/bin/bash
# Add cron job to run Google Drive backup daily at 2 AM
CRON_JOB="0 2 * * * $(pwd)/run-gdrive-backup.sh >> $(pwd)/gdrive-backup.log 2>&1"
# Check if cron job already exists
if crontab -l 2>/dev/null | grep -q "run-gdrive-backup.sh"; then
echo "Google Drive backup cron job already exists"
else
# Add new cron job
(crontab -l 2>/dev/null; echo "$CRON_JOB") | crontab -
echo "Google Drive backup cron job added"
fi