로그인

검색

[chat gpt vs. gemini] 챗지피티 와 제미나이 한테 도커 database backup script 만들라고 하기

[chat gpt vs. gemini] 챗지피티 와 제미나이 한테 도커 database backup script 만들라고 하기

 

- 두 AI 모두 무료사양을 이용

 

 

선 결론 

- chatGTP 보다 gemini 가 원하는 코딩을 해줬다.

 

 

요구된 코딩

- docker mysql db 를 찾아서, 백업을 한다. (env 에서 기본정보를 가져온다)

- docker maria db 를 찾아서, 백업을 한다. (env 에서 기본정보를 가져온다)

- docker progresql 를 찾아서, 백업을 한다. (env 에서 기본정보를 가져온다)

 

 

 

 

결과 (우분투 서버 24.04 에서 작동 확인)

 

#!/bin/bash

# --- Configuration ---
BACKUP_DIR="/vo2" # Base directory for all backups
DATE=$(date +%Y%m%d_%H%M%S)

# --- Functions ---

# Function to extract an environment variable from a container
get_env_var() {
    local container_id="$1"
    local var_name="$2"
    # Inspect container, format to get each env var on a new line, then grep
    docker inspect "$container_id" --format='{{range .Config.Env}}{{.}}{{"\n"}}{{end}}' | \
        grep "^${var_name}=" | head -n 1 | cut -d'=' -f2-
}

# Function to backup MySQL/MariaDB
backup_mysql_mariadb() {
    local container_id="$1"
    local container_name="$2"
    local db_user="$3"
    local db_password="$4"
    local db_name="$5"

    echo "--- Backing up MySQL/MariaDB container: $container_name (ID: $container_id) ---"

    # Export credentials so mysqldump can pick them up
    export MYSQL_USER="$db_user"
    export MYSQL_PASSWORD="$db_password"

    if [ -z "$db_name" ]; then
        echo "Warning: MYSQL_DATABASE not found for $container_name. Attempting to dump all user databases..."
        
        if [ -z "$db_user" ]; then
            echo "Error: No MYSQL_USER found. Cannot backup without a user. Skipping."
            unset MYSQL_USER MYSQL_PASSWORD # Unset immediately if error
            return 1
        fi
        
        echo "Dumping all databases (excluding system databases)..."
        local backup_file="$BACKUP_DIR/$container_name-$DATE-all_databases.gz"
        # Removed the MYSQL_DATABASE export from here as it's not needed for all-databases dump
        docker exec -i "$container_id" sh -c 'exec mysqldump -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" --all-databases --ignore-database=information_schema --ignore-database=performance_schema --ignore-database=mysql --ignore-database=sys' | gzip > "$backup_file"

        if [ $? -eq 0 ]; then
            echo "Successfully backed up all databases for $container_name to $backup_file"
        else
            echo "Error backing up all databases for $container_name."
        fi
    else
        echo "Backing up database: $db_name"
        local backup_file="$BACKUP_DIR/$container_name-$db_name-$DATE.gz"
        # Pass MYSQL_DATABASE as an environment variable to the exec'd shell
        docker exec -i "$container_id" sh -c 'export MYSQL_DATABASE="'"$db_name"'"; exec mysqldump -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE"' | gzip > "$backup_file"

        if [ $? -eq 0 ]; then
            echo "Successfully backed up $db_name for $container_name to $backup_file"
        else
            echo "Error backing up $db_name for $container_name."
        fi
    fi
    unset MYSQL_USER MYSQL_PASSWORD # Unset after use
    echo ""
}

# Function to backup PostgreSQL
backup_postgres() {
    local container_id="$1"
    local container_name="$2"
    local db_user="$3"
    local db_password="$4"
    local db_name="$5"

    echo "--- Backing up PostgreSQL container: $container_name (ID: $container_id) ---"

    # Export PGPASSWORD for pg_dump to pick up
    export PGPASSWORD="$db_password"

    if [ -z "$db_name" ]; then
        echo "Warning: POSTGRES_DB not found for $container_name. Attempting to dump all databases..."
        
        if [ -z "$db_user" ]; then
            echo "Error: No POSTGRES_USER found. Cannot backup without a user. Skipping."
            unset PGPASSWORD # Unset immediately if error
            return 1
        fi
        
        echo "Dumping all databases (excluding system databases)..."
        local backup_file="$BACKUP_DIR/$container_name-$DATE-all_databases.gz"
        # pg_dumpall does not take -d, it dumps all databases.
        docker exec -i "$container_id" pg_dumpall -U "$db_user" | gzip > "$backup_file"

        if [ $? -eq 0 ]; then
            echo "Successfully backed up all databases for $container_name to $backup_file"
        else
            echo "Error backing up all databases for $container_name."
        fi
    else
        echo "Backing up database: $db_name"
        local backup_file="$BACKUP_DIR/$container_name-$db_name-$DATE.gz"
        docker exec -i "$container_id" pg_dump -U "$db_user" -d "$db_name" | gzip > "$backup_file"

        if [ $? -eq 0 ]; then
            echo "Successfully backed up $db_name for $container_name to $backup_file"
        else
            echo "Error backing up $db_name for $container_name."
        fi
    fi
    unset PGPASSWORD # Unset after use
    echo ""
}

