7535 字
38 分钟
SillyTavern 完全指南(三):运维篇 — 生产部署与日常维护

目录#


1. 生产级部署#

如果你已经完成了入门篇和进阶篇的学习,现在应该已经在本地能稳定使用 SillyTavern 了。但本地 localhost:8000 只能自己访问,想要在外网安全地使用,或者想让多个设备同时连接,就需要一套完整的生产级部署方案。

本章将带你从单容器裸奔,进化到 Podman Compose 编排 + Nginx 反代 + HTTPS 安全传输 + 可选的 Cloudflare Tunnel 远程访问。

1.1 Podman Compose 编排部署#

Podman Compose 是生产环境的首选方案。相比于手动敲 podman run,Compose 文件将整个部署描述声明化,方便版本控制和重复部署。

1.1.1 安装 Podman Compose#

Terminal window
# Linux (Fedora / RHEL / CentOS)
sudo dnf install podman-compose
# Ubuntu / Debian
sudo apt install podman-compose
# macOS / Windows: Podman Desktop 已内置 podman-compose
podman-compose --version

提示: Podman Compose 与 Docker Compose 的 compose.yaml 格式基本兼容。本文的 Compose 文件可直接用于 Docker Compose,只需将 podman-compose 替换为 docker compose

1.1.2 完整 Compose 文件#

在项目根目录创建 compose.yaml

# compose.yaml — SillyTavern 生产部署编排文件
# 使用: podman-compose up -d
# 停止: podman-compose down
services:
# ============================================================
# SillyTavern 主服务
# ============================================================
sillytavern:
image: ghcr.io/sillytavern/sillytavern:latest
container_name: sillytavern
restart: unless-stopped
# 映射端口:宿主机:容器内
# 宿主机建议使用非标准端口(如 8300),避免端口扫描
ports:
- "127.0.0.1:8300:8000"
# 数据卷挂载:持久化所有用户数据
volumes:
# 配置和数据目录
- ./data:/home/node/app/data
# 用户自定义插件
- ./plugins:/home/node/app/plugins
# 配置文件
- ./config.yaml:/home/node/app/config.yaml:ro
# 环境变量通过 .env 文件加载
env_file:
- .env
# 健康检查:每 30s 检测服务是否存活
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/"]
interval: 30s
timeout: 10s
retries: 3
# 日志限制,防止磁盘写满
logging:
driver: journald
options:
max-size: "50m"
max-file: "3"
# ============================================================
# ChromaDB 向量数据库(可选,进阶篇的向量化记忆需要此服务)
# 端口映射为 127.0.0.1:8301:8000,在 SillyTavern 扩展设置中应
# 将 ChromaDB API 地址配置为 http://127.0.0.1:8301
# ============================================================
chromadb:
image: chromadb/chroma:latest
container_name: sillytavern-chroma
restart: unless-stopped
ports:
- "127.0.0.1:8301:8000"
volumes:
- ./chroma_data:/chroma/chroma
environment:
- IS_PERSISTENT=TRUE
- PERSIST_DIRECTORY=/chroma/chroma
- ANONYMIZED_TELEMETRY=FALSE
logging:
driver: journald
options:
max-size: "20m"
max-file: "2"

逐段说明:

  • ports: "127.0.0.1:8300:8000":关键的安全设定。只监听本地回环地址,不暴露到公网。前方将由 Nginx 反代处理外部流量。
  • volumes:将容器内的数据目录映射到宿主机,这样删除重建容器不会丢失数据。config.yaml 以只读模式挂载,避免运行时误修改。
  • env_file: .env:敏感信息(API Key)通过环境变量文件注入,不写在 Compose 文件中,避免不小心提交到 Git。
  • healthcheck:容器编排平台(如 Podman 健康检查)会定期检查服务是否正常,异常时自动重启。
  • logging:限制日志文件大小,防止长时间运行后磁盘写满。

1.1.3 启动与管理#

Terminal window
# 启动所有服务
podman-compose up -d
# 查看运行状态
podman-compose ps
# 查看日志(实时跟踪)
podman-compose logs -f sillytavern
# 重启单个服务
podman-compose restart sillytavern
# 停止并移除所有容器
podman-compose down
# 更新镜像后重建
podman-compose pull && podman-compose up -d

1.1.4 Podman Pod 方式(备选方案)#

如果你的环境没有 podman-compose,或者你更喜欢轻量方案,可以直接使用 Podman Pod:

Terminal window
# 创建 Pod
podman pod create \
--name sillytavern-pod \
--publish 127.0.0.1:8300:8000
# 在 Pod 内启动容器
podman run -d \
--pod sillytavern-pod \
--name sillytavern \
-v ./data:/home/node/app/data \
--env-file .env \
--restart unless-stopped \
ghcr.io/sillytavern/sillytavern:latest
# 查看 Pod 状态
podman pod list
podman pod stats sillytavern-pod

Pod 方式的好处是同一 Pod 内的容器可以通过 localhost 互相通信,适合需要多个辅助容器(如 ChromaDB)的场景。不过 Compose 方式在可维护性上更胜一筹,推荐作为主力方案。

1.2 Nginx 反代配置#

Nginx 在前端接收所有外部请求,根据域名或路径转发到后端的 SillyTavern 服务。这样做有三个好处:统一的 SSL 终止、访问日志集中管理、方便叠加认证和限流。

