mirror of
https://github.com/frappe/frappe_docker.git
synced 2026-06-23 00:05:09 +00:00
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:
parent
973eafff69
commit
56cef5fe68
14 changed files with 245 additions and 1 deletions
8
backup.env
Normal file
8
backup.env
Normal 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
18
backup.log
Normal 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
26
backup.sh
Executable 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
29
create-site.yaml
Normal 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
8
email.env
Normal 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
10
gdrive-backup.env
Normal 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
52
gdrive-backup.yaml
Normal 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:
|
||||||
2
pwd.yml
2
pwd.yml
|
|
@ -125,7 +125,7 @@ services:
|
||||||
- sites:/home/frappe/frappe-bench/sites
|
- sites:/home/frappe/frappe-bench/sites
|
||||||
- logs:/home/frappe/frappe-bench/logs
|
- logs:/home/frappe/frappe-bench/logs
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "80:8080"
|
||||||
|
|
||||||
queue-long:
|
queue-long:
|
||||||
image: frappe/erpnext:v15.54.5
|
image: frappe/erpnext:v15.54.5
|
||||||
|
|
|
||||||
7
run-backup-cron.sh
Executable file
7
run-backup-cron.sh
Executable 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
9
run-gdrive-backup.sh
Executable 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
9
run-s3-backup.sh
Executable 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
34
s3-backup.yaml
Normal 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
21
setup-email.sh
Executable 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
13
setup-gdrive-backup-cron.sh
Executable 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
|
||||||
Loading…
Reference in a new issue