Skip to main content
warning

本教程是由社区贡献的,不属于 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 进行数据库加密
灾难恢复与测试制定灾难恢复计划并定期测试备份和恢复过程。
备选备份工具探索其他命令行备份工具,如 borgbackuprestic 以获取高级功能。
邮件通知与 Webhooks实现邮件通知或 webhooks 以监控备份的成功或失败。