TeslaMate는 DB로 PostgreSQL을 사용합니다.
DB를 잘 백업하면, 다른 머신으로 이동시에도 동일하게 데이터를 볼 수 있습니다.
백업 명령어 한줄이면 끝나기는 하지만, 자동화하는게 또 엔지니어의 본문이기에 ..ㅎㅎ
Teslamate에서 사용되는 PostgreSQL 데이터베이스의 백업을 원하는 시간에 자동으로 백업받고, Gmail을 통해 원하는 메일로 전송하는 스크립트 입니다.

자동백업스크립트 동작 구성도 입니다.
- 사용방법
본 문서에 첨부된 쉘스크립트 파일을 다운 받아 업로드 하거나, 아래 소스코드를 복사하여 테슬라메이트가 설치된 서버에 접속하여 파일을 붙여넣기 합니다.
실행은 “bash 스크립트명.sh “ 와 같이 할 수 있습니다.

먼저 메일을 보낼 수 있게 해주는 패키지인 msmtp, mutt 가 시스템에 있는지 확인하고 없으면 설치합니다.

이후 docker 컨테이너를 검색하여 보여줍니다.
기본적으로 컨테이너 이름에 database가 포함된다면 추천으로 보여주며, 개별 설정했다면 해당 컨테이너 이름을 넣어주면 됩니다.
기본적으로 컨테이너 이름에 database가 포함된다면 추천으로 보여주며, 개별 설정했다면 해당 컨테이너 이름을 넣어주면 됩니다.
기본으로 설치했다면, 그냥 엔터를 쳐서 진행이 가능합니다.
이 후 과정은 다음과 같습니다.
DB 사용자 비밀번호
백업파일을 보낼 Gmail주소
백업파일을 받을 메일주소
백업파일을 보낼 Gmail주소
백업파일을 받을 메일주소

Gmail 을 웹이 아닌 다른데에서 접속시에는 별도의 비밀번호가 필요합니다.
구글 계정으로 이동 : https://myaccount.google.com/security
상단 검색창에 “앱 비밀번호" 입력

앱 비밀번호 리스트가 보입니다.
나중에 어떤 것인지 찾을 수 있게 이름을 정하고 만들기를 클릭합니다.

앱 비밀번호가 생성되었고, 해당 비밀번호는 첫화면에서만 볼 수 있으므로, 복사하여 비밀번호에 넣어줍니다.
(gmail로그인 비밀번호로 입력하면 안됩니다.)
해당 정보를 바탕으로 mail을 발송할 msmtp 파일을 생성합니다.
이제 주기적으로 보낼 수 있도록 백업 스크립트를 실행할 crontab 작성이 실행됩니다.
선택은 다음과 같습니다.
매일/매주/매월
시/분 설정
완료되면 실행할 스크립트가 생성되며, crontab에 자동으로 등록됩니다.

“crontab -l” 명령을 통해 일정이 제대로 등록되었는지 확인해봅니다.

바로 테스트를 해보기 위해서는 스크립트 마지막에 생성된 백업 스크립트 파일을 직접 실행하면 됩니다.
정상적으로 실행되면, “script finished.” 메시지로 마무리 됩니다.
백업파일은 메일로 발송되면 삭제하도록 했습니다.
만약 시스템에도 남기고싶다면, 삭제 부분을 조정하시면 됩니다.

