# 서버 환경에서의 데이터 백업 가이드 ## 개요 이 가이드는 서버 환경에서 데이터를 효율적으로 백업하고 관리하는 방법을 설명합니다. 특히 Docker와 같은 컨테이너 환경을 운영하는 서버에서 안정적인 백업 시스템을 구축할 수 있도록 다양한 백업 전략과 자동화 스크립트 예제를 제공합니다. ## 목차 1. [백업 전략](#백업-전략) 2. [디렉토리 구조 및 설정](#디렉토리-구조-및-설정) 3. [증분 백업 구현](#증분-백업-구현) 4. [백업 자동화](#백업-자동화) 5. [원격 서버로 백업 전송](#원격-서버로-백업-전송) 6. [백업 로테이션 및 관리](#백업-로테이션-및-관리) 7. [예제 스크립트](#예제-스크립트) ## 백업 전략 서버 환경에서는 다음과 같은 항목들을 백업해야 합니다: - 애플리케이션 데이터 (웹 애플리케이션 데이터, 사용자 업로드 파일 등) - 서버 설정 파일 (nginx, apache 설정 등) - Docker 관련 데이터 (docker-compose.yml, Dockerfile, 볼륨 데이터 등) - 데이터베이스 백업 파일 백업 주기는 데이터의 중요도와 변경 빈도에 따라 결정해야 합니다: - 중요 데이터: 일일 백업 - 설정 파일: 변경 시마다 백업 - 전체 시스템: 주간 또는 월간 백업 ## 디렉토리 구조 및 설정 효율적인 백업을 위한 디렉토리 구조 예시: ``` /data/ ├── backup/ │ ├── source/ # 원본 백업 저장 │ ├── compress/ # 압축된 백업 파일 │ └── mirror/ # 미러링 백업 저장 (연도별/월별) ├── webapps/ # 웹 애플리케이션 디렉토리 └── upload/ # 업로드 파일 디렉토리 ``` 백업 디렉토리 초기 설정: ```bash #!/bin/bash BACKUP_DIR="/data/backup" SOURCE_DIR="/data/webapps" UPLOAD_DIR="/data/upload" BACKUP_SOURCE_PATH="${BACKUP_DIR}/source" BACKUP_COMPRESS_DIR="${BACKUP_DIR}/compress" BACKUP_MIRROR_DIR="${BACKUP_DIR}/mirror" # 필요한 디렉토리 생성 mkdir -p "${BACKUP_SOURCE_PATH}" mkdir -p "${BACKUP_COMPRESS_DIR}" mkdir -p "${BACKUP_MIRROR_DIR}" ``` ## 증분 백업 구현 rsync를 이용한 증분 백업 구현: ```bash #!/bin/bash SOURCE_DIR="/data/webapps" BACKUP_DIR="/data/backup" BACKUP_SOURCE_PATH="${BACKUP_DIR}/source" LATEST_LINK="${BACKUP_DIR}/latest" # rsync를 이용한 증분 백업 rsync -av --delete \ "${SOURCE_DIR}/" \ --link-dest "${LATEST_LINK}" \ --exclude=".cache" \ "${BACKUP_SOURCE_PATH}" # 심볼릭 링크 업데이트 rm -rf "${LATEST_LINK}" ln -s "${BACKUP_SOURCE_PATH}" "${LATEST_LINK}" ``` ## 백업 자동화 ### Cron을 이용한 자동화 아래와 같이 crontab을 설정하여 백업을 자동화할 수 있습니다: ``` # 매일 오전 3시에 백업 실행 0 3 * * * /path/to/daily_backup_script.sh # 매주 일요일 오전 2시에 백업 실행 0 2 * * 0 /path/to/weekly_backup_script.sh # 매월 마지막 날 오전 1시에 백업 실행 0 1 28-31 * * [ "$(date -d '+1 day' +\%d)" -eq "1" ] && /path/to/monthly_backup_script.sh ``` ### 월말 체크 스크립트 월의 마지막 날에만 실행할 작업을 위한 스크립트: ```bash #!/bin/bash TODAY=$(date +%d) TOMORROW=$(date -d "1 day" +%d) # 내일의 날짜가 오늘보다 작으면 월의 마지막 날 if [ $TOMORROW -lt $TODAY ]; then # 월말 백업 작업 실행 /path/to/monthly_backup.sh exit 0 fi exit 1 ``` ## 원격 서버로 백업 전송 ### rsync를 이용한 백업 전송 ```bash rsync -avz --delete /data/backup/compress/ user@remote-server:/remote/backup/directory/ ``` ### lftp를 이용한 FTP 전송 ```bash lftp -c "open -u username,password ftp-server -p 21; mirror -R /data/backup/mirror /remote/directory" ``` 실제 예제(비밀번호 보안 주의): ```bash lftp -c "open -u admin,password 118.45.160.139 -p 2121; mirror -R /data/backup/mirror /homes/java/203" ``` ### 암호화된 백업 전송 민감한 데이터를 안전하게 전송하기 위한 암호화 방법: ```bash # 백업 파일 암호화 tar -czf - /data/backup/source | gpg -e -r recipient@email.com > backup-$(date +%Y%m%d).tar.gz.gpg # 암호화된 백업 파일 전송 scp backup-$(date +%Y%m%d).tar.gz.gpg user@remote-server:/remote/backup/directory/ ``` ## 백업 로테이션 및 관리 ### 월별 백업 로테이션 구현 오래된 백업을 자동으로 삭제하고 새 백업을 유지하는 로테이션 시스템: ```bash #!/bin/bash set -o errexit set -o nounset set -o pipefail # 백업 디렉토리 설정 BACKUP_DIR="/data/backup" MIRROR_DIR="/data/backup/mirror/$(date +%Y%m)" MIRROR_CHECK_DIR="/data/backup/mirror/$(date -d "-6 month" +%Y%m)" # 필요한 디렉토리 생성 if [ ! -d "${MIRROR_DIR}" ]; then mkdir -p "${MIRROR_DIR}" fi # 6개월 이상 지난 백업 삭제 if [ -d "${MIRROR_CHECK_DIR}" ]; then rm -rf "${MIRROR_CHECK_DIR}" fi # 압축 백업 파일을 월별 디렉토리로 복사 cp -R /data/backup/compress/* "${MIRROR_DIR}" ``` ### Docker 볼륨 데이터 백업 Docker 볼륨 데이터를 외부에서 백업하는 방법: ```bash # Docker 볼륨 데이터 위치 (일반적으로 /var/lib/docker/volumes/) DOCKER_VOLUME_PATH="/var/lib/docker/volumes" BACKUP_PATH="/data/backup/docker_volumes" # 백업 디렉토리 생성 mkdir -p "${BACKUP_PATH}" # Docker 볼륨 데이터 백업 tar -czf "${BACKUP_PATH}/docker_volumes-$(date +%Y%m%d).tar.gz" -C "${DOCKER_VOLUME_PATH}" . ``` ## 예제 스크립트 ### 소스 코드 및 업로드 파일 백업 스크립트 ```bash #!/bin/bash set -o errexit set -o nounset set -o pipefail BACKUP_DIR="" SOURCE_DIR_UPLOAD="" SOURCE_DIR_WEBAPPS="" BACKUP_COMPRESS_DIR="" BACKUP_UPLOAD_PATH="" BACKUP_WEBAPPS_PATH="" UPLOAD_TARGET="" WEBAPPS_TARGET="" LATEST_UPLOAD_LINK="" LATEST_WEBAPPS_LINK="" SOURCE_DIR_UPLOAD="/data/upload" SOURCE_DIR_WEBAPPS="/data/webapps" BACKUP_DIR="/data/backup" BACKUP_UPLOAD_PATH="${BACKUP_DIR}/upload/source" BACKUP_WEBAPPS_PATH="${BACKUP_DIR}/webapps/source" BACKUP_COMPRESS_DIR="${BACKUP_DIR}/compress" UPLOAD_TARGET="${BACKUP_COMPRESS_DIR}/upload.tar.gz" WEBAPPS_TARGET="${BACKUP_COMPRESS_DIR}/webapps.tar.gz" LATEST_UPLOAD_LINK="${BACKUP_DIR}/upload/latest" LATEST_WEBAPPS_LINK="${BACKUP_DIR}/webapps/latest" # 필요한 디렉토리 생성 if [ ! -d "${BACKUP_DIR}" ]; then mkdir -p "${BACKUP_DIR}"; fi if [ ! -d "${BACKUP_UPLOAD_PATH}" ]; then mkdir -p "${BACKUP_UPLOAD_PATH}"; fi if [ ! -d "${BACKUP_WEBAPPS_PATH}" ]; then mkdir -p "${BACKUP_WEBAPPS_PATH}"; fi if [ ! -d "${BACKUP_COMPRESS_DIR}" ]; then mkdir -p "${BACKUP_COMPRESS_DIR}"; fi # rsync를 이용한 증분 백업 (업로드 디렉토리) rsync -av --delete \ "${SOURCE_DIR_UPLOAD}/" \ --link-dest "${LATEST_UPLOAD_LINK}" \ --exclude=".cache" \ "${BACKUP_UPLOAD_PATH}" # rsync를 이용한 증분 백업 (웹앱 디렉토리) rsync -av --delete \ "${SOURCE_DIR_WEBAPPS}/" \ --link-dest "${LATEST_WEBAPPS_LINK}" \ --exclude=".cache" \ "${BACKUP_WEBAPPS_PATH}" # 심볼릭 링크 업데이트 및 압축 rm -rf "${LATEST_UPLOAD_LINK}" rm -rf "${UPLOAD_TARGET}" rm -rf "${LATEST_WEBAPPS_LINK}" rm -rf "${WEBAPPS_TARGET}" ln -s "${BACKUP_UPLOAD_PATH}" "${LATEST_UPLOAD_LINK}" ln -s "${BACKUP_WEBAPPS_PATH}" "${LATEST_WEBAPPS_LINK}" tar -cf "${UPLOAD_TARGET}" "${BACKUP_UPLOAD_PATH}" tar -cf "${WEBAPPS_TARGET}" "${BACKUP_WEBAPPS_PATH}" ``` ### 미러링 백업 및 원격 전송 스크립트 ```bash #!/bin/bash set -o errexit set -o nounset set -o pipefail # 백업 디렉토리 설정 MIRROR_DIR="/data/backup/mirror/$(date +%Y%m)" MIRROR_CHECK_DIR="/data/backup/mirror/$(date -d "-6 month" +%Y%m)" # 필요한 디렉토리 생성 if [ ! -d "${MIRROR_DIR}" ]; then mkdir -p "${MIRROR_DIR}" fi # 6개월 이상 지난 백업 삭제 if [ -d "${MIRROR_CHECK_DIR}" ]; then rm -rf "${MIRROR_CHECK_DIR}" fi # 압축 백업 파일을 월별 디렉토리로 복사 cp -R /data/backup/compress/* "${MIRROR_DIR}" # 원격 FTP 서버로 백업 파일 전송 lftp -c "open -u username,password remote-ftp-server -p 2121; mirror -R /data/backup/mirror /remote/directory" ``` ### 데이터베이스 백업 스크립트 (MySQL/MariaDB) ```bash #!/bin/bash set -o errexit set -o nounset set -o pipefail # 데이터베이스 접속 정보 DB_USER="dbuser" DB_PASS="dbpassword" DB_NAME="dbname" BACKUP_DIR="/data/backup/database" BACKUP_FILE="${BACKUP_DIR}/mysql-$(date +%Y%m%d).sql.gz" # 백업 디렉토리 생성 mkdir -p "${BACKUP_DIR}" # MySQL 데이터베이스 백업 mysqldump -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" | gzip > "${BACKUP_FILE}" # 30일 이상 지난 백업 파일 삭제 find "${BACKUP_DIR}" -name "mysql-*.sql.gz" -type f -mtime +30 -delete ``` ## 결론 서버 환경에서 데이터 백업은 시스템의 안정성과 지속성을 보장하는 중요한 작업입니다. 이 가이드에서 제공하는 방법과 스크립트를 활용하여 체계적인 백업 시스템을 구축하고, 정기적인 테스트를 통해 복원 과정이 원활하게 작동하는지 확인하세요. 효율적인 백업 시스템을 위한 핵심 원칙: - 자동화된 백업 스크립트 구현 - 주기적인 백업 수행 (일간, 주간, 월간) - 다중 백업 위치 활용 (로컬 및 원격) - 백업 로테이션 시스템 도입 (오래된 백업 자동 삭제) - 데이터 복원 테스트 정기적 수행 중요한 데이터는 항상 여러 위치에 분산 저장하고, 백업 프로세스를 자동화하여 인적 오류를 최소화하는 것을 권장합니다.