Post

Docker에서 실행 중인 DB 백업 + 메일링 설정하기

Database 백업

  • 10일동안 진행했던 해커톤 포텐데이 의 프로젝트 문덕을 디벨롭하면서, 애플 앱스토어를 통해 실제로 유저들에게 서비스를 제공하기로 했다.
  • 100% 완벽한 안정성을 가진 서비스는 없으므로, 백업과 복구할 수 있는 수단을 미리 준비해야 한다.
  • 가장 편하고 간단한 방법은 클라우드 서비스의 RDS 서비스를 이용하는 것이다.
  • 하지만 이러한 서비스는 비싸다.
    • DB 요금 : 월 180,000원 db
    • 서버 요금 : 월 88,000원 server
  • NCP의 크레딧으로 무료로 서비스를 이용하고 있지만 최대한 가성비 좋게, 서비스를 오래 유지하려면 최소 스펙으로 운영해야 한다.
  • 그래서 서버 한 대만으로 충분히 DB까지 사용할 수 있다고 판단하여 서버 인스턴스 하나에 애플리케이션, DB, Redis까지 운용하기로 했다.

    AWS의 프리티어 인스턴스 t2.micro 보다도 스펙이 훨씬 좋다.


백업 스크립트 작성

  • 도커로 DB 컨테이너를 띄워도 충분히 백업할 수 있다.
  • docker exec -t <컨테이너 이름> 은 해당 컨테이너 내부에서 명령어를 실행할 수 있게 해준다.
  • 사용중인 Postgres에서 pg_dump 는 DB의 데이터를 SQL 형식으로 백업시켜주는 명령어다.
  • 위의 두 명령어를 통해서 백업 스크립트를 작성할 수 있다.


[백업 파일 저장 경로 설정]

1
2
3
4
5
6
7
8
#!/bin/bash

BACKUP_DIR="/root/backup/postgres_backups/"
FILE_NAME="${BACKUP_DIR}$(date +%y%m%d-%H%M%S).sql"

docker exec -t [컨테이너이름] pg_dump -U [DB User 이름] [DB 이름] > "$FILE_NAME"

echo "Backup Proccessed at $(date)" >> /root/backup/script/postgres_backup.sh.log
  • 백업을 하면 당연히 백업 파일을 저장할 경로 설정이 필요하다.
  • ~ 홈 디렉토리 경로는 사용자에 따라 경로가 바뀔 수 있으므로 사용을 자제하자.
    • ex. 사용자 root일 때 ~ : /root
    • ex. 사용자 ubuntu일 때 ~ : /ubuntu
  • 파일 이름은 저장 경로와 현재 날짜를 기록하도록 설정한다.
    • 이 방식이 파일 이름도 겹치지 않고, 가장 구분하기 쉽다. backup
  • 명령 실행에 성공했을 때, 로그에도 기록해주면 한눈에 백업 기록을 볼 수 있을 것이다. backuplog


[crontab으로 백업 스케쥴러 설정하기]

  • 일일이 백업을 수동으로 하는 것은 굉장히 귀찮은 일이 될 것이다.
  • 그래서 Linux에 기본으로 깔려있는 crontab 을 통해 스케쥴러 설정을 한다.
  • crontab -e 를 통해 설정 파일을 열고 다음 명령어를 넣는다.
1
0 0 * * * sh /root/backup/postgres_backup.sh >> /root/backup/script/postgres_backup.sh.log 2>&1
  • 2>는 표준 오류 출력, &1은 표준 출력으로 리다이렉션 한다는 뜻이다.
  • 즉, 스케쥴러 실행에서의 모든 출력을 오른쪽 경로의 파일에 이어쓴다.(>>)
  • 이렇게 crontab 실행 결과에 대한 오류가 발생했을 때에도 로그에 기록이 된다.

    스크립트 내부에 성공 시 저장되는 로그는 스크립트의 일부로 처리되어 crontab 자체의 출력과는 별도로 기록된다.


