:::๊ฒฝ๊ณ ์ด ํํ ๋ฆฌ์ผ์ ์ปค๋ฎค๋ํฐ ๊ธฐ์ฌ๋ก ์ ์๋์์ผ๋ฉฐ Open WebUI ํ์์ ์ง์ํ์ง ์์ต๋๋ค. ์ด๋ ํน์ ์ฌ์ฉ ์ฌ๋ก์ ๋ง์ถฐ Open WebUI๋ฅผ ์ฌ์ฉ์ ์ ์ํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ฃผ๋ ๋ฐ์๋ง ๋ชฉ์ ์ด ์์ต๋๋ค. ๊ธฐ์ฌํ๊ณ ์ถ์ผ์ ๊ฐ์? ๊ธฐ์ฌ ํํ ๋ฆฌ์ผ์ ํ์ธํ์ธ์. :::
์ธ์คํด์ค๋ฅผ ๋ฐฑ์ ํ๊ธฐ
์๋ฌด๋ ๋ฐ์ดํฐ๋ฅผ ์๊ณ ์ถ์ดํ์ง ์์ต๋๋ค!
Open WebUI๋ฅผ ์๊ฐ ํธ์คํ ํ๋ ๊ฒฝ์ฐ๋ผ๋ฉด, ๊ตฌ์ฑ ์์ ์ผ๋ถ๋ฅผ ๋ณด์กดํ๊ธฐ ์ํด ์ ์ ๋ฐฑ์ ๊ณํ์ ์ํํ๊ณ ์ถ์ ์ ์์ต๋๋ค.
์ด ๊ฐ์ด๋๋ ์ฌ์ฉ์๊ฐ ์ด๋ฅผ ์ํํ๋ ๊ธฐ๋ณธ ๊ถ์ฅ ์ฌํญ์ ์ ๊ณตํ๋ ค๋ ์๋๋ก ์์ฑ๋์์ต๋๋ค.
์ด ๊ฐ์ด๋๋ ์ฌ์ฉ์๊ฐ Docker๋ฅผ ํตํด Open WebUI๋ฅผ ์ค์นํ๊ฑฐ๋ ์ค์นํ ์๋๊ฐ ์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
๋ฐ์ดํฐ ์ง์์ฑ ํ๋ณดโ
๋จผ์ Docker๋ฅผ ์ฌ์ฉํด ์คํ์ ๋ฐฐํฌํ๊ธฐ ์ ์, Docker Compose๊ฐ ์ง์ ๊ฐ๋ฅํ ๋ฐ์ดํฐ ์คํ ์ด๋ฅผ ์ฌ์ฉํ๋์ง ํ์ธํ์ธ์. Docker Compose Github ์ ์ฅ์์์ ์ ๊ณต๋ ๊ตฌ์ฑ ํ์ผ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์ด๋ฏธ ์ด๋ฌํ ์์ ์ด ์ฒ๋ฆฌ๋์ด ์์ต๋๋ค. ํ์ง๋ง ์ฌ์ฉ์๊ฐ ๊ฐ๋ณ์ ์ผ๋ก ๋ณํํ์ฌ ์ด ๋ถ๋ถ์ ํ์ธํ๋ ๊ฒ์ ์๊ธฐ ์ฌ์ด ์ ์ ์ ์ํ์ธ์.
Docker ์ปจํ ์ด๋๋ ์ผ์์ ์ด๋ฉฐ ๋ฐ์ดํฐ๋ ํธ์คํธ ํ์ผ ์์คํ ์์ ์์กดํ๊ธฐ ์ํด ์ง์์ ์ผ๋ก ์ ์ง๋์ด์ผ ํฉ๋๋ค.
Docker ๋ณผ๋ฅจ ์ฌ์ฉโ
ํ๋ก์ ํธ ์ ์ฅ์์์ ์ ๊ณต๋ Docker Compose๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ Open Web UI๋ฅผ Docker ๋ณผ๋ฅจ์ ์ฌ์ฉํด ๋ฐฐํฌํ๊ฒ ๋ฉ๋๋ค.
Ollama ๋ฐ Open WebUI์ ์ค์น ๊ฒฝ๋ก๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
ollama:
volumes:
- ollama:/root/.ollama
open-webui:
volumes:
- open-webui:/app/backend/data
ํธ์คํธ์์ ์ค์ ๊ฒฝ๋ก๋ฅผ ์ฐพ์ผ๋ ค๋ฉด ๋ค์์ ์คํํ์ธ์:
docker volume inspect ollama
๊ทธ๋ฆฌ๊ณ
docker volume inspect open-webui
ํธ์คํธ ์ง์ ๋ฐ์ธ๋ ์ฌ์ฉโ
์ผ๋ถ ์ฌ์ฉ์๋ Open Web UI๋ฅผ ํธ์คํธ ํ์ผ ์์คํ ์ ์ง์ (๊ณ ์ ๋) ๋ฐ์ธ๋๋ก ๋ฐฐํฌํฉ๋๋ค, ์๋์ ๊ฐ์ต๋๋ค:
services:
ollama:
container_name: ollama
image: ollama/ollama:${OLLAMA_DOCKER_TAG-latest}
volumes:
- /opt/ollama:/root/.ollama
open-webui:
container_name: open-webui
image: ghcr.io/open-webui/open-webui:${WEBUI_DOCKER_TAG-main}
volumes:
- /opt/open-webui:/app/backend/data
์ด ๋ฐฉ์์ผ๋ก ์ธ์คํด์ค๋ฅผ ๋ฐฐํฌํ๋ค๋ฉด, ๋ฃจํธ ๊ฒฝ๋ก๋ค์ ๊ธฐ๋กํด ๋์ธ์.
๋ฐฑ์ ์์ ์ ์คํฌ๋ฆฝํ โ
์ด๋ป๊ฒ ์ธ์คํด์ค๊ฐ ๊ตฌ์ฑ๋์๋ ์ง ๊ฐ์ ์๋ฒ์ ์ฑ ๋ฐ์ดํฐ ์คํ ์ด๋ฅผ ๊ฒ์ฌํ์ฌ ์ด๋ค ๋ฐ์ดํฐ๋ฅผ ๋ฐฑ์ ํ ๊ฒ์ธ์ง ์ดํดํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ๋ค์๊ณผ ๊ฐ์ ๊ตฌ์กฐ๋ฅผ ํ์ธํ ์ ์์ด์ผ ํฉ๋๋ค:
โโโ audit.log
โโโ cache/
โโโ uploads/
โโโ vector_db/
โโโ webui.db
์ง์ ๊ฐ๋ฅํ ๋ฐ์ดํฐ ์คํ ์ด์ ํ์ผ๋คโ
ํ์ผ/๋๋ ํฐ๋ฆฌ | ์ค๋ช |
---|---|
audit.log | ์ด๋ฒคํธ ๊ฐ์ฌ ๊ธฐ๋ก ํ์ผ |
cache/ | ์บ์ ๋ฐ์ดํฐ ์ ์ฅ ๋๋ ํฐ๋ฆฌ |
uploads/ | ์ฌ์ฉ์ ์ ๋ก๋ ํ์ผ ์ ์ฅ ๋๋ ํฐ๋ฆฌ |
vector_db/ | ChromaDB ๋ฒกํฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ํฌํจํ ๋๋ ํฐ๋ฆฌ |
webui.db | ๊ธฐํ ์ธ์คํด์ค ๋ฐ์ดํฐ๋ฅผ ์๊ตฌ ์ ์ฅํ๊ธฐ ์ํ SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค |
ํ์ผ ์์ค ๋ฐฑ์ ์ ๊ทผ๋ฒ
์ ํ๋ฆฌ์ผ์ด์ ๋ฐ์ดํฐ๋ฅผ ๋ฐฑ์ ํ๋ ์ฒซ ๋ฒ์งธ ๋ฐฉ๋ฒ์ ํ์ผ ์์ค ๋ฐฑ์ ์ ๊ทผ๋ฒ์ผ๋ก, Open Web UI์ ์ง์์ ์ธ ๋ฐ์ดํฐ๋ฅผ ์ ๋๋ก ๋ฐฑ์ ํ ์ ์๋๋ก ํ๋ ๊ฒ์ ๋๋ค.
๊ธฐ์ ์๋น์ค๋ ๊ฑฐ์ ๋ฌดํํ ๋ฐฉ๋ฒ์ผ๋ก ๋ฐฑ์
๋ ์ ์์ผ๋, ์ฆ๋ถ ์์
์ ์ํด rsync
๋ ์ฌ์ ํ ์ธ๊ธฐ๊ฐ ์์ผ๋ฉฐ ๋ฐ๋ชจ๋ก ์ฌ์ฉ๋ ๊ฒ์
๋๋ค.
์ฌ์ฉ์๋ ์ ์ฒด data
๋๋ ํฐ๋ฆฌ๋ฅผ ๋์์ผ๋ก ์ผ์ ๋ชจ๋ ์ธ์คํด์ค ๋ฐ์ดํฐ๋ฅผ ํ ๋ฒ์ ๋ฐฑ์
ํ๊ฑฐ๋ ๊ฐ๋ณ ๊ตฌ์ฑ ์์๋ฅผ ๋์์ผ๋ก ํ๋ ๋ ์ ํ์ ์ธ ๋ฐฑ์
์์
์ ์์ฑํ ์ ์์ต๋๋ค. ๋์์ ๋ํ ๋ ๋ง์ ์ค๋ช
์ด๋ฆ์ ์ถ๊ฐํ ์๋ ์์ต๋๋ค.
๋ชจ๋ฒ์ ์ธ rsync ์์ ์ ๋ค์๊ณผ ๊ฐ์ ์ ์์ต๋๋ค:
#!/bin/bash
# ๊ตฌ์ฑ
SOURCE_DIR="." # ํ์ผ ๊ตฌ์กฐ๊ฐ ์์นํ ํ์ฌ ๋๋ ํฐ๋ฆฌ
B2_BUCKET="b2://OpenWebUI-backups" # Backblaze B2 ๋ฒํท
B2_PROFILE="your_rclone_profile" # rclone ํ๋กํ์ผ ์ด๋ฆ
# rclone์ด B2 ์ธ์ฆ ์ ๋ณด๋ก ๊ตฌ์ฑ๋์๋์ง ํ์ธ
# ์ถ์ฒ ๋ฐ ๋์ ๋๋ ํฐ๋ฆฌ ์ ์
SOURCE_UPLOADS="$SOURCE_DIR/uploads"
SOURCE_VECTORDB="$SOURCE_DIR/vector_db"
SOURCE_WEBUI_DB="$SOURCE_DIR/webui.db"
DEST_UPLOADS="$B2_BUCKET/user_uploads"
DEST_CHROMADB="$B2_BUCKET/ChromaDB"
DEST_MAIN_DB="$B2_BUCKET/main_database"
# cache ๋ฐ audit.log ์ ์ธ
EXCLUDE_LIST=(
"cache/"
"audit.log"
)
# rclone ์ ์ธ ์ธ์ ๊ตฌ์ฑ
EXCLUDE_ARGS=""
for EXCLUDE in "${EXCLUDE_LIST[@]}"; do
EXCLUDE_ARGS="$EXCLUDE_ARGS --exclude $EXCLUDE"
done
# ์ค๋ฅ ๊ฒ์ฌ๋ก rclone ๋๊ธฐํ ์ํ ํจ์
rclone_sync() {
SOURCE="$1"
DEST="$2"
echo "Syncing $SOURCE to $DEST..."
rclone sync "$SOURCE" "$DEST" $EXCLUDE_ARGS --progress --transfers=32 --checkers=16 --profile "$B2_PROFILE"
if [ $? -ne 0 ]; then
echo "Error: rclone sync failed for $SOURCE to $DEST"
exit 1
fi
}
# ๊ฐ ๋๋ ํฐ๋ฆฌ/ํ์ผ์ ๋ํด rclone ๋๊ธฐํ ์ํ
rclone_sync "$SOURCE_UPLOADS" "$DEST_UPLOADS"
rclone_sync "$SOURCE_VECTORDB" "$DEST_CHROMADB"
rclone_sync "$SOURCE_WEBUI_DB" "$DEST_MAIN_DB"
echo "๋ฐฑ์
์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋์์ต๋๋ค."
exit 0
์ปจํ ์ด๋ ์ค๋จ์ ๋๋ฐํ Rsync ์์ โ
๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ์ ์งํ๋ ค๋ฉด ์ผ๋ฐ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฐฑ์ ์ ์ ์ง๋ ํ์ผ ์์คํ ์์ ์คํํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ๊ธฐ๋ณธ ๋ชจ๋ธ ๋ฐฑ์ ์์ ์ ์ฝ๊ฐ ์์ ํ์ฌ ๋ฐฑ์ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๊ธฐ ์ ์ ์คํ์ ์ค๋จํ๊ณ ์ดํ ๋ค์ ์์ํ๋๋ก ์ค์ ํ ์ ์์ต๋๋ค.
์ด ๋ฐฉ๋ฒ์ ๋จ์ ์ ์ธ์คํด์ค ๋ค์ดํ์์ ์๋ฐํ๋ค๋ ๊ฒ์ ๋๋ค. ์ฌ์ฉํ์ง ์๋ ์๊ฐ๋์ ์์ ์ ์คํํ๊ฑฐ๋ ์คํ ์ค์ธ ๋ฐ์ดํฐ์ ๋ํด ์ผ์ผ ์ํํธ์จ์ด ๋ฐฑ์ ์ ์ํํ๊ณ ์ ์ง๋ ๋ฐ์ดํฐ์ ๋ํด ๋ ๊ฒฌ๊ณ ํ ์ฃผ๊ฐ ๋ฐฑ์ ์ ๊ณ ๋ คํ์ญ์์ค.
#!/bin/bash
# ์ค์
COMPOSE_FILE="docker-compose.yml" # docker-compose.yml ํ์ผ์ ๊ฒฝ๋ก
B2_BUCKET="b2://OpenWebUI-backups" # Backblaze B2 ๋ฒํท
B2_PROFILE="your_rclone_profile" # rclone ํ๋กํ ์ด๋ฆ
SOURCE_DIR="." # ํ์ฌ ๋๋ ํ ๋ฆฌ (ํ์ผ ๊ตฌ์กฐ๊ฐ ์๋ ์์น)
# ์์ค ๋ฐ ๋์ ๋๋ ํ ๋ฆฌ ์ ์
SOURCE_UPLOADS="$SOURCE_DIR/uploads"
SOURCE_VECTORDB="$SOURCE_DIR/vector_db"
SOURCE_WEBUI_DB="$SOURCE_DIR/webui.db"
DEST_UPLOADS="$B2_BUCKET/user_uploads"
DEST_CHROMADB="$B2_BUCKET/ChromaDB"
DEST_MAIN_DB="$B2_BUCKET/main_database"
# cache ๋ฐ audit.log ์ ์ธ
EXCLUDE_LIST=(
"cache/"
"audit.log"
)
# rclone์ ์ ์ธ ์ธ์ ๊ตฌ์ฑ
EXCLUDE_ARGS=""
for EXCLUDE in "${EXCLUDE_LIST[@]}"; do
EXCLUDE_ARGS="$EXCLUDE_ARGS --exclude $EXCLUDE"
done
# rclone ๋๊ธฐํ ์ํ ๋ฐ ์ค๋ฅ ํ์ธ์ ์ํ ํจ์
rclone_sync() {
SOURCE="$1"
DEST="$2"
echo "$SOURCE๋ฅผ $DEST๋ก ๋๊ธฐํ ์ค..."
rclone sync "$SOURCE" "$DEST" $EXCLUDE_ARGS --progress --transfers=32 --checkers=16 --profile "$B2_PROFILE"
if [ $? -ne 0 ]; then
echo "์ค๋ฅ: $SOURCE๋ฅผ $DEST๋ก ๋๊ธฐํ ์คํจ"
exit 1
fi
}
# 1. Docker Compose ํ๊ฒฝ ์ค๋จ
echo "Docker Compose ํ๊ฒฝ ์ค๋จ ์ค..."
docker-compose -f "$COMPOSE_FILE" down
# 2. ๋ฐฑ์
์ํ
echo "๋ฐฑ์
์์ ์ค..."
rclone_sync "$SOURCE_UPLOADS" "$DEST_UPLOADS"
rclone_sync "$SOURCE_VECTORDB" "$DEST_CHROMADB"
rclone_sync "$SOURCE_WEBUI_DB" "$DEST_MAIN_DB"
# 3. Docker Compose ํ๊ฒฝ ์์
echo "Docker Compose ํ๊ฒฝ ์์ ์ค..."
docker-compose -f "$COMPOSE_FILE" up -d
echo "๋ฐฑ์
์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋์์ต๋๋ค."
exit 0
SQLite์ ChromaDB ๋ฐฑ์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ B2 ์๊ฒฉ์ผ๋ก ๋ชจ๋ธ ๋ฐฑ์ ์คํฌ๋ฆฝํธโ
#!/bin/bash
#
# Backblaze B2 ๋ฒํท์ ChromaDB ๋ฐ SQLite๋ฅผ ๋ฐฑ์
ํ๋ ์คํฌ๋ฆฝํธ
# openwebuiweeklies๋ฅผ ์ฌ์ฉํ์ฌ 3๊ฐ์ ์ฃผ๊ฐ ์ค๋
์ท์ ์ ์งํฉ๋๋ค.
# ์ค๋
์ท์ ๋
๋ฆฝ์ ์ด๊ณ ์์ ํ ๋ณต์ ๊ฐ๋ฅํฉ๋๋ค.
# ChromaDB์ SQLite์ ๊ธฐ๋ณธ ๋ฐฑ์
๋ฉ์ปค๋์ฆ์ ์ฌ์ฉํฉ๋๋ค.
# audit.log, cache ๋ฐ uploads ๋๋ ํ ๋ฆฌ๋ฅผ ์ ์ธํฉ๋๋ค.
#
# rclone์ด ์ฌ๋ฐ๋ฅด๊ฒ ์ค์น๋๊ณ ๊ตฌ์ฑ๋์๋์ง ํ์ธํ์ธ์.
# rclone ์ค์น: https://rclone.org/install/
# rclone ๊ตฌ์ฑ: https://rclone.org/b2/
# ChromaDB ๋ฐ SQLite ๋ฐ์ดํฐ๊ฐ ํฌํจ๋ ์์ค ๋๋ ํ ๋ฆฌ
SOURCE="/var/lib/open-webui/data"
# B2 ๋ฒํท ์ด๋ฆ ๋ฐ ์๊ฒฉ ์ด๋ฆ
B2_REMOTE="openwebuiweeklies"
B2_BUCKET="b2:$B2_REMOTE"
# ๋ฐฑ์
๋๋ ํ ๋ฆฌ์ฉ ํ์์คํฌํ
TIMESTAMP=$(date +%Y-%m-%d)
# ๋ฐฑ์
๋๋ ํ ๋ฆฌ ์ด๋ฆ
BACKUP_DIR="open-webui-backup-$TIMESTAMP"
# B2 ๋ฒํท์ ๋ฐฑ์
๋๋ ํ ๋ฆฌ์ ๋ํ ์ ์ฒด ๊ฒฝ๋ก
DESTINATION="$B2_BUCKET/$BACKUP_DIR"
# ์ ์งํ ์ฃผ๊ฐ ์ค๋
์ท์ ์
NUM_SNAPSHOTS=3
# ์ ์ธ ํํฐ (๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฐฑ์
์ดํ ์ ์ฉ)
EXCLUDE_FILTERS="--exclude audit.log --exclude cache/** --exclude uploads/** --exclude vector_db"
# ChromaDB ๋ฐฑ์
์ค์ (ํ์์ ๋ฐ๋ผ ์กฐ์ )
CHROMADB_DATA_DIR="$SOURCE/vector_db" # ChromaDB ๋ฐ์ดํฐ ๋๋ ํ ๋ฆฌ ๊ฒฝ๋ก
CHROMADB_BACKUP_FILE="$SOURCE/chromadb_backup.tar.gz" # ChromaDB ๋ฐฑ์
์ ์ํ ์์นด์ด๋ธ ํ์ผ
# SQLite ๋ฐฑ์
์ค์ (ํ์์ ๋ฐ๋ผ ์กฐ์ )
SQLITE_DB_FILE="$SOURCE/webui.db" # SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ์ผ ๊ฒฝ๋ก
SQLITE_BACKUP_FILE="$SOURCE/webui.db.backup" # SQLite ๋ฐฑ์
์์ ํ์ผ
# ChromaDB ๋ฐฑ์
ํจ์
backup_chromadb() {
echo "ChromaDB ๋ฐฑ์
์ค..."
# vector_db ๋๋ ํ ๋ฆฌ๋ฅผ tar ์์นด์ด๋ธ๋ก ๋ง๋ค๊ธฐ
tar -czvf "$CHROMADB_BACKUP_FILE" -C "$SOURCE" vector_db
echo "ChromaDB ๋ฐฑ์
์๋ฃ."
}
# SQLite ๋ฐฑ์
ํจ์
backup_sqlite() {
echo "SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฐฑ์
์ค..."
# .backup ๋ช
๋ น์ ์ฌ์ฉํ์ฌ SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฐฑ์
sqlite3 "$SQLITE_DB_FILE" ".backup $SQLITE_BACKUP_FILE"
# ๋ฐฑ์
ํ์ผ์ ์์ค ๋๋ ํ ๋ฆฌ๋ก ์ด๋
mv "$SQLITE_BACKUP_FILE" "$SOURCE/"
echo "SQLite ๋ฐฑ์
์๋ฃ."
}
# ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฐฑ์
์ํ
backup_chromadb
backup_sqlite
# ์ ์ธ๋ฅผ ์ ์ฉํ์ฌ ๋ฐฑ์
์ํ
rclone copy "$SOURCE" "$DESTINATION" $EXCLUDE_FILTERS --progress
# ์ค๋๋ ๋ฐฑ์
์ ๊ฑฐ, ์ต๊ทผ NUM_SNAPSHOTS๋ง ์ ์ง
find "$B2_BUCKET" -type d -name "open-webui-backup-*" | sort -r | tail -n +$((NUM_SNAPSHOTS + 1)) | while read dir; do
rclone purge "$dir"
done
echo "$DESTINATION์ผ๋ก ๋ฐฑ์
์๋ฃ"
์์ ์ค๋ ์ท(Point In Time Snapshots)โ
๋ฐฑ์ ์ธ์๋ ์ฌ์ฉ์๋ ๋ก์ปฌ(์๋ฒ์) ๋๋ ์๊ฒฉ์ง ํน์ ๋ ๋ค์ ์์ ์ค๋ ์ท์ ์์ฑํ์ฌ ์ ์ฅํ ์ ์์ต๋๋ค.
#!/bin/bash
# ์ค์
SOURCE_DIR="." # ์ค๋
์ทํ ๋๋ ํ ๋ฆฌ(ํ์ฌ ๋๋ ํ ๋ฆฌ)
SNAPSHOT_DIR="/snapshots" # ์ค๋
์ท์ ์ ์ฅํ ๋๋ ํ ๋ฆฌ
TIMESTAMP=$(date +%Y%m%d%H%M%S) # ํ์์คํฌํ ์์ฑ
# ์ค๋
์ท ๋๋ ํ ๋ฆฌ๊ฐ ์์ผ๋ฉด ์์ฑ
mkdir -p "$SNAPSHOT_DIR"
# ์ค๋
์ท ์ด๋ฆ ์์ฑ
SNAPSHOT_NAME="snapshot_$TIMESTAMP"
SNAPSHOT_PATH="$SNAPSHOT_DIR/$SNAPSHOT_NAME"
# rsync ์ค๋
์ท ์ํ
echo "์ค๋
์ท ์์ฑ ์ค: $SNAPSHOT_PATH"
rsync -av --delete --link-dest="$SNAPSHOT_DIR/$(ls -t "$SNAPSHOT_DIR" | head -n 1)" "$SOURCE_DIR/" "$SNAPSHOT_PATH"
# rsync ์ฑ๊ณต ํ์ธ
if [ $? -eq 0 ]; then
echo "์ค๋
์ท์ด ์ฑ๊ณต์ ์ผ๋ก ์์ฑ๋์์ต๋๋ค."
else
echo "์ค๋ฅ: ์ค๋
์ท ์์ฑ ์คํจ."
exit 1
fi
exit 0
Crontab์ ์ฌ์ฉํ ์ผ์ ์ค์ โ
๋ฐฑ์ ์คํฌ๋ฆฝํธ๋ฅผ ์ถ๊ฐํ๊ณ ๋ฐฑ์ ์คํ ๋ฆฌ์ง ๋ฅผ ์ค์ ํ ํ์๋ ์คํฌ๋ฆฝํธ๊ฐ ๊ธฐ๋๋๋ก ์๋ํ๋์ง ํ์ง ๊ฒ์ฌ๋ฅผ ์ํํด์ผ ํฉ๋๋ค. ๋ก๊ทธ ๊ธฐ๋ก์ด ๋งค์ฐ ์ถ์ฒ๋ฉ๋๋ค.
์ํ๋ ์คํ ๋น๋์ ๋ฐ๋ผ ์คํฌ๋ฆฝํธ๋ฅผ crontab์ ์ค์ ํ์ญ์์ค.
์์ฉ ์ ํธ๋ฆฌํฐ
์์ฒด ๋ฐฑ์ ์์ ์ ์คํฌ๋ฆฝํ ํ๋ ๊ฒ ์ธ์๋ ์๋ฒ์ ์์ด์ ํธ๋ฅผ ์ค์นํ์ฌ ๋ฐฑ์ ์คํ์ ๋ณต์ก์ฑ์ ์ถ์ํํ๋ ์์ฉ ์ ํ์ ์ฐพ์ ์ ์์ต๋๋ค. ์ด๋ฌํ ๋ด์ฉ์ ์ด ๋ฌธ์์ ๋ฒ์๋ฅผ ๋ฒ์ด๋์ง๋ง ํธ๋ฆฌํ ์๋ฃจ์ ์ ์ ๊ณตํฉ๋๋ค.
ํธ์คํธ ์์ค ๋ฐฑ์
Open WebUI ์ธ์คํด์ค๋ ๋ฌผ๋ฆฌ์ ๋๋ ๊ฐ์ ํธ์คํธ์์ ํ๋ก๋น์ ๋ ๋ ์ ์์ต๋๋ค.
ํธ์คํธ ์์ค ๋ฐฑ์ ์ ์คํ ์ค์ธ ์ ํ๋ฆฌ์ผ์ด์ ๋์ ์ ์ฒด VM์ ์ค๋ ์ท ๋๋ ๋ฐฑ์ ์ ์์ฑํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค.
์ผ๋ถ๋ ์ด๋ฅผ ์ฃผ์ ๋๋ ์ ์ผํ ๋ณดํธ์ฑ ์ผ๋ก ํ์ฉํ ์ ์์ผ๋ฉฐ ๋ค๋ฅธ ์ผ๋ถ๋ ์ถ๊ฐ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณดํธํ๊ธฐ ์ํด ์ด๋ฅผ ๊ณ์ธต์ ์ผ๋ก ์ ์ฉํ ์ ์์ต๋๋ค.
์ผ๋ง๋ ๋ง์ ๋ฐฑ์ ์ด ํ์ํฉ๋๊น?
์ทจํ ๋ฐฑ์ ์๋ ๊ฐ์ธ์ ์ธ ์ํ ํ์ฉ ์์ค์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค. ๊ทธ๋ฌ๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ฒด๋ฅผ ๋ฐฑ์ ์ฌ๋ณธ์ผ๋ก ๊ฐ์ฃผํ์ง ์๋ ๊ฒ์ด ๋ชจ๋ฒ ์ฌ๋ก์์ ๊ธฐ์ตํ์ญ์์ค(๋น๋ก ํด๋ผ์ฐ๋์ ์๋ค ํ๋๋ผ๋!). ์ด๋ ์ธ์คํด์ค๋ฅผ VPS์ ํ๋ก๋น์ ๋ ํ ๊ฒฝ์ฐ์๋ ๋ ๊ฐ์ ๋ ๋ฆฝ์ ์ธ ๋ฐฑ์ ์ฌ๋ณธ์ ์ ์งํ๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์ธ ์ถ์ฒ์์ ์๋ฏธํฉ๋๋ค.
๋ง์ ํ ์ฌ์ฉ์ ์๊ตฌ๋ฅผ ์ถฉ์กฑํ๋ ๋ฐฑ์ ๊ณํ ์์:
๋ชจ๋ธ ๋ฐฑ์ ๊ณํ 1 (์ฃผ์ + 2 ์ฌ๋ณธ)โ
๋น๋ | ๋์ | ๊ธฐ ์ | ์ค๋ช |
---|---|---|---|
์ผ์ผ ์ฆ๋ถ | ํด๋ผ์ฐ๋ ์คํ ๋ฆฌ์ง (S3/B2) | rsync | ํด๋ผ์ฐ๋ ์คํ ๋ฆฌ์ง ๋ฒํท(S3 ๋๋ B2)์ ์ผ์ผ ์ฆ๋ถ ๋ฐฑ์ ์ ํธ์ํฉ๋๋ค. |
์ฃผ๊ฐ ์ฆ๋ถ | ์จ์ฌ์ดํธ ์คํ ๋ฆฌ์ง (ํ NAS) | rsync | ์๋ฒ์์ ์จ์ฌ์ดํธ ์คํ ๋ฆฌ์ง(์: ํ NAS)๋ก ์ฃผ๊ฐ ์ฆ๋ถ ๋ฐฑ์ ์ ๊ฐ์ ธ์ต๋๋ค. |
๋ชจ๋ธ ๋ฐฑ์ ๊ณํ 2 (์ฃผ์ + 3 ์ฌ๋ณธ)โ
์ด ๋ฐฑ์ ๊ณํ์ ์กฐ๊ธ ๋ ๋ณต์กํ์ง๋ง ๋ ํฌ๊ด์ ์ ๋๋ค. ์ถ๊ฐ์ ์ธ ์ค๋ณต์ฑ์ ์ํด ๋ ๊ฐ์ ํด๋ผ์ฐ๋ ์คํ ๋ฆฌ์ง ์ ๊ณต์์ ์ผ์ผ ํธ์๋ฅผ ํฌํจํฉ๋๋ค.
๋น๋ | ๋์ | ๊ธฐ์ | ์ค๋ช |
---|---|---|---|
์ผ์ผ ์ฆ๋ถ | ํด๋ผ์ฐ๋ ์คํ ๋ฆฌ์ง (S3) | rsync | S3 ํด๋ผ์ฐ๋ ์คํ ๋ฆฌ์ง ๋ฒํท์ผ๋ก ์ผ์ผ ์ฆ๋ถ ๋ฐฑ์ ์ ํธ์ํฉ๋๋ค. |
์ผ์ผ ์ฆ๋ถ | ํด๋ผ์ฐ๋ ์คํ ๋ฆฌ์ง (B2) | rsync | Backblaze B2 ํด๋ผ์ฐ๋ ์คํ ๋ฆฌ์ง ๋ฒํท์ผ๋ก ์ผ์ผ ์ฆ๋ถ ๋ฐฑ์ ์ ํธ์ํฉ๋๋ค. |
์ฃผ๊ฐ ์ฆ๋ถ | ์จ์ฌ์ดํธ ์คํ ๋ฆฌ์ง (ํ NAS) | rsync | ์๋ฒ์์ ์จ์ฌ์ดํธ ์คํ ๋ฆฌ์ง(์: ํ NAS)๋ก ์ฃผ๊ฐ ์ฆ๋ถ ๋ฐฑ์ ์ ๊ฐ์ ธ์ต๋๋ค. |
์ถ๊ฐ ์ฃผ์
์ด ๊ฐ์ด๋๋ฅผ ์ ์ ํ ํฌ๊ด์ ์ผ๋ก ์ ์งํ๊ธฐ ์ํด ์ด๋ฌํ ์ถ๊ฐ ์ฃผ์ ๋ ์๋ต๋์์ง๋ง ์ธ์คํด์ค์ ๋ฐ์ดํฐ ๋ณดํธ ๊ณํ์ ์ค์ ํ๊ณ ์ ์งํ๋ ๋ฐ ํ ์ ํ ์๊ฐ์ด ์ผ๋ง๋ ๋๋์ง์ ๋ฐ๋ผ ๊ฒํ ํ ๋งํ ๊ฐ์น๊ฐ ์์ต๋๋ค:
์ฃผ์ | ์ค๋ช |
---|---|
SQLite ๊ธฐ๋ฐ ๋ฐฑ์ | ์์ ์ ์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฐฑ์
์๋ฃจ์
์ ์ํด SQLite์ .backup ๋ช
๋ น์ ๊ณ ๋ คํ์ญ์์ค. |
์ํธํ | ๋ฐฑ์ ์คํฌ๋ฆฝํธ๋ฅผ ์์ ํ์ฌ ๋ณด์์ ๊ฐํํ๊ธฐ ์ํด ๋๊ธฐ ์ค ์ํธํ๋ฅผ ํฌํจ์ํต๋๋ค. |
์ฌ๋ ๋ณต๊ตฌ ๋ฐ ํ ์คํธ | ์ฌ๋ ๋ณต๊ตฌ ๊ณํ์ ๊ฐ๋ฐํ๊ณ ์ ๊ธฐ์ ์ผ๋ก ๋ฐฑ์ ๋ฐ ๋ณต๊ตฌ ํ๋ก์ธ์ค๋ฅผ ํ ์คํธํ์ญ์์ค. |
๋์ฒด ๋ฐฑ์ ๋๊ตฌ | borgbackup ๋๋ restic ๊ณผ ๊ฐ์ ๋ค๋ฅธ ๋ช
๋ น์ค ๋ฐฑ์
๋๊ตฌ๋ฅผ ํ์ํ์ฌ ๊ณ ๊ธ ๊ธฐ๋ฅ์ ํ์ฉํ์ญ์์ค. |
์ด๋ฉ์ผ ์๋ฆผ ๋ฐ ์นํ | ๋ฐฑ์ ์ฑ๊ณต ๋๋ ์คํจ๋ฅผ ๋ชจ๋ํฐ๋งํ๊ธฐ ์ํด ์ด๋ฉ์ผ ์๋ฆผ ๋๋ ์นํ ์ ๊ตฌํํ์ญ์์ค. |