本教程是由社区贡献的,不属于 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
Model Backup Script Using SQLite & ChromaDB Backup Functions To B2 Remote
#!/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
# 配置
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 进行调度
一旦您添加了备份脚本并配置了备份存储,您就需要对脚本进行 QA 以确保它们按预期运行。记录日志是非常明智的。
根据您所需的运行频率,使用 crontabs 设置您的新脚本。
商业工具
除了编写自己的备份作业脚本外,您还可以找到一些商业产品,它们通常通过在服务器上安装代理来运行,从而抽象出运行备份的复杂性。这些超出了本文的范围,但提供了方便的解决方案。
宿主机级别备份
您的 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 命令来获得一致的数据库备份解决方案。 |
| 加密 | 修改备份脚本以包含静态加密。有关数据库级加密,请参阅 使用 SQLCipher 进行数据库加密。 |
| 灾难恢复与测试 | 制定灾难恢复计划并定期测试备份和恢复过程。 |
| 备选备份工具 | 探索其他命令行备份工具,如 borgbackup 或 restic 以获取高级功能。 |
| 邮件通知与 Webhooks | 实现邮件通知或 webhooks 以监控备份的成功或失败。 |