백업 파일 이메일 전송

  • 이렇게 컨테이너로 작동하는 DB 파일을 호스트 내부에다 백업을 수행하지만, 클라우드인 호스트 시스템도 100% 안전하다고 믿을 수 있는가?
  • 클라우드 서비스의 오류로 서버가 다운될 가능성도 없지는 않으니, 내 메일로 전달하여 이중 백업을 설정해보겠다.


[패키지 설치]

  • 우리는 postfix 라이브러리와 Google SMTP를 사용하여 메일을 전송할 것이다.
1
2
3
sudo apt-get install mailutils \
libsasl2-2 libsasl2-modules \
postfix ca-certificates coreutils 


[구글 앱 비밀번호 생성]

  • 구글 SMTP를 사용하려면 앱 비밀번호가 필요하다.
  • 앱 비밀번호 생성은 여기 를 참고하자.


[postfix 설정]

  • Mail Transfer Agent인 postfix 설정을 진행한다.


디렉토리 이동 및 설정 파일 백업

1
2
3
cd /etc/postfix

cp -rp main.cf main.cf.ori


main.cf 파일에 아래 코드 추가

1
2
3
4
smtp_use_tls = yes
smtp_sasl_auth_enable = yes
smtp_sasl_security_options = noanonymous
smtp_sasl_password_maps = hash:/etc/postfix/gmail_passwd


패스워드 파일 생성(gmail_passwd) 후 내용 추가

1
2
3
sudo vi /etc/postfix/gmail_passwd

[smtp.gmail.com]:587 구글이메일@gmail.com:앱비밀번호


권한 변경 및 테이블 DB 생성

1
2
3
sudo chmod 400 /etc/postfix/gmail_passwd

sudo postmap /etc/postfix/gmail_passwd


postfix 서비스 재시작

1
sudo systemctl restart postfix


메일 발송 테스트

1
2
3
echo "메일 테스트, hostname : $(hostname)" \
 | mailx -s "Subject : Email Test" \
계정@수신자메일서비스.com


만약 메일이 도착안되었다면 로그 확인

1
/var/log/mail.log


[백업 파일 전송 테스트]

  • 메일 서비스가 작동되는 것을 확인했다면, 백업 파일도 잘 보내지는지 확인해보자.
  • 1.백업 파일이 있는곳에서, 2. 가장 최신 파일을 찾고, 3. 메일을 보낸다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash

BACKUP_DIR="/root/backup/postgres_backups/"

# 가장 최신 파일 찾기
LATEST_FILE=$(ls -t ${BACKUP_DIR}*.sql | head -1)

# 메일로 보내기
if [ -n "$LATEST_FILE" ]; then
    echo "전송 대상 파일: $LATEST_FILE"
    mail -s "백업 파일" -A "$LATEST_FILE" [전송 대상 이메일] < /dev/null
else
    echo "오류 - 파일 없음"
fi
  • 여기서 < /dev/null 은 표준 입력을 비워두는 것이다.
  • 이 명령어를 통해 mail 이 추가적인 입력을 요구하지 않도록 설정한다.

    이 명령어를 사용하지 않으면 body 내용 미입력으로 인해 메일이 발송되지 않는다.


[스케쥴러 설정]

  • 파일까지 정상적으로 보내지는 것을 확인했다면, 메일 발송도 자동화할 차례이다.
  • 마찬가지로 crontab -e로 아래 명령어를 추가하자.
1
5 0 1,15 * * sh /root/backup/mail_backup.sh >> /root/backup/script/mail_backup.sh.log 2>&1
  • 메일을 매달 1일, 15일 0시 5분에 보내도록 설정한다.
  • 백업 스케쥴러가 이미 0시 0분에 설정되어 있으므로, 백업 로직이 실행된 후 메일 로직이 실행되도록 5분에 설정했다.


백업 설정 완료

  • 이제 매일 DB의 데이터가 서버 인스턴스에 저장될 것이고, 2주마다 1번씩 내 메일로 전달된다. mail
  • 지구 종말이 오지 않는 이상, DB에 문제가 생기더라도 백업된 파일로 복구할 수 있게 된다.
This post is licensed under CC BY 4.0 by the author.