本教程由社区贡献,不受 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 ,以获取高级功能。 |
电子邮件通知和 Webhooks | 实现电子邮件通知或 Webhooks 来监控备份成功或失败。 |