Docker 部署与运维
如果你不想装 Python / uv / 一堆依赖,直接用 Docker 镜像一行起服。独立 Docker 部署把 .env 与 .data/ 放在宿主机工作目录中,升级容器不会丢失。
mkdir -p ~/afterglow && cd ~/afterglow
# 拿一个 compose 文件即可,约 50 行
curl -O https://raw.githubusercontent.com/kldhsh123/Afterglow/main/docker/compose.standalone.yaml
mv compose.standalone.yaml compose.yaml
# 首次创建语言和容器访问配置;已有 .env 请编辑对应字段
if [ ! -f .env ]; then
printf '%s\n' 'XUWEN_LANGUAGE=zh-CN' 'CONFIG_UI_LOCALHOST_ONLY=false' > .env
fi
docker compose pull # 从 GHCR 拉公开镜像(amd64 / arm64 都有)
docker compose up -d容器首次启动会检测到缺少身份、模型等关键配置,进入配置向导首次模式。看一次性 setup token:
docker compose logs backend | grep -iE "token|/config/"浏览器打开 http://localhost:8000/config/,把 token 粘进向导第 1 步,8 步走完即生效。向导写入的 .env 直接落到 ~/afterglow/.env,备份在 .env-backups/,重启即用。
本页示例在首次启动前创建含 XUWEN_LANGUAGE=zh-CN 和 CONFIG_UI_LOCALHOST_ONLY=false 的宿主 .env,所以启动提示为中文且容器外可访问向导;已有 .env 时请手动核对这两个字段。完成向导后执行 docker compose restart backend 加载配置。后端未设置语言时默认英文,改为 XUWEN_LANGUAGE=en 可切换英文;页面语言下拉框独立。
独立 Compose 读取挂载目录中的 .env;仅在宿主命令前写 XUWEN_LANGUAGE=zh-CN docker compose up -d 不会把该变量传入容器。CLI 命令可用 --language zh-CN / --language en 单独选择输出语言,示例见下文。
完成后目录结构:
~/afterglow/
├── compose.yaml
├── .env ← 向导生成,含完整注释
├── .env.example ← 从镜像拷出的模板
├── .env-backups/ ← 历次配置变更
└── .data/
├── lancedb/ ← 向量库
├── persona/ ← 人格卡片
├── stickers/ ← 表情包
├── images/ ← 图片缓存
└── uploads/ ← 配置向导上传暂存日常运维命令
# 看日志
docker compose logs -f backend
# 改了 .env 必须重启(pydantic-settings 不监听文件变化)
docker compose restart backend
# 拉新版镜像 + 滚动更新
docker compose pull && docker compose up -d
# 导入聊天记录(把待导入 JSON 放到挂载目录下任何子路径)
docker compose run --rm backend \
python -m xuwen.ingestion.cli import .imports/qq.json --language zh-CN
# 可选:离线导入历史图片(目录内可包含多个 JSON/JSONL 和任意层级图片目录)
docker compose run --rm backend \
python -m xuwen.ingestion.cli import-images .imports/export-dir --plugin afterglow_v1 --language zh-CN
# 大库建索引
docker compose run --rm backend python -m xuwen.ingestion.cli index --language zh-CN
# 临时停 / 完全停(数据保留)
docker compose stop
docker compose down
# 进容器排错
docker compose exec backend bash前端怎么办
镜像包含后端与配置向导,不包含主聊天前端。前端按快速开始运行 pnpm dev, 或自行用 Nginx 托管 frontend/dist。后端容器对外暴露 8000,前端请求发送到该端口。
与源码部署互操作
完全可以并存,只要别同时跑(端口冲突)。但两种模式默认使用不同目录:普通源码部署读取仓库里的 backend/.env 与 backend/.data/,下面的独立 Docker 部署读取 ~/afterglow/.env 与 ~/afterglow/.data/。
如果希望两种模式复用同一份配置和数据,可以让源码进程也从 Docker 工作目录启动:
# 今天用源码模式
cd ~/afterglow
XUWEN_LANGUAGE=zh-CN uv run --project /path/to/Afterglow/backend \
uvicorn xuwen.chat_api.app:create_app --factory --reload
# 关掉后明天换 Docker
docker compose up -d把 /path/to/Afterglow 替换为源码仓库路径。这样两边都会读取 ~/afterglow/.env 与 ~/afterglow/.data/;如果仍按快速开始从仓库的 backend/ 启动,则需要自行复制或迁移这两个目录。
几个 Docker 模式特有的注意点
- 首次冷启动会自动注入
CONFIG_UI_LOCALHOST_ONLY=false到挂载目录的.env,因为容器外浏览器访问/config/时请求源 IP 是 docker 网桥,会被 localhost-only 拒。配置完成后想重新收紧的话手动改回true即可。 - 配置向导写入是 atomic rename,直接落到宿主机
.env——不是写在容器层,重启不丢。 - 容器 entrypoint 会动态对齐 uid/gid 到挂载目录所有者,避免 WSL drvfs / Linux 原生 / NFS 等跨 uid 场景下向导写文件
EPERM报错。 - 改
.env后必须docker compose restart,与源码模式一致——pydantic-settings只在启动时加载。
故障排查
| 现象 | 大概率原因 | 处理 |
|---|---|---|
向导 PUT /config/values 500 + EPERM | 挂载目录 uid 与容器内不一致,且 entrypoint 没对齐成功 | 看启动日志有没有 [entrypoint] 调整 afterglow 用户匹配;没有就贴日志反馈 issue |
| LanceDB deprecation warning 刷屏 | 上游 lance crate 的弃用提示,不影响功能 | .env 加 RUST_LOG=lance=error 屏蔽 |