From 75c171ce09693636724c546cb8573e681575e89b Mon Sep 17 00:00:00 2001 From: "Kevin Veen-Birkenbach [aka. Frantz]" Date: Sun, 23 Jan 2022 17:20:42 +0100 Subject: [PATCH] Implemented database backup with mysqldump --- README.md | 3 +++ docker-volume-backup.py | 38 ++++++++++++++++++++++++-------------- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 1573b78..f89eac5 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,9 @@ To checkout what's going on in the mount container type in the following command docker run -it --entrypoint /bin/sh --rm --volumes-from {{container_name}} -v /Backups/:/Backups/ kevinveenbirkenbach/alpine-rsync ``` +## Setup +Install pandas + ## Optimation This setup script is not optimized yet for performance. Please optimized this script for performance if you want to use it in a professional environment. diff --git a/docker-volume-backup.py b/docker-volume-backup.py index acc6cd4..78ce92f 100644 --- a/docker-volume-backup.py +++ b/docker-volume-backup.py @@ -1,11 +1,12 @@ #!/bin/python # Backups volumes of running containers # -import subprocess, os, sys, pathlib +import subprocess, os, sys, pathlib, csv, pandas from datetime import datetime from pprint import pprint def bash(command): + print(command); process=subprocess.Popen([command],stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) out, err=process.communicate() stdout=out.splitlines() @@ -26,6 +27,8 @@ def list_to_string(list): return str(' '.join(list)); print('start backup routine...') +print('load connection data...'); +databases=pandas.read_csv("databases.csv",sep=";"); print('start volume backups...') backup_time=datetime.now().strftime("%Y%m%d%H%M%S") backups_folder='/Backups/' @@ -40,29 +43,36 @@ for volume_name in volume_names: print('skipped due to no running containers using this volume.'); else: container=containers[0] - print("stop containers:"); - print_bash("docker stop " + list_to_string(containers)) source_path_command="docker inspect --format \"{{ range .Mounts }}{{ if eq .Type \\\"volume\\\"}}{{ if eq .Name \\\"" + volume_name +"\\\"}}{{ println .Destination }}{{ end }}{{ end }}{{ end }}\" \""+ container +"\"" source_path_command_result_filtered=list(filter(None, bash(source_path_command))) for source_path in source_path_command_result_filtered: destination_path=backup_repository_folder+"latest/"+ volume_name - sql_destination_path=destination_path + "/files" + files_destination_path=destination_path + "/files" sql_destination_path=destination_path + "/sql" log_path=backup_repository_folder + "log.txt" backup_dir_path=backup_repository_folder + "diffs/"+ backup_time + "/" + volume_name files_backup_dir_path=backup_dir_path + "/files" sql_backup_dir_path=backup_dir_path + "/sql" - if os.path.exists(destination_path): - print("backup volume: " + volume_name); + + print("Create backup folder structure for " + volume_name); + pathlib.Path(sql_destination_path).mkdir(parents=True, exist_ok=True) + pathlib.Path(files_backup_dir_path).mkdir(parents=True, exist_ok=True) + pathlib.Path(files_destination_path).mkdir(parents=True, exist_ok=True) + pathlib.Path(sql_backup_dir_path).mkdir(parents=True, exist_ok=True) + + databases_entries=databases.loc[databases['container'] == container]; + if len(databases_entries) == 1: + database_entry=databases_entries.iloc[0]; + sql_destination_dir_file_path=sql_destination_path+"/backup.sql" + database_backup_command="docker exec "+ database_entry["container"] + " /usr/bin/mysqldump -u "+ database_entry["username"] + " -p"+ database_entry["password"] + " "+ database_entry["database"] + " > " + sql_destination_dir_file_path + print_bash(database_backup_command) + print_bash("cp -v " + sql_destination_dir_file_path + " " + sql_backup_dir_path) else: - print("first backup volume: " + volume_name); - pathlib.Path(sql_destination_path).mkdir(parents=True, exist_ok=True) - pathlib.Path(files_backup_dir_path).mkdir(parents=True, exist_ok=True) - pathlib.Path(sql_destination_path).mkdir(parents=True, exist_ok=True) - pathlib.Path(sql_backup_dir_path).mkdir(parents=True, exist_ok=True) - print_bash("docker run --rm --volumes-from " + container + " -v "+backups_folder+":"+ backups_folder +" \"kevinveenbirkenbach/alpine-rsync\" sh -c \"rsync -abP --delete --delete-excluded --log-file=" + log_path +" --backup-dir=" + files_backup_dir_path +" '"+ source_path +"/' " + sql_destination_path +"\"") - print("start containers:") - print_bash("docker start " + list_to_string(containers)) + print("stop containers:"); + print_bash("docker stop " + list_to_string(containers)) + print_bash("docker run --rm --volumes-from " + container + " -v "+backups_folder+":"+ backups_folder +" \"kevinveenbirkenbach/alpine-rsync\" sh -c \"rsync -abP --delete --delete-excluded --log-file=" + log_path +" --backup-dir=" + files_backup_dir_path +" '"+ source_path +"/' " + files_destination_path +"\"") + print("start containers:") + print_bash("docker start " + list_to_string(containers)) print("end backup routine for volume:" + volume_name) print('finished volume backups.') print('restart docker service...')