-
Notifications
You must be signed in to change notification settings - Fork 29
/
backup.sh
457 lines (391 loc) · 15.2 KB
/
backup.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
#!/bin/bash
#
# bash-backup V1.2
#################################################################
# You need megatools in order to upload your backup file to MEGA
# Download megatools from http://megatools.megous.com/
#################################################################
# Simple backup script for GNU/Linux servers
# Main features:
# - Backup custom files and directories
# - Backup MySQL/PostgreSQL/MongoDB databases
# - Copy/SCP/FTP to another server or mounted media
# - Backup GitLab
# - Upload to MEGA.nz cloud
# - Send a notification to your email
# - Logging all the activities
# - Encrypts backup file using GPG
# - Backup multiple MariaDB/MySQL docker containers
#
# Edit the configuration and run:
# $ sudo bash backup.sh
#
# Please help to simplify and develop new features
# Narbeh - http://narbeh.org - [email protected]
#################################################################
################
# Configuration
################
# Server Name
server_name="hostname"
# Backup path
backup_path="/tmp"
# Script log file
log_file="/var/log/backup.log"
# Files to backup (Multi value)
backup_files_enable="no"
backup_files="/root/.bash_history /etc/passwd"
# Directories to backup (Multi value)
backup_dir_enable="no"
backup_directories="/etc /var/log /usr/local"
# backup sync directory to MinIO (Multi value)
backup_to_minio_enable="no"
minio_directories="/etc /var/log /usr/local"
minio_bucket=""
minio_cluster_name=""
# Copy to other media (Multi value)
external_copy="no"
external_storage="/mnt"
# Copy tar backup to MinIo
external_minio_copy="no"
external_minio_bucket=""
external_minio_cluster_name=""
# SCP to other server (Trusted servers for now)
scp_enable="no"
scp_server="1.2.3.4"
scp_port="22"
scp_username="root"
scp_path="/media/backups"
# Enable iptables backup
iptables_backup="no"
# Upload to FTP server (Using curl command)
ftp_enable="no"
ftp_server="1.2.3.4"
ftp_path="/backups"
ftp_username=""
ftp_password=""
# Send an email the result of the backup process
# You should have sendmail or postfix installed
send_email="no"
email_to="[email protected]"
# Encrypt archive file using GPG
gpg_enable="no"
gpg_public_recipient=""
# Upload to MEGA.nz if you have installed the client.
# /Root/ is the main directory in MEGA.nz
mega_enable="no"
mega_email=""
mega_pass=""
mega_path="/Root/backups" # /Root/ should always be here.
# Full MySQL dump (All Databases)
mysql_backup="no"
mysql_user=""
mysql_pass=""
# Full PostgreSQL dump (All Databases)
postgres_backup="no"
postgres_user=""
postgres_pass=""
postgres_database=""
postgres_host="localhost"
postgres_port="5432"
# MongoDB collection dump (MongoDB Version +3)
mongo_backup="no"
mongo_host="localhost"
mongo_port="27017"
mongo_database=""
mongo_collection=""
# Docker Mariadb/Mysql dump config
# pattern of backup most be like containerID:::user:::password:::database
# This script can backup multiple container with this pattern
docker_mysql_backup="no"
docker_mysql_containers=""
#################################################################
#################################################################
#################################################################
################
# Do the backup
################
case $1 in
"--fresh" )
rm /var/backup_lock 2> /dev/null;;
*)
:;;
esac
# Main variables
color='\033[0;36m'
color_fail='\033[0;31m'
nc='\033[0m'
hostname=$(hostname -s)
date_now=$(date +"%Y-%m-%d %H:%M:%S")
# Checking lock file
test -r /var/backup_lock
if [ $? -eq 0 ];then
echo -e "\n ${color}--- $date_now There is another backup process. \n${nc}"
echo "$date_now There is another backup process." >> $log_file
echo -e "\n ${color}--- $date_now If not, run the script with --fresh argument. \n${nc}"
exit
fi
touch /var/backup_lock 2> /dev/null
path_date=$(hostname -s)_$(date +"%Y-%m-%d-%H-%M-%S")
mkdir -p $backup_path/Backup/$path_date 2>> $log_file
echo -e "\n ${color}--- $date_now Backup started. \n${nc}"
echo "$date_now Backup started." >> $log_file
sleep 1
# Backing up the files
if [ $backup_files_enable = "yes" ]
then
echo -e "\n ${color}--- $date_now Backing up files \n${nc}"
echo "$date_now Backing up files" >> $log_file
mkdir $backup_path/Backup/$path_date/custom_files | tee -a $log_file
for backup_custom_files in $backup_files
do
echo "--> $backup_custom_files" | tee -a $log_file
cp $backup_files $backup_path/Backup/$path_date/custom_files/ 2>> $log_file
done
echo
fi
if [ $iptables_backup = "yes" ]
then
echo -e "\n ${color}--- $date_now Backing up iptables rules \n${nc}"
echo "$date_now Backing up iptables rules" >> $log_file
[ -d $backup_path/Backup/$path_date/custom_files ] || mkdir $backup_path/Backup/$path_date/custom_files
iptables-save > $backup_path/Backup/$path_date/custom_files/iptables-save
echo
fi
sleep 1
# Backing up the directories
if [ $backup_dir_enable = "yes" ]
then
echo -e "\n ${color}--- $date_now Backing up directories \n${nc}"
echo "$date_now Backing up directories" >> $log_file
for backup_dirs in $backup_directories
do
echo "--> $backup_dirs" | tee -a $log_file
dir_name=`echo $backup_dirs | cut -d / -f2- | sed 's/\//-/g'`
if [[ -d ${backup_dirs}/.git ]]; then
tar -cjf $backup_path/Backup/$path_date/$dir_name.tar.bz2 -X ${backup_dirs}/.gitignore $backup_dirs/ > /dev/null 2> /dev/null
else
tar -cjf $backup_path/Backup/$path_date/$dir_name.tar.bz2 $backup_dirs/ > /dev/null 2> /dev/null
fi
done
echo
fi
sleep 1
# Backing up the directories to MinIo
if [ $backup_to_minio_enable = "yes" ]
if ! [ -x "$(command -v mc)" ]; then
echo 'Error: minio client (mc) is not installed.' >&2
exit 1
fi
then
echo -e "\n ${color}--- $date_now Backing up directories \n${nc}"
echo "$date_now Backing up directories" >> $log_file
for backup_dirs in $minio_directories
do
echo "--> $backup_dirs" | tee -a $log_file
dir_name=`echo $backup_dirs | awk -F'/' '{print $NF}'`
mc mirror --overwrite $backup_dirs ${minio_cluster_name}/${minio_bucket}/${dir_name}
done
echo
fi
sleep 1
# MySQL backup
if [ $mysql_backup = "yes" ]
then
echo -e "\n ${color}--- $date_now MySQL backup enabled, backing up: \n${nc}"
echo "$date_now MySQL backup enabled, backing up" >> $log_file
# Using ionice for MySQL dump
ionice -c 3 mysqldump -u $mysql_user -p$mysql_pass --events --all-databases | gzip -9 > $backup_path/Backup/$path_date/MySQL_Full_Dump_$path_date.sql.gz | tee -a $log_file
if [ $? -eq 0 ]
then
echo -e "\n ${color}--- $date_now MySQL backup completed. \n${nc}"
echo "$date_now MySQL backup completed" >> $log_file
else
echo -e " ${color_fail} MySQL backup failed. ${nc} \n"
echo "$date_now MySQL backup failed" >> $log_file
fi
fi
sleep 1
# GitLab backup
if [ $gitlab_backup = "yes" ]
then
echo -e "\n ${color}--- $date_now GitLab backup enabled, backing up: \n${nc}"
echo "$date_now GitLab backup enabled, backing up" >> $log_file
gitlab_backup_path=`grep 'backup_path' $gitlab_config | grep -v manage | cut -d "=" -f2 | cut -d '"' -f2`
gitlab-rake gitlab:backup:create STRATEGY=${gitlab_mode} &> $log_file
if [ $? -eq 0 ]
then
last_backup_file=`ls -ltr ${gitlab_backup_path} | awk '{print $9}' | tail -n 1`
cp ${gitlab_backup_path}/${last_backup_file} $backup_path/Backup/$path_date/
echo -e "\n ${color}--- $date_now GitLab backup completed. \n${nc}"
echo "$date_now GitLab backup completed" >> $log_file
else
echo -e " ${color_fail} GitLab backup failed. ${nc} \n"
echo "$date_now GitLab backup failed" >> $log_file
fi
fi
sleep 1
# PostgreSQL backup
if [ $postgres_backup = "yes" ]
then
# Creating ~/.pgpass for PostgreSQL password
# PostgreSQL does not support inline password
# Know better solution? Let me know.
USERNAME=`whoami`
CUR_DATE=$(date +"%Y-%m-%d-%H-%M-%S")
if [ $USERNAME = "root" ]
then
echo "$postgres_host:$postgres_port:$postgres_database:$postgres_user:$postgres_pass" > /root/.pgpass
chmod 600 /root/.pgpass
else
echo "$postgres_host:$postgres_port:$postgres_database:$postgres_user:$postgres_pass" > /home/$USERNAME/.pgpass
chmod 600 /home/$USERNAME/.pgpass
fi
echo -e "\n ${color}--- $date_now PostgreSQL backup enabled, backing up: \n${nc}"
echo "$date_now PostgreSQL backup enabled, backing up" >> $log_file
# Using ionice for PostgreSQL dump
ionice -c 3 pg_dump -p $postgres_port -h $postgres_host -Fc -U $postgres_user $postgres_database > ${backup_path}/Backup/${path_date}/Postgres_Full_Dump_${path_date}.dump | tee -a $log_file
if [ $? -eq 0 ]
then
echo -e "\n ${color}--- $date_now PostgreSQL backup completed. \n${nc}"
echo "$date_now PostgreSQL backup completed" >> $log_file
fi
fi
sleep 1
# MongoDB backup
if [ $mongo_backup = "yes" ]
then
echo -e "\n ${color}--- $date_now MongoDB backup enabled, backing up: \n${nc}"
echo "$date_now MongoDB backup enabled, backing up" >> $log_file
# Using ionice for MongoDB dump
ionice -c 3 mongodump --host $mongo_host --collection $mongo_collection --db $mongo_database --gzip --archive=${backup_path}/Backup/${path_date}/MongoDB_${mongo_collection}_${path_date}.dump | tee -a $log_file
if [ $? -eq 0 ]
then
echo -e "\n ${color}--- $date_now MongoDB backup completed. \n${nc}"
echo "$date_now MongoDB backup completed" >> $log_file
fi
fi
sleep 1
# Docker Backup
# Mariadb or Mysql backup
if [ $docker_mysql_backup = "yes" ]
then
echo -e "\n ${color}--- $date_now Docker Mariadb/MySQL backup enabled, backing up: \n${nc}"
echo "$date_now Docker MySQL backup enabled, backing up" >> $log_file
for docker_mysql_container in $docker_mysql_containers
do
docker_mysql_container_id=`echo $docker_mysql_container | awk -F":::" '{print $1}'`
docker_mysql_container_name=`docker ps --filter "id=$docker_mysql_container_id" | awk '{print $11}'`
docker_mysql_user=`echo $docker_mysql_container | awk -F":::" '{print $2}'`
docker_mysql_pass=`echo $docker_mysql_container | awk -F":::" '{print $3}'`
docker_mysql_database=`echo $docker_mysql_container | awk -F":::" '{print $4}'`
docker exec $docker_mysql_container_id /usr/bin/mysqldump -u $docker_mysql_user --password=$docker_mysql_pass $docker_mysql_database | gzip -9 > $backup_path/Backup/$path_date/Docker_MySQL_${docker_mysql_container_name}_Dump_$path_date.sql.gz | tee -a $log_file
if [ $? -eq 0 ]
then
echo -e "\n ${color}--- $date_now Docker Mariadb/MySQL backup completed. \n${nc}"
echo "$date_now Backing up files" >> $log_file
fi
done
fi
############################################################################################
# Create TAR file
echo -e "\n ${color}--- $date_now Creating TAR file located in $backup_path/Full_Backup_$path_date.tar.bz2 \n${nc}"
echo "$date_now Creating TAR file located in $backup_path/Full_Backup_$path_date.tar.bz2" >> $log_file
tar -cjf $backup_path/Full_Backup_${path_date}.tar.bz2 $backup_path/Backup/$path_date 2> /dev/null
rm -rf $backup_path/Backup/
final_archive="Full_Backup_${path_date}.tar.bz2"
sleep 1
############################################################################################
# Encrypt using GPG
if [ $gpg_enable = "yes" ]
then
echo -e "\n ${color}--- $date_now Encrypting archive file using $gpg_public_recipient key\n${nc}"
echo "$date_now Encrypting archive file using $gpg_public_recipient key" >> $log_file
gpg --yes --always-trust -e -r $gpg_public_recipient $backup_path/Full_Backup_${path_date}.tar.bz2
# Removing the unencrypted archive file
rm $backup_path/Full_Backup_${path_date}.tar.bz2
final_archive="Full_Backup_${path_date}.tar.bz2.gpg"
fi
sleep 1
# Copy to other storage
if [ $external_copy = "yes" ]
then
for cp_paths in $external_storage
do
echo -e "\n ${color}--- $date_now Copy backup archive to $cp_paths: \n${nc}"
echo "$date_now Copy backup archive to $cp_paths" >> $log_file
cp $backup_path/$final_archive $cp_paths/
if [ $? -eq 0 ]
then
echo -e "Copied to $cp_paths. \n"
echo "$date_now Copied to $cp_paths" >> $log_file
else
echo -e " ${color_fail} Copy to $cp_paths failed. ${nc} \n"
echo "$date_now Copy to $cp_paths failed. Please investigate." >> $log_file
fi
done
fi
sleep 1
# SCP to other server
if [ $scp_enable = "yes" ]
then
echo -e "\n ${color}--- $date_now SCP backup archive to $scp_server: \n${nc}"
echo "$date_now SCP backup archive to $scp_server" >> $log_file
scp -P $scp_port $backup_path/$final_archive '$scp_username'@'$scp_server':$scp_path
echo "$date_now SCP done" | tee -a $log_file
fi
sleep 1
# Upload to FTP server
if [ $ftp_enable = "yes" ]
then
if [ `which curl` ]
then
echo -e "\n ${color}--- $date_now Uploading backup archive to FTP server $ftp_server \n${nc}"
echo "$date_now Uploading backup archive to FTP server $ftp_server" >> $log_file
curl --connect-timeout 30 -S -T $backup_path/$final_archive ftp://$ftp_server/$ftp_path --user $ftp_username:$ftp_password | tee -a $log_file
if [ $? -eq 0 ]
then
echo "$date_now FTP Upload Done" | tee -a $log_file
else
echo -e "\n ${color_fail}--- $date_now FTP upload failed. \n${nc}"
echo "$date_now FTP upload failed. Please investigate." >> $log_file
fi
else
echo -e " ${color_fail}--- $date_now You have been enabled FTP upload. ${nc}"
echo -e " ${color_fail}--- $date_now You need to install curl package. ${nc}"
echo -e " ${color_fail}--- $date_now FTP upload failed. ${nc}"
echo "$date_now FTP upload failed. Install 'curl' package." >> $log_file
fi
fi
# Upload archive file to MEGA.nz
if [ $mega_enable = "yes" ]
then
if [ `which megaput` ]
then
echo -e "\n ${color}--- $date_now Uploading backup archive to MEGA.nz \n${nc}"
echo "$date_now Uploading backup archive to MEGA.nz" >> $log_file
megaput --reload --path $mega_path -u $mega_email -p $mega_pass $backup_path/$final_archive
echo "$date_now MEGA Upload Done. Path: $mega_path" | tee -a $log_file
else
echo -e " ${color_fail}--- $date_now You have been enabled MEGA upload. ${nc}"
echo -e " ${color_fail}--- $date_now You need to install megatools from http://megatools.megous.com ${nc}"
echo -e " ${color_fail}--- $date_now MEGA upload failed. ${nc}"
echo "$date_now Uploading to MEGA.nz failed. Install 'megatools' from http://megatools.megous.com" >> $log_file
fi
fi
# Send a simple email notification
if [ $send_email = "yes" ]
then
echo -e "Backup completed $date_now\nBackup path: $backup_path/$final_archive" | mail -s "Backup Result" $email_to >> $log_file 2>&1
fi
echo -e "\n"
echo -e "###########################################################"
echo -e "$date_now Backup finished"
echo -e "Backup path: $backup_path/$final_archive"
echo -e "###########################################################"
echo -e "\n"
echo "$date_now Backup finished. Backup path: $backup_path/$final_archive" >> $log_file
echo "#######################" >> $log_file
# Removing lock after successful backup
rm /var/backup_lock
exit 0