최종적으로 위와 같이 백업파일이 메일로 발송됩니다.
소스코드 다운
- 소스코드
#!/bin/bash
# 도커 PostgreSQL 백업 및 Gmail 전송 환경 설정 자동화 스크립트
# ===============================================================
# 1. 필수 패키지 및 Docker 상태 확인
# ===============================================================
echo "필수 패키지 설치를 시작합니다 (msmtp, mutt)..."
if command -v apt &> /dev/null; then
sudo apt update
sudo apt install -y msmtp mutt
elif command -v yum &> /dev/null; then
sudo yum install -y epel-release
sudo yum yum -y msmtp mutt
else
echo "지원되지 않는 패키지 관리자입니다. msmtp, mutt를 수동으로 설치하세요."
exit 1
fi
if ! command -v docker &> /dev/null; then
echo "'docker' 명령어를 찾을 수 없습니다. 도커가 설치되어 있는지 확인하세요."
exit 1
fi
echo "필수 패키지 설치 완료."
# ===============================================================
# 2. Docker 컨테이너 이름 자동 추천 및 입력
# ===============================================================
echo "--- Docker 컨테이너 확인 ---"
# 'postgres' 또는 'database'를 포함하는 실행 중인 컨테이너 이름 목록 추출
RECOMMENDED_CONTAINER=$(docker ps --format "{{.Names}}" | grep -E 'postgres|database|db|pgsql' | head -n 1)
if [ -n "$RECOMMENDED_CONTAINER" ]; then
echo "추천 컨테이너 이름: [$RECOMMENDED_CONTAINER]"
read -p "PostgreSQL 도커 컨테이너 이름 (추천값으로 Enter): " PG_CONTAINER_NAME
PG_CONTAINER_NAME=${PG_CONTAINER_NAME:-$RECOMMENDED_CONTAINER}
else
echo "PostgreSQL 또는 Database 컨테이너를 찾을 수 없습니다."
read -p "PostgreSQL 도커 컨테이너 이름을 수동으로 입력하세요: " PG_CONTAINER_NAME
fi
# 변수 확인 및 설정
CURRENT_USER_HOME="$HOME"
BACKUP_DIR="${CURRENT_USER_HOME}/dbbackup"
DEFAULT_DB_NAME="teslamate"
echo "--- DB 접속 및 기타 설정 ---"
read -p "PostgreSQL 사용자 이름 (기본값: $DEFAULT_DB_NAME): " PG_USER_INPUT
PG_USER=${PG_USER_INPUT:-$DEFAULT_DB_NAME}
read -p "백업할 데이터베이스 이름 (기본값: $DEFAULT_DB_NAME): " PG_DB_INPUT
PG_DB=${PG_DB_INPUT:-$DEFAULT_DB_NAME}
echo "DB 비밀번호는 보안상 스크립트에 직접 저장됩니다. 주의하십시오."
read -s -p "PostgreSQL 사용자 비밀번호: " PG_PASSWORD
echo
echo "--- Gmail 및 이메일 설정 ---"
read -p "백업 파일을 보낼 Gmail 주소 (발신자): " SENDER_GMAIL
read -p "백업 알림을 받을 수신자 이메일 주소: " RECIPIENT_EMAIL
echo "Gmail 앱 비밀번호를 입력해주세요. (화면에 표시되지 않습니다): "
read -s APP_PASSWORD
echo
# ===============================================================
# 3. msmtp 설정
# ===============================================================
MSMTP_CONF="${CURRENT_USER_HOME}/.msmtprc"
echo "msmtp 설정 파일 ($MSMTP_CONF)을 생성합니다."
cat <<EOF > "$MSMTP_CONF"
# msmtp 설정 파일
account default
host smtp.gmail.com
port 587
auth on
tls on
tls_starttls on
user $SENDER_GMAIL
password $APP_PASSWORD
from $SENDER_GMAIL
logfile ${CURRENT_USER_HOME}/.msmtp.log
EOF
chmod 600 "$MSMTP_CONF"
echo "msmtp 설정 완료."
# ===============================================================
# 4. 스케줄 선택 및 Cron Job 설정
# ===============================================================
echo "--- 백업 스케줄 설정 ---"
echo "백업 주기를 선택하세요:"
echo " 1) 매일 (Daily)"
echo " 2) 매주 (Weekly, 일요일)"
echo " 3) 매월 (Monthly, 1일)"
read -p "선택 (1, 2, 3): " SCHEDULE_CHOICE
read -p "백업을 실행할 시간 (0-23): " SCHEDULE_HOUR
read -p "백업을 실행할 분 (0-59): " SCHEDULE_MINUTE
case "$SCHEDULE_CHOICE" in
1) CRON_SCHEDULE="$SCHEDULE_MINUTE $SCHEDULE_HOUR * * *" ; DESCRIPTION="매일 $SCHEDULE_HOUR시 $SCHEDULE_MINUTE분";;
2) CRON_SCHEDULE="$SCHEDULE_MINUTE $SCHEDULE_HOUR * * 0" ; DESCRIPTION="매주 일요일 $SCHEDULE_HOUR시 $SCHEDULE_MINUTE분";;
3) CRON_SCHEDULE="$SCHEDULE_MINUTE $SCHEDULE_HOUR 1 * *" ; DESCRIPTION="매월 1일 $SCHEDULE_HOUR시 $SCHEDULE_MINUTE분";;
*) echo "잘못된 선택입니다. 매일 $SCHEDULE_HOUR시 $SCHEDULE_MINUTE분에 설정합니다." ; CRON_SCHEDULE="$SCHEDULE_MINUTE $SCHEDULE_HOUR * * *";;
esac
# ===============================================================
# 5. 백업 실행 스크립트 생성 및 Cron 등록
# ===============================================================
EXEC_SCRIPT_PATH="${CURRENT_USER_HOME}/daily_postgres_docker_backup.sh"
mkdir -p "$BACKUP_DIR"
echo "백업 실행 스크립트 ($EXEC_SCRIPT_PATH)를 생성합니다."
# 백업 스크립트 내용 생성 (아래 2단계 스크립트 내용 삽입)
cat <<EOF > "$EXEC_SCRIPT_PATH"
$(cat <<- 'EOF_SCRIPT'
#!/bin/bash
# ===============================================================
# 1. 사용자 환경 변수 (설정 스크립트에서 자동 입력됨)
# ===============================================================
PG_CONTAINER_NAME="PLACEHOLDER_PG_CONTAINER_NAME"
PG_USER="PLACEHOLDER_PG_USER"
PG_DB="PLACEHOLDER_PG_DB"
PG_PASSWORD="PLACEHOLDER_PG_PASSWORD"
RECIPIENT_EMAIL="PLACEHOLDER_RECIPIENT_EMAIL"
SENDER_GMAIL="PLACEHOLDER_SENDER_GMAIL"
CURRENT_USER_HOME="PLACEHOLDER_CURRENT_USER_HOME"
BACKUP_DIR="PLACEHOLDER_BACKUP_DIR"
MSMTP_CONF="PLACEHOLDER_MSMTP_CONF"
# ===============================================================
# 2. 실행 변수
# ===============================================================
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${PG_DB}_${TIMESTAMP}.sql.gz"
FULL_HOST_PATH="${BACKUP_DIR}/${BACKUP_FILE}"
LOG_FILE="${BACKUP_DIR}/${PG_DB}_backup.log"
# ===============================================================
# 3. 백업 및 전송 로직
# ===============================================================
# 로그 시작 (콘솔과 로그 파일에 동시 기록)
echo "========================================================" | tee -a "$LOG_FILE"
echo "[$(date)] Starting Docker backup for ${PG_DB}..." | tee -a "$LOG_FILE"
echo "[$(date)] Target Container: ${PG_CONTAINER_NAME}" | tee -a "$LOG_FILE"
# 1. 도커 컨테이너 내부에서 pg_dump 실행 및 호스트로 파이프/압축
# --user postgres 옵션을 사용하여 권한 문제(role "root" does not exist)를 해결합니다.
echo "[$(date)] Running pg_dump inside container as user 'postgres'..." | tee -a "$LOG_FILE"
docker exec --user postgres -e PGPASSWORD="$PG_PASSWORD" "$PG_CONTAINER_NAME" \
pg_dump -U "$PG_USER" -d "$PG_DB" -F p | gzip > "$FULL_HOST_PATH" 2>> "$LOG_FILE"
DUMP_STATUS=$?
if [ $DUMP_STATUS -ne 0 ]; then
ERROR_SUB="PostgreSQL Docker Backup FAILED - ${PG_DB}"
echo "[$(date)] ERROR: Backup failed (docker exec status: $DUMP_STATUS). Check DB credentials or container status." | tee -a "$LOG_FILE"
ERROR_BODY="ERROR: 백업에 실패했습니다. (STATUS: $DUMP_STATUS) 로그 파일 확인: $LOG_FILE"
# 실패 알림 메일 전송
echo "$ERROR_BODY" | mutt -e "set sendmail=\"/usr/bin/msmtp -C $MSMTP_CONF\"" -s "$ERROR_SUB" -- "$RECIPIENT_EMAIL"
echo "Backup FAILED. Notification sent." | tee -a "$LOG_FILE"
# 빈 파일이 생성되었을 경우 삭제
if [ -f "$FULL_HOST_PATH" ] && [ ! -s "$FULL_HOST_PATH" ]; then
rm -f "$FULL_HOST_PATH"
echo "[$(date)] Empty backup file deleted." >> "$LOG_FILE"
fi
exit 1
fi
echo "[$(date)] Backup successful: $FULL_HOST_PATH" | tee -a "$LOG_FILE"
# 2. mutt를 사용하여 이메일 전송
SUBJECT="PostgreSQL Docker Backup SUCCESS - ${PG_DB} (${TIMESTAMP})"
FILE_SIZE=$(du -h "$FULL_HOST_PATH" | awk '{print $1}')
BODY="데이터베이스 '${PG_DB}'의 백업이 완료되어 첨부됩니다.\n파일 크기: $FILE_SIZE"
echo "[$(date)] Sending email with attachment ($FILE_SIZE)..." | tee -a "$LOG_FILE"
echo -e "$BODY" | mutt -e "set sendmail=\"/usr/bin/msmtp -C $MSMTP_CONF\"" \
-s "$SUBJECT" -a "$FULL_HOST_PATH" -- "$RECIPIENT_EMAIL"
MAIL_STATUS=$?
if [ $MAIL_STATUS -ne 0 ]; then
echo "[$(date)] ERROR: Email sending failed (mutt status: $MAIL_STATUS). Check ~/.msmtp.log" | tee -a "$LOG_FILE"
else
echo "[$(date)] Email sent successfully to $RECIPIENT_EMAIL." | tee -a "$LOG_FILE"
fi
# 3. 백업 파일 정리 (메일 전송 성공 시에만 삭제)
if [ $MAIL_STATUS -eq 0 ]; then
rm -f "$FULL_HOST_PATH"
echo "[$(date)] Host backup file deleted." | tee -a "$LOG_FILE"
else
echo "[$(date)] Email failed, keeping host backup file for inspection: $FULL_HOST_PATH" | tee -a "$LOG_FILE"
fi
echo "[$(date)] Script finished." | tee -a "$LOG_FILE"
EOF_SCRIPT
)
EOF
# 스크립트 내용에 실제 입력 값 채워넣기 (sed를 사용하여 변수 치환)
sed -i "s|PLACEHOLDER_PG_CONTAINER_NAME|$PG_CONTAINER_NAME|g" "$EXEC_SCRIPT_PATH"
sed -i "s|PLACEHOLDER_PG_USER|$PG_USER|g" "$EXEC_SCRIPT_PATH"
sed -i "s|PLACEHOLDER_PG_DB|$PG_DB|g" "$EXEC_SCRIPT_PATH"
sed -i "s|PLACEHOLDER_PG_PASSWORD|$PG_PASSWORD|g" "$EXEC_SCRIPT_PATH"
sed -i "s|PLACEHOLDER_RECIPIENT_EMAIL|$RECIPIENT_EMAIL|g" "$EXEC_SCRIPT_PATH"
sed -i "s|PLACEHOLDER_SENDER_GMAIL|$SENDER_GMAIL|g" "$EXEC_SCRIPT_PATH"
sed -i "s|PLACEHOLDER_CURRENT_USER_HOME|$CURRENT_USER_HOME|g" "$EXEC_SCRIPT_PATH"
sed -i "s|PLACEHOLDER_BACKUP_DIR|$BACKUP_DIR|g" "$EXEC_SCRIPT_PATH"
sed -i "s|PLACEHOLDER_MSMTP_CONF|$MSMTP_CONF|g" "$EXEC_SCRIPT_PATH"
chmod +x "$EXEC_SCRIPT_PATH"
# Cron Job 등록 (기존 항목 제거 후 새로 등록)
(crontab -l 2>/dev/null | grep -v "$EXEC_SCRIPT_PATH"; echo "$CRON_SCHEDULE $EXEC_SCRIPT_PATH") | crontab -
echo "백업 실행 스크립트 생성 완료: $EXEC_SCRIPT_PATH"
echo "Cron Job 등록 완료: $DESCRIPTION ($CRON_SCHEDULE)"
echo "=========================================================="
echo "설정 완료. 이제 테스트를 진행 후 사용하세요."
echo "백업 파일 및 로그 경로: $BACKUP_DIR"
echo "# 문의사항이나 개선사항은 linux1547@hanmail.net을 통해 연락 주세요. "
echo " 제작자 : 최성기 ( https://seonggi.kr ) "
echo "=========================================================="
'달빛궁전 > 테슬라(차량)' 카테고리의 다른 글
| TeslaMate (테슬라메이트) 설치 방안 (0) | 2025.10.20 |
|---|---|
| 테슬라 Y를 구매하게된 이야기 - 시작 (0) | 2025.10.03 |