1.2.1 安装 Nginx#

Terminal window
# Fedora / RHEL
sudo dnf install nginx
# Ubuntu / Debian
sudo apt install nginx
# 启动并设置开机自启
sudo systemctl enable --now nginx

1.2.2 完整 Nginx 配置#

创建 /etc/nginx/conf.d/sillytavern.conf

/etc/nginx/conf.d/sillytavern.conf
# SillyTavern 反代配置
upstream sillytavern_backend {
# 指向本地 SillyTavern 服务
# 8300 对应 Compose 文件中映射的宿主机端口
server 127.0.0.1:8300;
keepalive 64;
}
server {
# 监听 80 端口,重定向到 HTTPS
listen 80;
listen [::]:80;
server_name sillytavern.yourdomain.com;
# Let's Encrypt 验证路径,acme.sh 自动处理
location /.well-known/acme-challenge/ {
root /var/www/html;
}
# 其他 HTTP 请求全部重定向到 HTTPS
location / {
return 301 https://$host$request_uri;
}
}
server {
# HTTPS 配置
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name sillytavern.yourdomain.com;
# SSL 证书路径(acme.sh 安装证书后的默认位置)
# 注意:将 /home/youruser/ 替换为你的实际用户名
ssl_certificate /home/youruser/.acme.sh/sillytavern.yourdomain.com_ecc/fullchain.cer;
ssl_certificate_key /home/youruser/.acme.sh/sillytavern.yourdomain.com_ecc/sillytavern.yourdomain.com.key;
# 现代 SSL 配置(2026 年安全标准)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_ecdh_curve X25519:prime256v1:secp384r1;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# 安全响应头
add_header Strict-Transport-Security "max-age=63072000" always;
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
# 请求体大小限制(角色卡上传可能需要较大限制)
client_max_body_size 50M;
# ---------- 反代配置 ----------
location / {
# 向后端转发
proxy_pass http://sillytavern_backend;
# WebSocket 支持(SillyTavern 实时通信需要)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 传递真实客户端信息
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 超时设置(长对话生成可能耗时较长)
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
}

关键配置说明:

  • proxy_set_header UpgradeConnection "upgrade":WebSocket 协议升级的必要头,SillyTavern 的实时消息推送依赖 WebSocket,缺少这两行会导致连接不稳定。
  • proxy_read_timeout 300s:AI 模型响应时间长,默认 60s 可能会超时截断,建议调大到 300s。
  • client_max_body_size 50M:角色卡文件(特别是带图片的 V2 角色卡)可能超过默认的 1M 限制。

1.2.3 配置防火墙#

Terminal window
# firewalld(Fedora / RHEL)
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
# ufw(Ubuntu / Debian)
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload

1.3 HTTPS 证书(Let’s Encrypt + acme.sh)#

ACME 客户端推荐使用 acme.sh,它是目前最活跃、支持最广泛的 Let’s Encrypt 客户端脚本。

1.3.1 安装 acme.sh#

Terminal window
# 使用官方脚本安装
curl https://get.acme.sh | sh -s email=your-email@example.com
# 重新加载 shell
exec zsh
# 验证安装
acme.sh --version
# 切换到 Let's Encrypt 生产环境(默认为 ZeroSSL,也可用 Let's Encrypt)
acme.sh --set-default-ca --server letsencrypt

1.3.2 申请证书#

假设 Nginx 已经在运行且 80 端口可访问:

Terminal window
# 使用 Webroot 模式申请 ECC 证书(推荐)
# ECC 证书比 RSA 证书更小、更安全
export DOMAIN="sillytavern.yourdomain.com"
acme.sh --issue -d $DOMAIN \
--webroot /var/www/html \
--keylength ec-256

自动化流程说明: acme.sh 会在安装时自动添加 cron 任务,每天检查证书是否在 60 天内过期,过期前自动续签并在续签后自动重载 Nginx。你不需要手动管理续期。

验证 cron 任务已安装:

Terminal window
crontab -l | grep acme.sh

应该能看到类似输出:

0 0 * * * "/home/youruser/.acme.sh"/acme.sh --cron --home "/home/youruser/.acme.sh" > /dev/null

提示: 默认情况下 acme.sh 每 60 天自动续签一次,有效期总共 90 天。续签后会自动执行 --reloadcmd 重载 Nginx 使新证书生效。

1.4 Cloudflare Tunnel 方案(无公网 IP 用户)#

如果你没有公网 IP,或者不想暴露服务器端口到公网,Cloudflare Tunnel 是最佳选择。它通过 cloudflared 客户端与 Cloudflare 边缘网络建立加密隧道,外部流量从 Cloudflare 直接进入你的内网服务,完全不经过公网端口。

1.4.1 前提条件#

  • 一个 Cloudflare 账号(免费版即可)
  • 域名 DNS 托管在 Cloudflare
  • 服务器能正常访问 Cloudflare 网络

1.4.2 安装 cloudflared#

Terminal window
# Linux (amd64)
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64
sudo mv cloudflared-linux-amd64 /usr/local/bin/cloudflared
sudo chmod +x /usr/local/bin/cloudflared
# 验证
cloudflared --version

1.4.3 登录并创建 Tunnel#

Terminal window
# 登录 Cloudflare 账号(会打开浏览器授权)
cloudflared tunnel login
# 创建 Tunnel(命名为 sillytavern)
cloudflared tunnel create sillytavern
# 查看已创建的 Tunnel
cloudflared tunnel list

登录成功后会在 ~/.cloudflared/ 下生成证书文件,Tunnel 创建后会生成唯一的 Tunnel ID 和凭据文件。

1.4.4 配置 Tunnel#

创建 ~/.cloudflared/config.yaml

~/.cloudflared/config.yaml
# Cloudflare Tunnel 配置 — 将流量转发到本地 SillyTavern 服务
tunnel: sillytavern
credentials-file: /home/youruser/.cloudflared/sillytavern.json
# 入口规则:所有请求转发到本地 8300 端口
ingress:
# 主服务
- hostname: sillytavern.yourdomain.com
service: http://localhost:8300
# 健康检查(Cloudflare 内部用,可以返回 200)
- service: http_status:404

1.4.5 DNS 路由#

Terminal window
# 将域名指向 Tunnel
cloudflared tunnel route dns sillytavern sillytavern.yourdomain.com

1.4.6 以系统服务运行#

Terminal window
# 安装为 systemd 服务
sudo cloudflared service install
# 启动
sudo systemctl enable --now cloudflared
# 查看状态
sudo systemctl status cloudflared
# 查看日志
sudo journalctl -u cloudflared -f

提示: 使用 Cloudflare Tunnel 时,Nginx 可以只绑定本地 127.0.0.1:8300,完全移除 80/443 端口的 listen 监听——因为 cloudflared 已在边缘层处理了 TLS 终结。此时甚至可以在 compose.yaml 中去掉 ports 映射,将网络模式设为 network_mode: "host" 或使用 Podman 内部网络。

1.4.7 Tunnel 方案 vs 传统反代方案#

对比项Cloudflare TunnelNginx 反代 + 公网 IP
是否需要公网 IP
是否需要域名
是否需要开放端口是(80/443)
HTTPS 证书管理自动(Cloudflare 处理)需手动(acme.sh)
访问速度经 Cloudflare 中转直连(通常更快)
安全性极高(不出公网)高(需自行加固)
适用场景内网部署、家庭宽带有公网 IP 的 VPS

1.5 环境变量与 .env 文件管理#

敏感信息(API Key、密码)不应该硬编码在配置文件中,也不应该提交到 Git 仓库。

1.5.1 创建 .env 文件#

Terminal window
# 在 Compose 文件同级目录创建 .env
touch .env
chmod 600 .env # 仅文件所有者可读写

.env 文件内容示例:

Terminal window
# SillyTavern 环境变量配置
# 警告:此文件包含敏感信息,切勿提交到 Git!
# SillyTavern 内置认证
SILLYTAVERN_BASIC_AUTH_ENABLED=true
SILLYTAVERN_BASIC_AUTH_USERNAME=admin
SILLYTAVERN_BASIC_AUTH_PASSWORD=your-strong-password-here
# 可选:覆盖 SillyTavern 默认配置
# SILLYTAVERN_PORT=8000

1.5.2 在 Compose 文件中引用#

services:
sillytavern:
image: ghcr.io/sillytavern/sillytavern:latest
env_file:
- .env

1.5.3 添加到 .gitignore#

确保 .env 不会被提交:

Terminal window
echo ".env" >> .gitignore

1.5.4 管理多个环境#

对于开发、测试、生产不同环境,可以维护多套 .env 文件:

Terminal window
.env.development # 开发环境
.env.staging # 测试环境
.env.production # 生产环境

compose.yaml 中指定:

env_file:
- .env.production

⬆ 返回目录

2. 数据备份与恢复#

数据是 SillyTavern 最宝贵的资产——角色卡可以再下,但几十万字的对话历史一旦丢失就无可挽回。

2.1 关键数据文件清单#

SillyTavern 的所有用户数据默认存储在 data/ 目录下(相对于安装目录或数据卷挂载点)。以下是需要备份的核心文件和目录:

目录/文件路径说明备份优先级
data/default-user/characters/角色卡文件(.json / .png⭐⭐⭐
data/default-user/chats/对话历史记录⭐⭐⭐
data/default-user/user.conf用户配置文件(界面设置、预设偏好)⭐⭐
data/default-user/settings.json全局设置(API 端点、UI 设置)⭐⭐
data/default-user/group chats/群聊历史(如果使用过群聊功能)⭐⭐
data/default-user/worlds/世界书(Lorebook)数据⭐⭐
data/default-user/vectors/向量数据库本地文件
config.yamlSillyTavern 主配置(API Key 等敏感信息)⭐⭐⭐
secrets.json加密存储的密钥(如果使用)⭐⭐⭐
chroma_data/ChromaDB 持久化数据⭐(如果使用向量化记忆)

截图辅助: 在你的 SillyTavern 安装目录下执行 ls -la data/default-user/ 可以看到上述目录结构。确认你的数据目录中有 characters/chats/ 这两个最重要的目录。

2.2 自动备份脚本#

以下是一个完整的备份脚本,包含 tar 打包、日期命名、保留最近 N 份备份等特性:

#!/bin/bash
# ============================================================
# backup-sillytavern.sh — SillyTavern 自动备份脚本
# 使用: chmod +x backup-sillytavern.sh && ./backup-sillytavern.sh
# ============================================================
# ---------- 配置区 ----------
# SillyTavern 数据目录(Compose 文件中的 data 卷路径)
ST_DATA_DIR="/home/youruser/sillytavern/data"
# ChromaDB 数据目录(如果使用)
CHROMA_DIR="/home/youruser/sillytavern/chroma_data"
# 备份存储目录
BACKUP_DIR="/home/youruser/backups/sillytavern"
# 保留最近多少份备份
RETENTION_COUNT=14
# 备份文件名前缀
PREFIX="sillytavern-backup"
# ---------------------------
# 创建备份目录
mkdir -p "$BACKUP_DIR"
# 生成时间戳
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
BACKUP_FILE="${BACKUP_DIR}/${PREFIX}_${TIMESTAMP}.tar.gz"
echo "[$(date +"%Y-%m-%d %H:%M:%S")] 开始备份..."
# 打包备份
# --exclude 排除不需要备份的缓存和临时文件
tar -czf "$BACKUP_FILE" \
--exclude="*.log" \
--exclude="node_modules" \
--exclude="cache" \
"$ST_DATA_DIR" \
${CHROMA_DIR:+ "$CHROMA_DIR"} 2>/dev/null
# 检查备份是否成功
if [ $? -eq 0 ]; then
BACKUP_SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
echo "[$(date +"%Y-%m-%d %H:%M:%S")] 备份完成: $BACKUP_FILE ($BACKUP_SIZE)"
else
echo "[$(date +"%Y-%m-%d %H:%M:%S")] 备份失败!"
exit 1
fi
# 清理旧备份,只保留最近 $RETENTION_COUNT 份
echo "[$(date +"%Y-%m-%d %H:%M:%S")] 清理旧备份(保留最近 ${RETENTION_COUNT} 份)..."
find "$BACKUP_DIR" -name "${PREFIX}_*.tar.gz" -type f | sort -r | tail -n +$((RETENTION_COUNT + 1)) | while read -r old_file; do
rm -f "$old_file"
echo " 已删除: $old_file"
done
echo "[$(date +"%Y-%m-%d %H:%M:%S")] 备份流程全部完成"

保存脚本后赋予执行权限:

Terminal window
chmod +x backup-sillytavern.sh
./backup-sillytavern.sh

2.3 定时备份配置#

方式一:cron(最通用,推荐)#

Terminal window
# 编辑 cron 任务
crontab -e
# 每天凌晨 3:00 执行备份,日志写入文件
0 3 * * * /home/youruser/scripts/backup-sillytavern.sh >> /home/youruser/backups/sillytavern/backup.log 2>&1

方式二:systemd timer(更精细的控制)#

创建 /etc/systemd/system/sillytavern-backup.service

[Unit]
Description=SillyTavern Backup Service
After=network.target
[Service]
Type=oneshot
ExecStart=/home/youruser/scripts/backup-sillytavern.sh
User=youruser

创建 /etc/systemd/system/sillytavern-backup.timer

[Unit]
Description=Daily SillyTavern backup at 3:00 AM
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
RandomizedDelaySec=300
[Install]
WantedBy=timers.target

激活 timer:

Terminal window
sudo systemctl daemon-reload
sudo systemctl enable --now sillytavern-backup.timer
# 验证
sudo systemctl list-timers | grep sillytavern

2.4 跨设备迁移流程#

将 SillyTavern 从旧服务器迁移到新服务器的完整步骤:

源服务器(旧)操作:

Terminal window
# 1. 停止 SillyTavern 服务,保证数据一致性
podman-compose down
# 2. 打包完整数据目录
tar -czf sillytavern-migrate.tar.gz \
data/ \
config.yaml \
.env
# 3. 复制到新服务器(rsync 推荐,支持断点续传)
rsync -avP sillytavern-migrate.tar.gz user@new-server:/path/to/destination/

目标服务器(新)操作:

Terminal window
# 1. 在目标服务器上克隆 SillyTavern(如果用 Git 方式)
git clone https://github.com/SillyTavern/SillyTavern.git
cd SillyTavern
# 2. 解压数据到正确位置
tar -xzf ../sillytavern-migrate.tar.gz
# 3. 启动服务验证
podman-compose up -d

迁移后检查清单:

  • 角色卡列表是否完整?→ 访问 /characters 页面
  • 对话历史是否可加载?→ 分别打开几个旧对话验证
  • API Key 是否保留了?→ 检查 config.yaml.env
  • 预设配置是否迁移?→ 检查角色回复风格是否与之前一致
  • 世界书内容是否正常?→ 在对话中触发世界书条目测试

2.5 rclone 备份到云存储#

异地备份是备份策略的最后一道防线。推荐使用 rclone 将备份同步到云存储。

Terminal window
# 安装 rclone
sudo apt install rclone # Ubuntu / Debian
sudo dnf install rclone # Fedora
# 交互式配置远程存储(以 Google Drive 为例)
rclone config
# 配置完成后,测试同步
rclone ls googledrive:/
# 将备份同步到 Google Drive
rclone sync /home/youruser/backups/sillytavern googledrive:sillytavern-backups/ \
--progress \
--verbose
# S3 兼容存储(如 MinIO、Backblaze B2、Cloudflare R2)示例
rclone sync /home/youruser/backups/sillytavern s3:bucket-name/sillytavern-backups/ \
--progress \
--verbose

可以将 rclone 同步命令加入到备份脚本末尾,实现备份 + 异地同步一步完成:

Terminal window
# 在 backup-sillytavern.sh 末尾添加
if command -v rclone &> /dev/null; then
echo "[$(date +"%Y-%m-%d %H:%M:%S")] 同步到云存储..."
rclone sync "$BACKUP_DIR" googledrive:sillytavern-backups/ --progress 2>>"$BACKUP_DIR/rclone.log"
fi

⬆ 返回目录

3. 性能优化#

3.1 长对话场景调优#

随着对话持续,上下文长度不断增长,会影响响应速度和质量。

Token 管理策略:

策略操作位置说明建议值
上下文限制(Context Limit)SillyTavern UI → 用户设置超过此长度的历史会被截断4096-8192
对话压缩(Chat Compression)SillyTavern UI → 高级设置自动对早期对话进行摘要压缩启用
动态上下文(Dynamic Context)SillyTavern UI → 高级设置根据实际对话长度自动调整上下文窗口启用(默认)
消息可见范围(Message Visible Range)对话界面右上角滑块控制当前可见的消息条数50-100

长对话的主动维护策略:

  1. 定期新建分支:当对话超过 100 轮,建议从关键节点创建分支(Fork),在新分支继续,避免历史过于臃肿。
  2. 手动摘要归档:在 SillyTavern 界面使用”对话摘要”功能(位于对话操作菜单中),AI 会生成当前对话摘要,归档后可以安全清理早期历史。
  3. 使用向量化记忆替代长上下文:进阶篇介绍的向量化记忆(ChromaDB)可以将关键信息存入向量数据库,让你在清理对话历史后仍能保持角色记忆一致性。

3.1.1 上下文长度设置参考#

Terminal window
# 在 SillyTavern settings.json 或 config.yaml 中
# 不建议超过模型的 max context(可在模型提供商文档中查询)
# DeepSeek: 64K
# Claude Sonnet 4: 200K
# OpenRouter 部分模型: 128K
contextLimit: 8192
chatCompression: true
dynamicContext: true

3.2 ChromaDB 向量数据库清理与维护#

如果启用了向量化记忆(进阶篇第 3 章),ChromaDB 的向量数据会持续增长。

3.2.1 查看 ChromaDB 数据量#

Terminal window
# 查看 ChromaDB 数据目录大小
du -sh /home/youruser/sillytavern/chroma_data/
# 查看容器内 ChromaDB 数据量
podman exec sillytavern-chroma du -sh /chroma/chroma

3.2.2 清理过期向量#

在 SillyTavern 界面的 Vector Storage 管理页面(扩展 → Vector Storage),你可以:

  • 查看每个角色名下的向量数量
  • 删除特定角色的所有向量
  • 手动触发向量重建

3.2.3 重建 ChromaDB 索引#

如果向量数据损坏或体积过大:

Terminal window
# 停止相关容器
podman-compose stop chromadb
# 备份旧的向量数据
mv /home/youruser/sillytavern/chroma_data /home/youruser/sillytavern/chroma_data_old
# 重建目录
mkdir -p /home/youruser/sillytavern/chroma_data
# 重启 ChromaDB(会自动创建新数据库)
podman-compose up -d chromadb
# 确认新数据库正常运行后,删除旧备份
rm -rf /home/youruser/sillytavern/chroma_data_old

提示: 删除旧 ChromaDB 数据不会影响角色卡和对话历史。向量化记忆是附加功能,丢失后只需在 SillyTavern 中重新导入并重新生成向量即可恢复。

3.3 多用户共享服务器方案#

如果多个人需要共用一台 SillyTavern 服务器,有两种方案:

3.3.1 多实例端口隔离#

每个用户运行独立的 SillyTavern 实例,通过不同端口访问:

# compose.yaml 多用户示例(片段)
services:
sillytavern-user1:
image: ghcr.io/sillytavern/sillytavern:latest
container_name: sillytavern-user1
ports:
- "127.0.0.1:8301:8000"
volumes:
- ./data-user1:/home/node/app/data
env_file:
- .env.user1
sillytavern-user2:
image: ghcr.io/sillytavern/sillytavern:latest
container_name: sillytavern-user2
ports:
- "127.0.0.1:8302:8000"
volumes:
- ./data-user2:/home/node/app/data
env_file:
- .env.user2

Nginx 反代配置多条 location 或不同子域名:

# Nginx 多用户反代
server {
listen 443 ssl http2;
server_name sillytavern.example.com;
# 用户1
location /user1/ {
proxy_pass http://127.0.0.1:8301/;
proxy_set_header Host $host;
# ... WebSocket 等其余配置同上
}
# 用户2
location /user2/ {
proxy_pass http://127.0.0.1:8302/;
proxy_set_header Host $host;
# ... 同上
}
}

3.3.2 SillyTavern 多用户模式#

SillyTavern 支持内置多用户(需要手动启用),但功能较基础,适合小团队共享:

# config.yaml 启用多用户
multiUser: true
enableUserAccounts: true

启用后在登录页面可以注册多个账号,每个用户有独立的数据目录。不过多实例方案隔离性更好,推荐在正式环境中使用。

⬆ 返回目录

4. 安全加固#

将 SillyTavern 暴露到公网前,必须做好安全防护。以下措施按重要性排列。

4.1 认证与访问控制(双层防护)#

第一层:SillyTavern 内置 Basic Auth#

config.yaml 中启用:

config.yaml
basicAuth:
enabled: true
users:
- username: "admin"
password: "your-strong-password-here"

或在 .env 环境变量中:

.env
SILLYTAVERN_BASIC_AUTH_ENABLED=true
SILLYTAVERN_BASIC_AUTH_USERNAME=admin
SILLYTAVERN_BASIC_AUTH_PASSWORD=your-strong-password-here

第二层:Nginx 层 Basic Auth(推荐,更可控)#

Terminal window
# 生成密码文件
sudo apt install apache2-utils # Ubuntu / Debian
sudo dnf install httpd-tools # Fedora
# 创建用户(会提示输入密码)
sudo htpasswd -c /etc/nginx/.htpasswd sillytavern-admin
# 后续添加更多用户(去掉 -c 参数)
sudo htpasswd /etc/nginx/.htpasswd another-user

在 Nginx 配置中添加 auth 指令:

# 在 server 块或 location 块中添加
location / {
auth_basic "SillyTavern - 请输入用户名和密码";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://sillytavern_backend;
# ... 其余反代配置同上
}

修改配置后重载 Nginx:

Terminal window
sudo nginx -t # 检查配置语法
sudo systemctl reload nginx

提示: 启用 Nginx Basic Auth 后,需要在 SillyTavern 内置认证之上再加一层密码。推荐两者同时启用——即使一层被绕过,还有另一层保护。

4.2 API Key 保护#

API Key 是连接 AI 后端的凭证,泄露后可能被恶意使用产生高额费用。

安全准则:

措施操作说明
环境变量隔离.env 中设置,不硬编码避免 API Key 出现在配置文件中
文件权限限制chmod 600 .env仅文件所有者可读写
不提交 Gitecho ".env" >> .gitignore防止 Key 泄露到远程仓库
轮换策略定期在 API 提供商后台更换 Key每 3-6 个月更换一次
Terminal window
# 检查 .env 文件权限
ls -la .env
# 应该显示: -rw------- (600)
# 如果不正确,修复
chmod 600 .env
# 搜索是否有 API Key 被硬编码在配置文件中
grep -r "sk-" config.yaml 2>/dev/null && echo "警告: config.yaml 中包含 API Key!"

4.3 公网暴露风险评估#

以下端口在 Linux 服务器上应该检查是否被意外暴露:

Terminal window
# 查看所有监听端口
ss -tlnp
# 检查 SillyTavern 端口是否只绑定在 127.0.0.1
# 应该显示: 127.0.0.1:8300,而不是 0.0.0.0:8300

端口暴露风险矩阵:

情况风险等级说明
仅 Nginx 暴露 443🟢 低通过 HTTPS + 认证,安全
直接暴露 8000 (SillyTavern)🔴 极高API Key、对话数据完全暴露
暴露 8300 但通过 Basic Auth🟡 中密码质量决定安全程度
Cloudflare Tunnel 仅 CF 接入🟢 低无暴露端口,最安全

4.4 fail2ban 配置(防暴力破解)#

fail2ban 可以监控 Nginx 的访问日志,对多次认证失败的 IP 进行临时封禁。

4.4.1 安装 fail2ban#

Terminal window
# Ubuntu / Debian
sudo apt install fail2ban
# Fedora
sudo dnf install fail2ban
# 启用开机自启
sudo systemctl enable fail2ban

4.4.2 创建 Nginx Auth jail#

创建 /etc/fail2ban/jail.local

/etc/fail2ban/jail.local
# fail2ban 本地配置文件,覆盖 defaults
[DEFAULT]
# 封禁时间:1 小时(秒)
bantime = 3600
# 发现时间窗口:10 分钟
findtime = 600
# 在 findtime 内最多尝试次数
maxretry = 5
# 忽略本机 IP
ignoreip = 127.0.0.1/8 ::1
# ============================================
# SillyTavern Nginx 认证防护
# ============================================
[sillytavern-auth]
enabled = true
# 监控 Nginx 访问日志
logpath = /var/log/nginx/access.log
# 使用 Nginx auth 过滤器
filter = nginx-http-auth
# 覆盖全局配置
port = http,https
# 封禁后发送邮件通知(可选)
# action = %(action_mwl)s

4.4.3 创建自定义过滤器(可选)#

如果内置的 nginx-http-auth 过滤器不够精确,可以创建 /etc/fail2ban/filter.d/sillytavern-auth.conf

/etc/fail2ban/filter.d/sillytavern-auth.conf
[Definition]
failregex = ^<HOST> - .* "(GET|POST) / HTTP/.*" 401 .*$
^<HOST> - .* "(GET|POST) /api.* HTTP/.*" 401 .*$
ignoreregex =

4.4.4 启动与测试#

Terminal window
# 启动 fail2ban
sudo systemctl start fail2ban
# 查看 SillyTavern jail 状态
sudo fail2ban-client status sillytavern-auth
# 手动测试正则匹配
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/sillytavern-auth.conf
# 查看当前封禁列表
sudo fail2ban-client banned

⬆ 返回目录

5. 故障排查手册#

本章以表格形式列出最常见的问题及其解决方案,方便快速定位。

5.1 连接后端失败:HTTP 错误码速查#

错误码现象原因解决方案诊断命令
401 Unauthorized提示”认证失败”API Key 无效或已过期在 API 提供商后台重新生成 Key,更新 .envcurl -s -o /dev/null -w "%{http_code}" https://api.deepseek.com/v1/models -H "Authorization: Bearer YOUR_KEY"
403 Forbidden提示”无权访问”API Key 权限不足或账号余额为 0检查账号余额,检查 API Key 权限范围登录 API 提供商控制台查看余额
429 Too Many Requests响应变慢后出现”请求过于频繁”触发了 API 速率限制降低请求频率,增加 SillyTavern 请求间隔(设置 → API → Request Interval 设为 1-2 秒)grep "429" /home/youruser/sillytavern/data/default-user/logs/*.log
500 Internal Server ErrorAPI 返回空或无意义内容后端模型服务内部错误稍后重试,查看模型提供商的官方状态公告检查 API 提供商官网或账号控制台了解服务状态
502 Bad GatewayNginx 返回 502SillyTavern 服务未启动或端口错误检查容器是否运行,检查 Compose 端口映射podman pspodman logs sillytavern

5.2 响应质量异常#

现象原因解决方案诊断方法
回复被截断(不完整)上下文限制(Context Limit)过低增加 Context Limit(4096 → 8192),检查模型的 Max Tokens 设置在 SillyTavern UI 查看当前上下文使用量
回复乱码/含奇怪符号编码问题,或模型输出层被截断检查 SillyTavern 编码设置(确保 UTF-8),尝试切换预设尝试用同一模型在 API 官方测试页生成相同提示词
角色偏移(OOC,角色突然说人话)上下文窗口被挤占,早期角色设定被弹出启用”Chat Compression”(对话压缩),或使用”Author’s Note”固定角色设定检查当前上下文使用百分比
回复质量逐渐下降长对话中上下文窗口尾部溢出创建新分支或启用摘要归档查看对话轮次和 Token 使用量统计

5.3 性能迟缓诊断#

症状可能原因诊断步骤修复方法
UI 响应慢(页面加载卡顿)服务器 CPU/内存不足htop 查看 CPU 和内存使用率增加服务器资源,减少并发用户数
生成回复慢(AI 思考时间长)模型推理速度瓶颈检查后端 API 延迟(在 SillyTavern UI 查看 “Response Time”)升级 API 套餐(更快的推理优先级),或切换到更小的模型
磁盘 IO 高日志文件过大或 ChromaDB 频繁读写iostat -x 1 查看磁盘利用率,du -sh data/default-user/logs/ 检查日志大小清理日志,增大 ChromaDB 批处理间隔
内存使用持续增长长时间运行未重启podman stats sillytavern 查看容器内存使用趋势定期重启容器(每周一次),或增加 --memory 限制
Terminal window
# 资源监控命令速查
htop # 实时 CPU/内存/进程
glances # 综合系统监控
podman stats # 容器资源使用统计
podman stats --no-stream # 单次快照
du -sh data/default-user/logs/ # 日志占用的磁盘空间
journalctl -u nginx --since "1 hour ago" | grep "error" # Nginx 错误日志

5.4 Podman 常见问题#

现象原因解决方案诊断命令
容器无法启动配置错误、端口冲突或镜像损坏查看容器日志定位错误podman logs sillytavern
端口已被占用其他服务使用了同一端口修改 compose.yaml 中的端口映射或停止冲突进程ss -tlnp | grep 8300
容器间网络不通网络配置或 Pod 模式问题检查容器网络模式,使用 network inspectpodman network inspect podman-default
SELinux 阻止卷挂载SELinux 安全上下文不匹配使用 chcon 更改安全上下文,或添加 :Z 标签ls -Z data/sudo chcon -Rt container_file_t data/
存储空间不足日志/镜像/卷积累清理未使用的镜像和卷podman system prune -af(谨慎使用,会删除未使用的镜像和卷)

SELinux 快速修复:

Terminal window
# 如果 Podman 因为 SELinux 拒绝挂载卷,添加 :Z 后缀
# 在 compose.yaml 中:
# volumes:
# - ./data:/home/node/app/data:Z
# 或在运行时添加 :Z
podman run -v ./data:/home/node/app/data:Z ...
# 也可以临时设置为 Permissive 模式(不推荐生产环境)
sudo setenforce 0

5.5 日志查看与诊断命令速查#

日志来源路径/命令常用参数
SillyTavern 应用日志data/default-user/logs/ 目录下tail -f data/default-user/logs/*.log
SillyTavern 容器日志podman logs sillytavernpodman logs -f --tail 100 sillytavern
Nginx 访问日志/var/log/nginx/access.logtail -f /var/log/nginx/access.log | grep -v "health"
Nginx 错误日志/var/log/nginx/error.logtail -f /var/log/nginx/error.log
systemd 系统日志journalctljournalctl -u sillytavern-backup.service -f
fail2ban 日志/var/log/fail2ban.logtail -f /var/log/fail2ban.log
Cloudflared 日志journalctl -u cloudflaredjournalctl -u cloudflared -f --tail 50
Podman 事件podman eventspodman events --since 5m

快速诊断三板斧:

Terminal window
# 1. 检查服务是否运行
podman-compose ps
# 2. 检查 SillyTavern 是否有报错
podman logs sillytavern --tail 50
# 3. 检查 Nginx 是否能正常转发
curl -sI https://sillytavern.yourdomain.com | head -5

⬆ 返回目录

6. 更新与维护#

6.1 Git Pull 更新流程#

如果使用 Git 克隆方式安装的 SillyTavern(对应入门篇的”方式二”),更新步骤如下:

Terminal window
# 重要:更新前先备份!
# 立即执行一次备份脚本
./backup-sillytavern.sh
# 或手动备份关键数据目录
cp -r data data_backup_$(date +"%Y%m%d_%H%M%S")
# 拉取最新代码
git pull origin main
# 更新 Node.js 依赖(SillyTavern 依赖可能变更)
npm install
# 重启服务
podman-compose restart sillytavern
# 验证更新后版本
# 在 SillyTavern UI 底部状态栏可以查看当前版本号

提示: 非必要不追新版本。建议在 SillyTavern 官方发布 Release 后等待 1-2 天,确认没有重大 Bug 再更新。关注 GitHub Releases 页面获取更新公告。

如果使用 Podman Compose 方式(推荐的生产方式):

Terminal window
# Compose 方式更新
podman-compose pull # 拉取最新镜像
podman-compose up -d # 重建容器

6.2 版本锁定#

生产环境建议锁定在某个稳定版本,避免意外升级引入不稳定变更:

Terminal window
# 查看所有可用版本标签
git tag -l | sort -V
# 锁定到特定版本(例如 1.12.6)
git checkout tags/1.12.6 -b stable-1.12.6
# 查看当前版本
git describe --tags

Compose 方式也建议指定具体版本号,而不是使用 latest

# compose.yaml 中指定具体版本
image: ghcr.io/sillytavern/sillytavern:1.12.6

6.3 版本回退方法#

如果更新后出现严重问题,回退到之前版本:

Terminal window
# Git 方式回退
# 1. 停止服务
podman-compose down
# 2. 回退到之前版本
git checkout tags/1.12.5
# 3. 重新安装依赖并启动
npm install
podman-compose up -d
# Compose 方式回退
# 1. 修改 compose.yaml 中镜像标签为旧版本
# image: ghcr.io/sillytavern/sillytavern:1.12.5
# 2. 重新创建容器
podman-compose up -d

提示: 如果更新同时导致数据不兼容,可能需要同时恢复之前备份的 data/ 目录。这也是每次更新前必须备份的原因。

6.4 社区资源#

资源链接说明语言
官方文档https://docs.sillytavern.app/官方部署、配置、扩展文档EN
GitHub Issueshttps://github.com/SillyTavern/SillyTavern/issues报告 Bug、搜索已知问题EN
GitHub Releaseshttps://github.com/SillyTavern/SillyTavern/releases版本发布说明和更新日志EN
官方 Discordhttps://discord.gg/sillytavern社区讨论、技术支持EN 为主
Reddit r/SillyTavernAIhttps://www.reddit.com/r/SillyTavernAI/用户交流、角色卡分享EN
Chub.aihttps://www.chub.ai/角色卡社区(最大)EN
NGA SillyTavern 讨论https://bbs.nga.cn/thread.php?fid=-547859中文社区讨论中文

6.5 后续学习路径#

完成本系列三篇文章后,你已经从零到掌握 SillyTavern 的完整使用链路。如果你希望继续深入,以下方向值得探索:

工程方向:

  • Kubernetes 编排:将 SillyTavern 部署到 K3s/K8s 集群,实现自动扩缩容和高可用
  • CI/CD 流水线:使用 GitHub Actions 自动化备份、镜像构建、自动部署
  • 监控告警:部署 Prometheus + Grafana 监控 SillyTavern 的 API 延迟和资源使用

AI 方向:

  • 提示工程(Prompt Engineering):深入学习 System Prompt 设计和 Chain-of-Thought 技术
  • 模型微调(Fine-tuning):使用 LoRA/QLoRA 对开源模型进行角色扮演微调
  • RAG 增强检索:为 SillyTavern 搭建自定义知识库 RAG 管道

创作方向:

  • 角色卡设计艺术:从对话示例撰写到角色弧光设计的完整方法论
  • 世界书构建:为你的原创世界观构建完整的 Lorebook 体系
  • SillyTavern 扩展开发:学习编写自定义 SillyTavern 扩展插件

本系列至此完结。从入门到进阶再到生产运维,希望这三篇文章能帮助你充分发挥 SillyTavern 的潜力。如果在部署中遇到问题,先查阅故障排查手册,依然无法解决再到社区资源中寻求帮助。

⬆ 返回目录

SillyTavern 完全指南(三):运维篇 — 生产部署与日常维护
https://blog.syomega.top/posts/sillytavern-operations/
作者
酱w
发布于
2026-05-18
许可协议
CC BY-NC-SA 4.0