本教程由社区贡献,不获得 Open WebUI 团队的支持。它仅作为演示,说明如何根据您的特定用例定制 Open WebUI。想要贡献?请查看贡献教程。
备份您的实例
没有人喜欢丢失数据!
如果您是Open WebUI的自托管用户,您可能希望制定某种正式的备份计划,以确保保留配置的第二份和第三份副本。
本指南旨在为用户提供一些关于如何进行备份的基本建议。
本指南假设用户已通过Docker安装Open WebUI(或打算这样做)
确保数据持久性
首先,在使用Docker部署堆栈之前,请确保您的Docker Compose使用持久性数据存储。如果您使用的是Github仓库中的Docker Compose,这一点已经处理好了。但是,很容易创建自己的变体并忘记验证这一点。
Docker容器是短暂的,数据必须持久化才能确保其在宿主文件系统上的存活。
使用Docker卷
如果您使用项目仓库中的Docker Compose,您将使用Docker卷部署Open Web UI。
对于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
# Configuration
SOURCE_DIR="." # Current directory (where the file structure resides)
B2_BUCKET="b2://OpenWebUI-backups" # Your Backblaze B2 bucket
B2_PROFILE="your_rclone_profile" # Your rclone profile name
# Ensure rclone is configured with your B2 credentials
# Define source and destination directories
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"
# Exclude cache and audit.log
EXCLUDE_LIST=(
"cache/"
"audit.log"
)
# Construct exclude arguments for rclone
EXCLUDE_ARGS=""
for EXCLUDE in "${EXCLUDE_LIST[@]}"; do
EXCLUDE_ARGS="$EXCLUDE_ARGS --exclude '$EXCLUDE'"
done
# Function to perform rclone sync with error checking
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
}
# Perform rclone sync for each directory/file
rclone_sync "$SOURCE_UPLOADS" "$DEST_UPLOADS"
rclone_sync "$SOURCE_VECTORDB" "$DEST_CHROMADB"
rclone_sync "$SOURCE_WEBUI_DB" "$DEST_MAIN_DB"
echo "Backup completed successfully."
exit 0
带容器中断的Rsync任务
为维护数据完整性,通常建议在冷文件系统上运行数据库备份。我们的默认模型备份任务可以稍微修改,以便在运行备份脚本之前关闭堆栈,并在之后重新启动。
当然,这种方法的缺点是会导致实例停机。考虑在不使用实例时运行此任务,或进行“软件”每日备份(对运行中的数据)以及更可靠的每周备份(对冷数据)。
#!/bin/bash
# Configuration
COMPOSE_FILE="docker-compose.yml" # Path to your docker-compose.yml file
B2_BUCKET="b2://OpenWebUI-backups" # Your Backblaze B2 bucket
B2_PROFILE="your_rclone_profile" # Your rclone profile name
SOURCE_DIR="." # Current directory (where the file structure resides)
# Define source and destination directories
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"
# Exclude cache and audit.log
EXCLUDE_LIST=(
"cache/"
"audit.log"
)
# Construct exclude arguments for rclone
EXCLUDE_ARGS=""
for EXCLUDE in "${EXCLUDE_LIST[@]}"; do
EXCLUDE_ARGS="$EXCLUDE_ARGS --exclude '$EXCLUDE'"
done
# Function to perform rclone sync with error checking
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
}
# 1. Stop the Docker Compose environment
echo "Stopping Docker Compose environment..."
docker-compose -f "$COMPOSE_FILE" down
# 2. Perform the backup
echo "Starting backup..."
rclone_sync "$SOURCE_UPLOADS" "$DEST_UPLOADS"
rclone_sync "$SOURCE_VECTORDB" "$DEST_CHROMADB"
rclone_sync "$SOURCE_WEBUI_DB" "$DEST_MAIN_DB"
# 3. Start the Docker Compose environment
echo "Starting Docker Compose environment..."
docker-compose -f "$COMPOSE_FILE" up -d
echo "Backup completed successfully."
exit 0
使用SQLite和ChromaDB备份功能到B2远程的模型备份脚本
#!/bin/bash
#
# Backup script to back up ChromaDB and SQLite to Backblaze B2 bucket
# openwebuiweeklies, maintaining 3 weekly snapshots.
# Snapshots are independent and fully restorable.
# Uses ChromaDB and SQLite native backup mechanisms.
# Excludes audit.log, cache, and uploads directories.
#
# Ensure rclone is installed and configured correctly.
# Install rclone: https://rclone.org/install/
# Configure rclone: https://rclone.org/b2/
# Source directory (containing ChromaDB and SQLite data)
SOURCE="/var/lib/open-webui/data"
# B2 bucket name and remote name
B2_REMOTE="openwebuiweeklies"
B2_BUCKET="b2:$B2_REMOTE"
# Timestamp for the backup directory
TIMESTAMP=$(date +%Y-%m-%d)
# Backup directory name
BACKUP_DIR="open-webui-backup-$TIMESTAMP"
# Full path to the backup directory in the B2 bucket
DESTINATION="$B2_BUCKET/$BACKUP_DIR"
# Number of weekly snapshots to keep
NUM_SNAPSHOTS=3
# Exclude filters (applied *after* database backups)
EXCLUDE_FILTERS="--exclude audit.log --exclude cache/** --exclude uploads/** --exclude vector_db"
# ChromaDB Backup Settings (Adjust as needed)
CHROMADB_DATA_DIR="$SOURCE/vector_db" # Path to ChromaDB data directory
CHROMADB_BACKUP_FILE="$SOURCE/chromadb_backup.tar.gz" # Archive file for ChromaDB backup
# SQLite Backup Settings (Adjust as needed)
SQLITE_DB_FILE="$SOURCE/webui.db" # Path to the SQLite database file
SQLITE_BACKUP_FILE="$SOURCE/webui.db.backup" # Temporary file for SQLite backup
# Function to backup ChromaDB
backup_chromadb() {
echo "Backing up ChromaDB..."
# Create a tar archive of the vector_db directory
tar -czvf "$CHROMADB_BACKUP_FILE" -C "$SOURCE" vector_db
echo "ChromaDB backup complete."
}
# Function to backup SQLite
backup_sqlite() {
echo "Backing up SQLite database..."
# Backup the SQLite database using the .backup command
sqlite3 "$SQLITE_DB_FILE" ".backup '$SQLITE_BACKUP_FILE'"
# Move the backup file to the source directory
mv "$SQLITE_BACKUP_FILE" "$SOURCE/"
echo "SQLite backup complete."
}
# Perform database backups
backup_chromadb
backup_sqlite
# Perform the backup with exclusions
rclone copy "$SOURCE" "$DESTINATION" $EXCLUDE_FILTERS --progress
# Remove old backups, keeping the most recent 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 "Backup completed to $DESTINATION"
时间点快照
除了进行备份,用户可能还希望创建时间点快照,这些快照可以存储在本地(服务器上)、远程或两者兼有。
#!/bin/bash
# Configuration
SOURCE_DIR="." # Directory to snapshot (current directory)
SNAPSHOT_DIR="/snapshots" # Directory to store snapshots
TIMESTAMP=$(date +%Y%m%d%H%M%S) # Generate timestamp
# Create the snapshot directory if it doesn't exist
mkdir -p "$SNAPSHOT_DIR"
# Create the snapshot name
SNAPSHOT_NAME="snapshot_$TIMESTAMP"
SNAPSHOT_PATH="$SNAPSHOT_DIR/$SNAPSHOT_NAME"
# Perform the rsync snapshot
echo "Creating snapshot: $SNAPSHOT_PATH"
rsync -av --delete --link-dest="$SNAPSHOT_DIR/$(ls -t "$SNAPSHOT_DIR" | head -n 1)" "$SOURCE_DIR/" "$SNAPSHOT_PATH"
# Check if rsync was successful
if [ $? -eq 0 ]; then
echo "Snapshot created successfully."
else
echo "Error: Snapshot creation failed."
exit 1
fi
exit 0
用于调度的Crontab
添加备份脚本并配置好备份存储后,您需要对脚本进行质量保证,以确保它们按预期运行。强烈建议进行日志记录。
根据您希望的运行频率,使用crontabs设置新的脚本来运行。
商业工具
除了编写自己的备份任务脚本外,您还可以找到商业产品,它们通常通过在服务器上安装代理来简化备份运行的复杂性。这些超出了本文的范围,但提供了方便的解决方案。
主机级备份
您的Open WebUI实例可能部署在您控制的主机(物理或虚拟化)上。
主机级备份涉及创建快照或备份,但备份的是整个虚拟机而非运行中的应用程序。
有些人可能希望将其作为主要或唯一的保护措施,而另一些人则可能希望将其作为额外的数据保护层。
我需要多少个备份?
您希望进行的备份数量取决于您的个人风险承受能力。但是,请记住,最佳实践是*不要*将应用程序本身视为备份副本(即使它存在于云端!)。这意味着,如果您已在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 ,以获取高级功能。 |
电子邮件通知和Webhook | 实现电子邮件通知或webhook以监控备份的成功或失败。 |