How to Back Up and Restore BookStack

머리말
BookStack은 개인이나 팀이 문서를 체계적으로 관리할 수 있는 훌륭한 위키 시스템입니다. 하지만 소중한 문서들이 담긴 BookStack을 안전하게 지키려면 정기적인 백업이 필수입니다. 마치 중요한 일기장을 복사해서 안전한 곳에 보관하는 것처럼 말이죠.
도커(Docker)로 BookStack을 운영하고 있다면, 백업과 복원 과정이 조금 특별합니다. 일반적인 파일 복사와는 달리 도커 볼륨이라는 특별한 저장소를 다뤄야 하기 때문입니다. 이 글에서는 BookStack의 모든 데이터를 안전하게 백업하고, 문제가 생겼을 때 완벽하게 복원하는 방법을 단계별로 알려드리겠습니다.
백업 준비하기
⚠️ 중요한 주의사항
- 이 작업은 서버에 직접 접근하는 SSH 연결이 필요합니다
- 문서에서 사용된 폴더 경로들은 예시이며, 실제 여러분의 서버 환경에 따라 다를 수 있습니다
- 백업 작업 전에 현재 BookStack이 정상 작동하는지 확인하세요
1단계: 도커 볼륨 확인하기
먼저 서버에 SSH로 접속한 후, 현재 있는 도커 볼륨들을 확인해봅시다.
docker volume ls
실행하면 다음과 같은 결과가 나타납니다 (실제 이름은 여러분의 환경에 따라 다름):
DRIVER VOLUME NAME
local 550a04997fbdaa798b4521f8d921e23b6345599699d20007c9e8f8a85096780c
local agwkgggk40go4gg840c880wk_slink-data
local jssw4kg08co848cc08kowgws_bookstack-data
local jssw4kg08co848cc08kowgws_bookstack-mariadb-data
local coolify-db
...
여기서 중요한 것은 BookStack 관련 두 개의 볼륨입니다:
*_bookstack-data
: BookStack 애플리케이션의 파일들 (업로드한 이미지, 설정 파일 등)*_bookstack-mariadb-data
: 데이터베이스 파일들 (모든 문서 내용, 사용자 정보 등)
💡 팁: 볼륨 이름 앞부분의 긴 문자열은 각 설치마다 다릅니다. 여러분의 볼륨 이름을 정확히 확인하고 메모해두세요!
볼륨이란? 도커에서 데이터를 저장하는 특별한 공간입니다. 일반 폴더와 비슷하지만 도커가 관리하는 안전한 저장소라고 생각하면 됩니다.
2단계: 백업 폴더 준비
백업 파일을 저장할 폴더를 만들고 이동합니다 (경로는 여러분의 환경에 맞게 수정하세요):
# 예시 경로 - 실제로는 여러분의 서버 구조에 맞게 변경하세요
mkdir -p /root/volumes/userdata/bookstack_backup
cd /root/volumes/userdata/bookstack_backup
📁 폴더 경로 참고사항:
/root/volumes/userdata/bookstack_backup
는 예시 경로입니다- 여러분의 서버에서는
/home/사용자명/backup
또는/opt/backups
등 다른 경로를 사용할 수 있습니다 - 백업 파일을 저장할 충분한 공간이 있는 위치를 선택하세요
3단계: 환경 설정 파일 만들기
백업을 더 쉽게 관리하기 위해 .env
파일을 만들어 설정값들을 저장합니다:
# .env 파일 내용 (실제 값들로 변경 필요)
BOOKSTACK_DATA_VOLUME=실제_여러분의_bookstack-data_볼륨명
MARIADB_DATA_VOLUME=실제_여러분의_bookstack-mariadb-data_볼륨명
MARIADB_CONTAINER=실제_여러분의_mariadb_컨테이너명
BOOKSTACK_CONTAINER=실제_여러분의_bookstack_컨테이너명
MYSQL_USER=실제_DB_사용자명
MYSQL_PASSWORD=실제_DB_비밀번호
MYSQL_DATABASE=bookstackapp
BACKUP_DIR=실제_여러분의_백업_폴더_경로
🔧 설정값 찾는 방법:
- 볼륨명:
docker volume ls
명령어로 확인 - 컨테이너명:
docker ps
명령어로 확인 - DB 정보: BookStack 설정 파일이나 docker-compose.yml에서 확인
백업 실행하기
이제 실제 백업을 수행하는 스크립트를 만들어보겠습니다. backup.sh
라는 파일을 만들어주세요:
⚠️ 스크립트 작성 전 확인사항:
.env
파일의 모든 값들이 여러분의 실제 환경에 맞게 설정되었는지 확인- 백업 폴더에 충분한 저장 공간이 있는지 확인
- BookStack과 MariaDB 컨테이너가 정상 실행 중인지 확인
#!/bin/bash
# .env 파일 경로를 실제 경로로 수정하세요
source /실제_여러분의_백업폴더_경로/.env
DATE=$(date +%Y%m%d_%H%M)
echo "BookStack 백업을 시작합니다..."
echo "백업 시각: $DATE"
# BookStack 애플리케이션 데이터 백업
echo "1. BookStack 파일 백업 중..."
docker run --rm \
-v $BOOKSTACK_DATA_VOLUME:/data \
-v $BACKUP_DIR:/backup \
alpine tar czf /backup/bookstack-data_$DATE.tar.gz -C /data .
if [ $? -eq 0 ]; then
echo " ✅ BookStack 파일 백업 성공"
else
echo " ❌ BookStack 파일 백업 실패"
exit 1
fi
# MariaDB 데이터 백업
echo "2. 데이터베이스 파일 백업 중..."
docker run --rm \
-v $MARIADB_DATA_VOLUME:/data \
-v $BACKUP_DIR:/backup \
alpine tar czf /backup/mariadb-data_$DATE.tar.gz -C /data .
if [ $? -eq 0 ]; then
echo " ✅ 데이터베이스 파일 백업 성공"
else
echo " ❌ 데이터베이스 파일 백업 실패"
exit 1
fi
# MariaDB 논리적 덤프 (추가 안전장치)
echo "3. 데이터베이스 덤프 생성 중..."
docker exec $MARIADB_CONTAINER \
sh -c "mariadb-dump --single-transaction -u $MYSQL_USER -p\"$MYSQL_PASSWORD\" $MYSQL_DATABASE" \
> $BACKUP_DIR/${MYSQL_DATABASE}_$DATE.sql
if [ $? -eq 0 ]; then
echo " ✅ 데이터베이스 덤프 생성 성공"
else
echo " ❌ 데이터베이스 덤프 생성 실패"
exit 1
fi
echo ""
echo "🎉 모든 백업이 완료되었습니다!"
echo "백업 완료 시각: $DATE"
echo "생성된 파일들:"
echo "- bookstack-data_$DATE.tar.gz"
echo "- mariadb-data_$DATE.tar.gz"
echo "- ${MYSQL_DATABASE}_$DATE.sql"
echo ""
echo "백업 파일 위치: $BACKUP_DIR"
스크립트에 실행 권한을 부여합니다 (경로를 실제 경로로 변경):
chmod +x /실제_여러분의_백업폴더_경로/backup.sh
백업 명령어 설명
docker run --rm
: 임시 컨테이너를 만들어 작업하고 자동으로 삭제합니다. 마치 일회용 작업대를 만드는 것과 같습니다.
-v 볼륨이름:/data
: 도커 볼륨을 컨테이너 안의 /data
폴더에 연결합니다. 이렇게 해야 볼륨 안의 파일들에 접근할 수 있습니다.
alpine tar czf
: 가벼운 Alpine Linux를 사용해서 파일들을 압축합니다. tar czf
는 파일들을 하나의 압축파일로 만드는 명령어입니다.
자동 백업과 텔레그램 알림 설정하기
매번 수동으로 백업하는 것은 번거롭고 깜빡할 수도 있습니다. 이제 자동으로 백업하고 결과를 텔레그램으로 알려주는 시스템을 만들어보겠습니다!
1단계: 텔레그램 봇 만들기
먼저 텔레그램에서 알림을 받기 위한 봇을 만들어야 합니다.
- 텔레그램에서
@BotFather
를 검색하고 대화를 시작하세요 /newbot
명령어를 입력하세요- 봇의 이름을 정하세요 (예: "BookStack 백업 알리미")
- 봇의 사용자명을 정하세요 (예: "bookstack_backup_bot")
- BotFather가 주는 토큰을 복사해서 안전한 곳에 저장하세요
🔑 챗 ID 찾기:
- 만든 봇과 대화를 시작하고 아무 메시지나 보내세요
- 웹브라우저에서 다음 주소로 이동하세요:
https://api.telegram.org/bot여러분의봇토큰/getUpdates
- 결과에서
"chat":{"id":숫자}
부분의 숫자가 챗 ID입니다
2단계: 개선된 백업 스크립트 만들기
텔레그램 알림 기능이 포함된 새로운 백업 스크립트를 만들어보겠습니다:
#!/bin/bash
# .env 파일 경로를 실제 경로로 수정하세요
source /실제_여러분의_백업폴더_경로/.env
# 텔레그램 설정 (실제 값으로 변경하세요)
TELEGRAM_BOT_TOKEN="여러분의_텔레그램_봇_토큰"
TELEGRAM_CHAT_ID="여러분의_챗_ID"
# 텔레그램 메시지 전송 함수
send_telegram_message() {
local message="$1"
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
-d chat_id="${TELEGRAM_CHAT_ID}" \
-d text="${message}" \
-d parse_mode="HTML" > /dev/null
}
DATE=$(date +%Y%m%d_%H%M)
START_TIME=$(date)
BACKUP_SUCCESS=true
ERROR_MESSAGES=""
echo "BookStack 백업을 시작합니다..."
echo "백업 시각: $DATE"
# 텔레그램으로 시작 알림
send_telegram_message "📦 <b>BookStack 백업 시작</b>
🕐 시작 시간: $START_TIME
📍 서버: $(hostname)"
# BookStack 애플리케이션 데이터 백업
echo "1. BookStack 파일 백업 중..."
docker run --rm \
-v $BOOKSTACK_DATA_VOLUME:/data \
-v $BACKUP_DIR:/backup \
alpine tar czf /backup/bookstack-data_$DATE.tar.gz -C /data .
if [ $? -eq 0 ]; then
echo " ✅ BookStack 파일 백업 성공"
APP_SIZE=$(du -h $BACKUP_DIR/bookstack-data_$DATE.tar.gz | cut -f1)
else
echo " ❌ BookStack 파일 백업 실패"
BACKUP_SUCCESS=false
ERROR_MESSAGES="$ERROR_MESSAGES\n❌ BookStack 파일 백업 실패"
fi
# MariaDB 데이터 백업
echo "2. 데이터베이스 파일 백업 중..."
docker run --rm \
-v $MARIADB_DATA_VOLUME:/data \
-v $BACKUP_DIR:/backup \
alpine tar czf /backup/mariadb-data_$DATE.tar.gz -C /data .
if [ $? -eq 0 ]; then
echo " ✅ 데이터베이스 파일 백업 성공"
DB_SIZE=$(du -h $BACKUP_DIR/mariadb-data_$DATE.tar.gz | cut -f1)
else
echo " ❌ 데이터베이스 파일 백업 실패"
BACKUP_SUCCESS=false
ERROR_MESSAGES="$ERROR_MESSAGES\n❌ 데이터베이스 파일 백업 실패"
fi
# MariaDB 논리적 덤프
echo "3. 데이터베이스 덤프 생성 중..."
docker exec $MARIADB_CONTAINER \
sh -c "mariadb-dump --single-transaction -u $MYSQL_USER -p\"$MYSQL_PASSWORD\" $MYSQL_DATABASE" \
> $BACKUP_DIR/${MYSQL_DATABASE}_$DATE.sql
if [ $? -eq 0 ]; then
echo " ✅ 데이터베이스 덤프 생성 성공"
SQL_SIZE=$(du -h $BACKUP_DIR/${MYSQL_DATABASE}_$DATE.sql | cut -f1)
else
echo " ❌ 데이터베이스 덤프 생성 실패"
BACKUP_SUCCESS=false
ERROR_MESSAGES="$ERROR_MESSAGES\n❌ 데이터베이스 덤프 생성 실패"
fi
END_TIME=$(date)
# 결과에 따른 텔레그램 알림
if [ "$BACKUP_SUCCESS" = true ]; then
send_telegram_message "✅ <b>BookStack 백업 성공!</b>
🕐 완료 시간: $END_TIME
📁 파일 크기:
• BookStack 데이터: $APP_SIZE
• MariaDB 데이터: $DB_SIZE
• SQL 덤프: $SQL_SIZE
📍 서버: $(hostname)
💾 백업 위치: $BACKUP_DIR"
echo ""
echo "🎉 모든 백업이 완료되었습니다!"
else
send_telegram_message "❌ <b>BookStack 백업 실패!</b>
🕐 실패 시간: $END_TIME
📍 서버: $(hostname)
🚨 오류 내용:$ERROR_MESSAGES
⚠️ 백업 상태를 확인해주세요!"
echo ""
echo "❌ 백업 중 오류가 발생했습니다!"
fi
echo "백업 완료 시각: $DATE"
echo "생성된 파일들:"
echo "- bookstack-data_$DATE.tar.gz"
echo "- mariadb-data_$DATE.tar.gz"
echo "- ${MYSQL_DATABASE}_$DATE.sql"
echo ""
echo "백업 파일 위치: $BACKUP_DIR"
이 스크립트를 backup_with_telegram.sh
로 저장하고 실행 권한을 주세요:
chmod +x /실제_여러분의_백업폴더_경로/backup_with_telegram.sh
3단계: 자동 백업 설정 (crontab)
이제 정기적으로 자동 백업이 실행되도록 설정해보겠습니다.
# crontab 편집
crontab -e
다음 내용을 추가하세요 (경로는 실제 경로로 수정):
# 매일 새벽 2시에 백업 실행
0 2 * * * /실제_여러분의_백업폴더_경로/backup_with_telegram.sh >> /var/log/bookstack_backup.log 2>&1
# 매주 일요일 새벽 3시에 백업 실행하려면:
# 0 3 * * 0 /실제_여러분의_백업폴더_경로/backup_with_telegram.sh >> /var/log/bookstack_backup.log 2>&1
# 매월 1일 새벽 4시에 백업 실행하려면:
# 0 4 1 * * /실제_여러분의_백업폴더_경로/backup_with_telegram.sh >> /var/log/bookstack_backup.log 2>&1
🕐 crontab 시간 설정 설명:
0 2 * * *
: 매일 새벽 2시30 14 * * 1
: 매주 월요일 오후 2시 30분0 0 1 * *
: 매월 1일 자정0 */6 * * *
: 6시간마다
4단계: 오래된 백업 파일 정리하기
백업 파일이 계속 쌓이면 저장 공간이 부족해질 수 있습니다. 오래된 백업 파일을 자동으로 삭제하는 스크립트도 만들어보겠습니다:
#!/bin/bash
# cleanup_old_backups.sh
source /실제_여러분의_백업폴더_경로/.env
# 7일 이상 된 백업 파일 삭제 (일수는 원하는 대로 변경 가능)
DAYS_TO_KEEP=7
echo "오래된 백업 파일 정리 시작..."
echo "$DAYS_TO_KEEP일 이상 된 파일들을 삭제합니다."
# 삭제할 파일들 미리 확인
echo "삭제 예정 파일들:"
find $BACKUP_DIR -name "*.tar.gz" -mtime +$DAYS_TO_KEEP -ls
find $BACKUP_DIR -name "*.sql" -mtime +$DAYS_TO_KEEP -ls
# 실제 삭제 실행
DELETED_COUNT=0
for file in $(find $BACKUP_DIR -name "*.tar.gz" -mtime +$DAYS_TO_KEEP); do
rm "$file"
DELETED_COUNT=$((DELETED_COUNT + 1))
done
for file in $(find $BACKUP_DIR -name "*.sql" -mtime +$DAYS_TO_KEEP); do
rm "$file"
DELETED_COUNT=$((DELETED_COUNT + 1))
done
echo "정리 완료: $DELETED_COUNT개 파일 삭제됨"
# 남은 저장 공간 확인
echo "백업 폴더 용량:"
du -sh $BACKUP_DIR
이 스크립트를 cleanup_old_backups.sh
로 저장하고 실행 권한을 주세요:
chmod +x /실제_여러분의_백업폴더_경로/cleanup_old_backups.sh
이 스크립트도 crontab에 추가할 수 있습니다:
# 매일 새벽 1시에 오래된 백업 파일 정리
0 1 * * * /실제_여러분의_백업폴더_경로/cleanup_old_backups.sh >> /var/log/backup_cleanup.log 2>&1
5단계: 백업 상태 확인
crontab이 제대로 작동하는지 확인하는 방법들:
# crontab 목록 확인
crontab -l
# 백업 로그 확인
tail -f /var/log/bookstack_backup.log
# cron 서비스 상태 확인
systemctl status cron
# 또는 (Ubuntu/Debian의 경우)
systemctl status crond
💡 추가 팁들:
- 텔레그램 봇 토큰과 챗 ID는 절대 다른 사람과 공유하지 마세요
- 백업이 성공했는지 처음 며칠은 텔레그램 메시지를 확인해보세요
- 서버 시간대가 맞는지 확인하세요 (
date
명령어로 확인) - 백업 파일을 다른 서버나 클라우드에도 복사해두면 더 안전합니다
복원하기
⚠️ 복원 작업 전 필수 확인사항
- 복원하려는 백업 파일들이 손상되지 않았는지 확인하세요
- BookStack과 MariaDB 컨테이너를 중지하고 진행하는 것이 안전합니다
- 복원 작업은 기존 데이터를 완전히 삭제하므로 신중하게 진행하세요
- 가능하면 현재 상태도 백업해두세요 (복원 실패 시 원상복구용)
문제가 생겨서 백업을 복원해야 할 때는 다음 단계를 따라주세요.
1단계: BookStack 애플리케이션 복원
# 실제 볼륨명과 백업 파일명으로 변경하세요
docker run --rm \
-v 실제_bookstack_데이터_볼륨명:/data \
-v 실제_백업_폴더_경로:/backup \
alpine sh -c "rm -rf /data/* && tar xzf /backup/bookstack-data_복원할날짜.tar.gz -C /data"
2단계: MariaDB 데이터 복원
# 실제 볼륨명과 백업 파일명으로 변경하세요
docker run --rm \
-v 실제_mariadb_데이터_볼륨명:/data \
-v 실제_백업_폴더_경로:/backup \
alpine sh -c "rm -rf /data/* && tar xzf /backup/mariadb-data_복원할날짜.tar.gz -C /data"
3단계: 데이터베이스 덤프 복원 (추가 안전장치)
BookStack 컨테이너는 중지하고 MariaDB만 실행한 상태에서:
# 실제 컨테이너명과 백업 파일명으로 변경하세요
docker exec -i 실제_mariadb_컨테이너명 \
sh -c "mysql -u 실제_DB_사용자명 -p\"실제_DB_비밀번호\" bookstackapp" \
< 실제_백업_폴더_경로/bookstackapp_복원할날짜.sql
💡 복원 후 확인사항:
- 모든 컨테이너를 다시 시작하세요
- BookStack 웹페이지에 접속해서 정상 작동하는지 확인하세요
- 주요 문서들과 사용자 계정이 정상인지 확인하세요
맺음말
BookStack의 안전한 백업과 복원은 우리의 소중한 문서들을 지키는 가장 확실한 방법입니다. 정기적인 백업을 통해 예상치 못한 서버 문제나 실수로부터 데이터를 보호할 수 있습니다.
이 가이드에서 제시한 방법은 세 가지 백업을 동시에 만듭니다: 애플리케이션 파일, 데이터베이스 파일, 그리고 데이터베이스 덤프. 이는 마치 중요한 문서를 여러 곳에 복사해두는 것과 같아서, 하나가 문제가 생겨도 다른 방법으로 복원할 수 있습니다.
백업은 한 번 설정해두면 자동으로 실행되도록 크론탭(crontab)에 등록할 수도 있습니다. 정기적인 백업으로 BookStack을 안전하게 운영하시길 바랍니다!
중요한 안전 수칙들:
- 새로운 서버로 이전할 때는 도커 컨테이너 이름이나 볼륨 이름이 달라집니다.
.env
파일의 설정값들을 새 환경에 맞게 반드시 수정하세요 - SSH 접속과 도커 명령어 사용은 서버 관리자 권한이 필요합니다
- 백업 작업 중에는 BookStack 사용을 가급적 피해주세요
- 정기 백업을 자동화하려면 크론탭(crontab)을 활용해보세요
- 백업 파일은 여러 곳에 분산 저장하는 것이 더 안전합니다
문서에서 사용된 경로와 이름들은 모두 예시입니다. 실제 여러분의 서버 환경에 맞게 수정해서 사용하세요!