diff --git a/backup-docker-to-local.py b/backup-docker-to-local.py index a962efb..046ca7b 100644 --- a/backup-docker-to-local.py +++ b/backup-docker-to-local.py @@ -8,12 +8,10 @@ import pathlib import pandas from datetime import datetime -#Ok class BackupException(Exception): """Generic exception for backup errors.""" pass -# OK def execute_shell_command(command): """Execute a shell command and return its output.""" print(command) @@ -23,12 +21,10 @@ def execute_shell_command(command): raise BackupException(f"Error in command: {command}\nOutput: {out}\nError: {err}\nExit code: {process.returncode}") return [line.decode("utf-8") for line in out.splitlines()] -# OK def get_machine_id(): """Get the machine identifier.""" return execute_shell_command("sha256sum /etc/machine-id")[0][0:64] -# OK def create_backup_directories(base_dir, machine_id, repository_name, backup_time): """Create necessary directories for backup.""" version_dir = os.path.join(base_dir, machine_id, repository_name, backup_time) @@ -66,12 +62,24 @@ def backup_database(container, databases, version_dir, db_type): if db_type == 'mariadb': backup_command = f"docker exec {container} /usr/bin/mariadb-dump -u {database_entry['username']} -p{database_entry['password']} {database_entry['database']} > {backup_destination_file}" elif db_type == 'postgres': - backup_command = f"PGPASSWORD={database_entry['password']} docker exec -i {container} pg_dump -U {database_entry['username']} -d {database_entry['database']} -h localhost --no-password > {backup_destination_file}" - + if database_entry['password']: + # Include PGPASSWORD in the command when a password is provided + backup_command = ( + f"PGPASSWORD={database_entry['password']} docker exec -i {container} " + f"pg_dump -U {database_entry['username']} -d {database_entry['database']} " + f"-h localhost > {backup_destination_file}" + ) + else: + # Exclude PGPASSWORD and use --no-password when the password is empty + backup_command = ( + f"docker exec -i {container} pg_dump -U {database_entry['username']} " + f"-d {database_entry['database']} -h localhost --no-password " + f"> {backup_destination_file}" + ) + execute_shell_command(backup_command) print(f"Database backup for {container} completed.") -# OK def backup_volume(volume_name, version_dir): """Backup files of a volume.""" print(f"Starting backup routine for volume: {volume_name}") @@ -82,26 +90,23 @@ def backup_volume(volume_name, version_dir): execute_shell_command(rsync_command) print(f"Backup routine for volume: {volume_name} completed.") -# OK def has_image(container,image): """Check if the container is using the image""" image_info = execute_shell_command(f"docker inspect {container} | jq -r '.[].Config.Image'") return image in image_info[0] -# OK def stop_containers(containers): """Stop a list of containers.""" for container in containers: print(f"Stopping container {container}...") execute_shell_command(f"docker stop {container}") -# OK + def start_containers(containers): """Start a list of stopped containers.""" for container in containers: print(f"Starting container {container}...") execute_shell_command(f"docker start {container}") -# OK def get_container_with_image(containers,image): for container in containers: if has_image(container,image): @@ -152,7 +157,7 @@ def main(): # This whitelist is configurated for https://github.com/kevinveenbirkenbach/backup-docker-to-local stop_and_restart_not_needed = [ - 'baserow', + # 'baserow', Doesn't use an extra database 'element', 'gitea', 'listmonk',