# --- Main Script Logic ---

echo "Starting Docker Database Backup Script..."
echo "Backup directory: $BACKUP_DIR"
echo "Current date: $DATE"
echo ""

# Create backup directory if it doesn't exist
mkdir -p "$BACKUP_DIR" || { echo "Error: Could not create backup directory $BACKUP_DIR. Exiting."; exit 1; }

# Get a list of all running Docker containers
CONTAINER_IDS=$(docker ps -q)

if [ -z "$CONTAINER_IDS" ]; then
    echo "No running Docker containers found."
    exit 0
fi

for ID in $CONTAINER_IDS; do
    CONTAINER_NAME=$(docker inspect -f '{{.Name}}' "$ID" | sed 's/^\///') # Remove leading slash
    CONTAINER_IMAGE=$(docker inspect -f '{{.Config.Image}}' "$ID")

    echo "Processing container: $CONTAINER_NAME (Image: $CONTAINER_IMAGE)"

    # --- Determine DB Type and Extract Credentials ---
    DB_TYPE="unknown"
    DB_USER=""
    DB_PASSWORD=""
    DB_NAME=""

    # Check for MySQL/MariaDB
    if [[ "$CONTAINER_IMAGE" == *mysql* ]] || [[ "$CONTAINER_IMAGE" == *mariadb* ]]; then
        DB_TYPE="mysql_mariadb"
        
        # Try to get specific user and password first
        DB_USER=$(get_env_var "$ID" "MYSQL_USER")
        DB_PASSWORD=$(get_env_var "$ID" "MYSQL_PASSWORD")
        DB_NAME=$(get_env_var "$ID" "MYSQL_DATABASE")

        if [ -z "$DB_USER" ]; then
            # Fallback to root if MYSQL_USER is not set
            DB_USER="root"
            DB_PASSWORD=$(get_env_var "$ID" "MYSQL_ROOT_PASSWORD")
            if [ -z "$DB_PASSWORD" ]; then
                echo "Warning: No MYSQL_ROOT_PASSWORD or MYSQL_PASSWORD found for $CONTAINER_NAME. MySQL/MariaDB backup might fail."
            fi
        fi

        if [ -z "$DB_USER" ] || [ -z "$DB_PASSWORD" ]; then
            echo "Error: Could not retrieve MySQL/MariaDB credentials (MYSQL_USER/PASSWORD or MYSQL_ROOT_PASSWORD) for $CONTAINER_NAME. Skipping."
            continue
        fi

    # Check for PostgreSQL
    elif [[ "$CONTAINER_IMAGE" == *postgres* ]]; then
        DB_TYPE="postgres"
        DB_USER=$(get_env_var "$ID" "POSTGRES_USER")
        DB_PASSWORD=$(get_env_var "$ID" "POSTGRES_PASSWORD")
        DB_NAME=$(get_env_var "$ID" "POSTGRES_DB")

        if [ -z "$DB_USER" ]; then
             DB_USER="postgres" # Default PostgreSQL user if not specified
        fi

        if [ -z "$DB_PASSWORD" ]; then
            echo "Error: Could not retrieve PostgreSQL password (POSTGRES_PASSWORD) for $CONTAINER_NAME. Skipping."
            continue
        fi
    fi

    # --- Perform Backup based on DB Type ---
    case "$DB_TYPE" in
        "mysql_mariadb")
            backup_mysql_mariadb "$ID" "$CONTAINER_NAME" "$DB_USER" "$DB_PASSWORD" "$DB_NAME"
            ;;
        "postgres")
            backup_postgres "$ID" "$CONTAINER_NAME" "$DB_USER" "$DB_PASSWORD" "$DB_NAME"
            ;;
        *)
            echo "Skipping unknown database type for container: $CONTAINER_NAME (Image: $CONTAINER_IMAGE)"
            echo ""
            ;;
    esac

done

sudo find "$BACKUP_DIR" -name "*.*" -mtime +1 -exec rm {} \;                    #하루지난 파일 삭제

echo "Docker Database Backup Script Finished."
echo "Backups are located in: $BACKUP_DIR"

 

$chmod +x dbbcakup.sh

 

 

백업된 데이터 형식은 다음과 같다.  

wordpress-db-1-exampledb-20250609_101625.gz

잘 백업되었는지 검증해 보려면, zcat 을 하면 된다.

$zcat wordpress-db-1-exampledb-20250609_101259.gz

$zless wordpress-db-1-exampledb-20250609_101259.gz          #페이지별로 끈어서 봄    'q' 중단

$gzip -d -k wordpress-db-1-exampledb-20250609_101259.gz       #압축풀기, sql 확장자로 됨      

 

 

이 게시물을

이 댓글을 삭제하시겠습니까?