核心环境变量
本页收录部署与日常运维会实际改动的环境变量:服务监听、数据库、密钥、限额、外部服务对接、Compose 编排层与沙箱 sidecar。控制系统内部行为(并发、重试、批量大小、读循环节奏等)的调优项不在本页,见高级调优环境变量。
使用官方 Docker Compose 部署时,绝大多数变量已经由 compose 文件填好合理值,你通常只需要在 .env 里提供三个必设项:POSTGRES_PASSWORD、REDIS_PASSWORD、JWT_SECRET。本页其余变量按需查阅即可。
所有时长类变量(如 ACCESS_TTL、REFRESH_TTL)使用 Go duration 格式:数字加单位后缀,支持 s(秒)、m(分钟)、h(小时),可以组合(如 1h30m)。没有 d(天)单位,30 天要写成 720h。
1. 服务基础
| 变量 | 默认值 | 说明 |
|---|---|---|
AIVORY_LISTEN | :8787 | 服务监听地址。默认监听所有网卡的 8787 端口;只想绑定本机时可写 127.0.0.1:8787。 |
AIVORY_ENV | development | 运行环境标识。设为 production 等非 dev 值后会触发部署级安全校验(见下文 JWT_SECRET 的启动规则)。 |
STATIC_DIR | (空) | 指向已构建的 SPA 前端目录时,API 进程会在同一端口同源伺服前端页面。生产镜像已内置该目录,无需设置。 |
怎么选/常见坑:生产部署务必把 AIVORY_ENV 设为 production,否则一部分只在部署环境生效的安全校验不会启用。STATIC_DIR 只在你自行构建前端、且想让 API 进程直接托管静态文件时才需要;用官方镜像时不要动它。前端与 API 同源(单容器同时服务 SPA 和 /api)是推荐形态,能省去跨域配置。
2. 数据库与缓存
| 变量 | 默认值 | 说明 |
|---|---|---|
DATABASE_URL | ./data/aivory.db?_pragma=journal_mode(WAL)&_pragma=busy_timeout(5000) | 数据库连接串。默认是 SQLite 文件路径(带 WAL 与 busy_timeout 参数);以 postgres:// 开头时切换为 PostgreSQL。 |
REDIS_URL | (空) | Redis 连接串。留空时使用进程内缓存与队列;设置后启用 Redis 缓存、任务队列与流式恢复。 |
QDRANT_URL | (空) | Qdrant 向量库地址。留空时禁用向量检索,RAG 走全文注入回退。 |
QDRANT_API_KEY | (空) | 访问 Qdrant 的 API key,与 Qdrant 服务端配置一致即可。 |
DATABASE_URL 的两种形态示例:
# SQLite(单机小规模,详见 SQLite 模式文档)
DATABASE_URL="./data/aivory.db?_pragma=journal_mode(WAL)&_pragma=busy_timeout(5000)"
# PostgreSQL(compose 部署默认形态)
DATABASE_URL="postgres://aivory:你的密码@postgres:5432/aivory"
DATABASE_URL 是否为 postgres:// 前缀,同时也是「是否为部署环境」判定的输入之一:一旦连接 PostgreSQL,启动时就会强制要求 JWT_SECRET(见下节)。另外,SQLite 与 PostgreSQL 之间没有自动数据迁移,切换前请先通过备份与迁移导出数据。
怎么选/常见坑:单人或小团队自用可以走 SQLite 模式,零外部依赖;多用户生产环境建议 PostgreSQL + Redis + Qdrant 全套(compose 默认即此)。REDIS_URL 留空时流式恢复等依赖队列的能力退化为进程内实现,多副本部署时必须配置 Redis。QDRANT_URL 留空并不影响知识库功能可用,只是检索质量退化为全文注入,文档量大时效果和 token 消耗都会变差。
3. 安全与会话
| 变量 | 默认值 | 说明 |
|---|---|---|
JWT_SECRET | (空) | 签发访问/刷新令牌的密钥。启动校验规则见下方警告。 |
ACCESS_TTL | 30m | 访问令牌有效期,Go duration 格式。 |
REFRESH_TTL | 720h | 刷新令牌有效期,默认 720 小时即 30 天。 |
ALLOWED_ORIGINS | http://localhost:5173,http://127.0.0.1:5173 | 允许跨域访问 API 的 origin 白名单,逗号分隔。仅前后端分离部署需要;单容器同源部署无需设置。 |
开发环境下未设置 JWT_SECRET 时,服务会自动生成一个随机临时密钥,每次重启都会导致全部登录会话失效。当系统「看起来是部署环境」(AIVORY_ENV 非 dev 值,或 DATABASE_URL 是 PostgreSQL)时,必须显式设置一个不少于 32 字符的密钥,否则服务拒绝启动。生成方式示例:
openssl rand -base64 48
密钥一旦投产不要随意更换:更换后所有用户的登录态立即失效。
怎么选/常见坑:ACCESS_TTL 调短能降低令牌泄露的窗口,但会增加刷新频率;REFRESH_TTL 决定用户「多久没来需要重新登录」。ALLOWED_ORIGINS 是新手常踩的坑:同源部署(推荐)完全不用配;只有把前端单独部署到另一个域名时才需要把该前端 origin 加进来,写完整的 scheme://host[:port],不要带路径和末尾斜杠。
4. 存储与限额
| 变量 | 默认值 | 说明 |
|---|---|---|
UPLOAD_DIR | ./data/uploads | 用户上传文件的存放目录。 |
ARTIFACT_DIR | ./data/artifacts | 生成产物(代码运行输出文件等)的存放目录。 |
BACKUP_DIR | ./data/backups | 备份文件的存放目录。 |
MAX_UPLOAD_BYTES | 52428800 | 单文件上传硬上限,默认 50MB。管理员后台还可在此上限内按图片/文件分别收紧。 |
MAX_BACKUP_BYTES | 21474836480 | 备份导入的大小上限,默认 20GiB。 |
DAILY_MESSAGE_LIMIT | 200 | 每用户每日消息条数上限。 |
IMAGE_DAILY_LIMIT | 30 | 每用户每日图片生成次数上限。 |
怎么选/常见坑:三个目录默认都在 ./data 下,compose 部署时对应宿主机的 DATA_DIR 挂载卷,请确保该卷有足够磁盘空间并纳入备份策略。MAX_UPLOAD_BYTES 是服务端硬上限,管理后台的图片/文件限额只能比它更小,不能放大;如果调大这里,还要同步调大反向代理的请求体上限(如 Nginx 的 client_max_body_size),否则请求会先被代理拦下,见反向代理。DAILY_MESSAGE_LIMIT 与 IMAGE_DAILY_LIMIT 是全局默认,针对单个用户的配额调整在用户与配额里操作。
5. 外部服务
| 变量 | 默认值 | 说明 |
|---|---|---|
SEARCH_PROVIDER | (空) | 联网搜索后端,如 serper。也可以在管理后台配置。 |
SEARCH_API_KEY | (空) | 搜索后端的 API key。 |
SEARCH_BASE_URL | (空) | 搜索后端的自定义地址(自建或代理网关时使用)。 |
EMBEDDING_BASE_URL | (空) | 嵌入(embedding)服务的 API 地址,OpenAI 兼容接口。 |
EMBEDDING_API_KEY | (空) | 嵌入服务的 API key。 |
EMBEDDING_MODEL | text-embedding-3-small | 嵌入模型名称。 |
EMBEDDING_DIM | 1536 | 嵌入向量维度。 |
MINERU_API_URL | (空) | MinerU 服务地址,用于扫描版 PDF 的 OCR 解析。compose 里默认填 https://mineru.net。 |
MINERU_API_KEY | (空) | MinerU 的 API key。 |
SANDBOX_BASE_URL | (空) | 代码沙箱 sidecar 的地址。compose 里默认 http://sandbox:8000。 |
SANDBOX_API_KEY | (空) | 与沙箱 sidecar 通信的共享密钥。compose 里默认使用共享值 aivory-bundled-sandbox。 |
ENABLE_MOCK_PROVIDER | false | 由 compose 传入,启用内置演示模型(无需真实模型 API 即可体验界面)。 |
向量库集合按固定维度建立,EMBEDDING_DIM 与 EMBEDDING_MODEL 实际输出维度不一致时向量写入与检索都会出错。更换嵌入模型时务必同步修改该值,且已入库的旧向量与新维度不兼容,需要重建知识库索引。默认的 text-embedding-3-small 对应 1536 维。
怎么选/常见坑:搜索与嵌入服务都不是必需项,不配置时对应功能(联网搜索、向量检索)自动降级或不可用。SEARCH_* 支持在管理后台配置,环境变量与后台二选一即可,后台配置的好处是改动不需要重启容器,见管理后台概览。沙箱两个变量留空则代码执行功能不可用;用官方 compose 时 sidecar 已随套件启动,不需要手工设置,但如果沙箱暴露在非内网环境,务必把 SANDBOX_API_KEY 从共享默认值改为随机强密钥(sidecar 侧同步修改,见第 8 节),详见代码沙箱部署。ENABLE_MOCK_PROVIDER 仅用于演示和验证部署,生产环境保持 false。
6. OAuth 多域名
| 变量 | 默认值 | 说明 |
|---|---|---|
OAUTH_CALLBACK_BASE_URL | (空) | 多域名部署时,固定 OAuth 回调所使用的唯一 scheme://host。 |
OAUTH_RETURN_ORIGINS | (空) | 跨域登录完成后允许跳回的 origin 白名单,逗号分隔。 |
怎么选/常见坑:单域名部署这两项都不需要设置。当同一套服务通过多个域名访问,而 OAuth 提供商(如 GitHub/Google)只允许注册固定的回调地址时,把 OAUTH_CALLBACK_BASE_URL 设为你在提供商处注册的那个域名;用户从其它域名发起登录后要能跳回原域名,就把那些域名加进 OAUTH_RETURN_ORIGINS。白名单外的 origin 不会被跳转,这是防开放重定向的安全设计,漏配会表现为「登录成功但回不到原页面」。
7. Compose 编排层变量(.env)
以下变量写在 compose 项目根目录的 .env 文件里,由 docker-compose.yml 展开注入各容器,不是 Aivory 进程直接读取的配置:
| 变量 | 默认值 | 说明 |
|---|---|---|
IMAGE_OWNER | hjxwz123 | 镜像所有者,拼接为 ghcr.io/<IMAGE_OWNER>/aivory-app 等镜像名。使用自建镜像仓库时修改。 |
IMAGE_TAG | latest | 镜像标签。生产环境建议锁定具体版本号(如 2.2.0)而非 latest。 |
POSTGRES_USER | aivory | PostgreSQL 用户名。 |
POSTGRES_PASSWORD | (必设) | PostgreSQL 密码,无默认值,首次部署必须填写。 |
POSTGRES_DB | aivory | PostgreSQL 数据库名。 |
REDIS_PASSWORD | (必设) | Redis 密码,无默认值,首次部署必须填写。 |
QDRANT_API_KEY | aivory-internal-qdrant | Qdrant 的 API key,app 容器与 qdrant 容器共用同一个值。 |
JWT_SECRET | (必设) | 直接透传给 app 容器,规则见第 3 节。 |
DATA_DIR | ./data | 宿主机数据目录,挂载给各容器持久化数据。 |
怎么选/常见坑:POSTGRES_PASSWORD、REDIS_PASSWORD、JWT_SECRET 三项没有默认值,.env 里漏填任何一个都会导致启动失败,这是有意为之的防呆设计。POSTGRES_* 修改后 compose 会用它们拼出 app 容器的 DATABASE_URL,不需要再手工写连接串。QDRANT_API_KEY 虽有默认值,但只要 Qdrant 端口没有暴露到 compose 网络之外就是安全的;如果你把 Qdrant 单独对外暴露,请改为强随机值。DATA_DIR 指向的目录就是全部持久化状态(数据库、上传、向量、备份),迁移主机时整目录拷走即可,详见 Docker Compose 部署。
8. 沙箱 sidecar 运维变量
以下变量作用于 aivory-sandbox-sidecar 容器(代码沙箱的控制面),与第 5 节 app 侧的 SANDBOX_BASE_URL/SANDBOX_API_KEY 是两端配置。sidecar 通过 Docker 为每个会话拉起隔离容器执行代码,整体架构见代码沙箱部署,用户侧功能见 Python 沙箱。
镜像与容器资源
| 变量 | 默认值 | 说明 |
|---|---|---|
SANDBOX_IMAGE | aivory-sandbox:latest | 会话容器使用的运行时镜像。 |
SANDBOX_NETWORK | none | 会话容器的网络模式。默认完全断网;设为 bridge 才允许运行时联网(如 pip 安装包)。 |
SANDBOX_MEMORY | 2g | 单个会话容器的内存上限。文档渲染类任务较吃内存,不建议低于默认值。 |
SANDBOX_CPUS | 1 | 单个会话容器的 CPU 配额。 |
SANDBOX_PIDS_LIMIT | 256 | 单个会话容器的进程数上限,防 fork 炸弹。 |
SANDBOX_NOFILE_ULIMIT | 1024:1024 | 会话容器的文件描述符 ulimit(软:硬)。 |
SANDBOX_PULL_ON_START | (空,关闭) | 非空且非 0/false 时,sidecar 启动时先 docker pull 运行时镜像一次,避免全新服务器首个会话因镜像缺失失败。拉取是尽力而为,失败只记日志不阻断启动。 |
认证
| 变量 | 默认值 | 说明 |
|---|---|---|
SANDBOX_API_KEY | (空) | sidecar 要求所有请求携带匹配的 Bearer 密钥,校验失败即拒绝。密钥为空且未显式豁免时,sidecar 直接拒绝启动(fail-closed)。 |
SANDBOX_ALLOW_NO_AUTH | (空,关闭) | 显式豁免无密钥启动,仅限可信的 localhost 开发机。只有 1/true/yes/on 四个取值生效,其它写法(包括 False/no/off)一律视为不豁免。 |
sidecar 直接驱动宿主机的 Docker,等价于宿主机 root 权限。SANDBOX_ALLOW_NO_AUTH 只应出现在完全不对外的本机开发环境;生产环境必须设置强随机的 SANDBOX_API_KEY,并与 app 侧(第 5 节)保持一致。
执行超时与会话回收
| 变量 | 默认值 | 说明 |
|---|---|---|
SANDBOX_EXEC_TIMEOUT_CAP_MS | 600000 | 单次执行超时的运维硬上限(10 分钟)。管理后台设置的每次调用超时会被钳制到该值以内;调低即收紧天花板。 |
SANDBOX_DEFAULT_EXEC_TIMEOUT_MS | 120000 | 调用方未指定超时时的默认单次执行超时(120 秒),不会静默继承 10 分钟硬上限。 |
SANDBOX_IDLE_TTL_SECONDS | 1800 | 会话空闲多久后被回收,默认 30 分钟。 |
SANDBOX_IDLE_TTL_CAP_SECONDS | 86400 | 空闲回收 TTL 的运维硬上限(24 小时)。管理后台可调短回收窗口,但永远不能超过该上限。 |
SANDBOX_MAX_SESSIONS | 16 | 同时存活的会话容器数上限。 |
SANDBOX_MAX_CONCURRENT_EXECS | 4 | 同时执行的代码运行数上限。 |
SANDBOX_MAX_CONCURRENT_CREATES | 2 | 同时进行的会话创建数上限。 |
SANDBOX_QUEUE_TIMEOUT_SECONDS | 150 | 请求在并发队列中的最长等待时间,超时报错返回。 |
文件系统与磁盘防护
| 变量 | 默认值 | 说明 |
|---|---|---|
SANDBOX_READ_ONLY_ROOTFS | 1 | 会话容器根文件系统只读(防磁盘写满攻击)。仅 /workspace、/tmp、$HOME 是有大小上限的 tmpfs。设为 0 或 false 可关闭,不建议。 |
SANDBOX_TMPFS_SIZE | 256m | /tmp 等 tmpfs 挂载的大小上限。 |
SANDBOX_WORKSPACE_SIZE | 512m | 可写工作区 /workspace 的 tmpfs 大小上限。旧名 SANDBOX_WORKSPACE_TMPFS_SIZE 仍作为兼容别名生效。 |
SANDBOX_DISK_SIZE | (空,关闭) | 会话容器可写层的磁盘配额(如 1g)。需要 Docker overlay2 存储驱动且启用 pquota/prjquota,不满足时 docker run 会报错,因此为可选项且以尽力而为方式应用(失败时自动去掉该参数重试)。 |
SANDBOX_SECCOMP_PROFILE | (空,关闭) | 为会话容器指定固定的 seccomp profile 文件路径(路径需在 sidecar 容器内可读)。仅在设置时附加到 docker run。 |
输出与产物限额
| 变量 | 默认值 | 说明 |
|---|---|---|
SANDBOX_MAX_OUTPUT_BYTES | 32768 | 单次执行 stdout/stderr 的截断上限(32KB)。 |
SANDBOX_MAX_ARTIFACT_BYTES | 20971520 | 单个产物文件的大小上限(20MiB)。 |
SANDBOX_MAX_TOTAL_ARTIFACT_BYTES | 52428800 | 单次执行全部产物的总大小上限(50MiB)。 |
SANDBOX_MAX_FILES_PER_EXEC | 20 | 单次执行可上传的文件数上限。 |
SANDBOX_MAX_UPLOAD_BYTES | 20971520 | 向沙箱上传单个文件的大小上限(20MiB)。 |
SANDBOX_MAX_ARCHIVE_BYTES | 209715200 | 工作区归档 tar 包的大小上限(200MiB)。会话 /workspace 超过该值时跳过归档(记日志),会话本身仍正常回收。 |
工作区持久化
| 变量 | 默认值 | 说明 |
|---|---|---|
SANDBOX_LOCAL_STORAGE_DIR | (空,关闭) | 本地磁盘归档后端目录,S3/OSS 之外的零依赖替代。设置后工作区 tar 包写入该目录,需挂载为卷才能跨 sidecar 重启保留;留空时 local 后端不生效,会话被回收即工作区丢失。该路径只能由运维通过环境变量指定,不接受远端调用方传入。 |
怎么选/常见坑:官方 compose 已为 sidecar 填好可用默认值,多数场景只需要关心 SANDBOX_API_KEY(与 app 侧一致)和是否放开 SANDBOX_NETWORK。放开网络(bridge)意味着不可信代码可以对外发包,请评估风险后再开。资源类上限(SANDBOX_MEMORY/SANDBOX_MAX_SESSIONS/SANDBOX_MAX_CONCURRENT_EXECS)按「宿主机内存 ≥ 会话数 × 单会话内存」估算,默认 16 会话 × 2g 的理论峰值超出小机器承受能力,小内存机器应先调低 SANDBOX_MAX_SESSIONS。sidecar 内部的读循环节奏、S3/OSS 超时重试、请求体大小等微调项(SANDBOX_S3_*、SANDBOX_MAX_BODY_BYTES 等)归入高级调优环境变量。
9. 前端构建期变量
| 变量 | 默认值 | 说明 |
|---|---|---|
VITE_API_BASE | /api | 前端调用 API 的基础路径,在构建时注入。仅前后端分离部署(前端静态托管在别处)时改为 API 服务的完整地址。 |
怎么选/常见坑:这是构建期变量,不是运行时变量:改了它必须重新构建前端产物,对已构建好的官方镜像设置它没有任何效果。单容器同源部署(默认形态)保持 /api 即可;只有把前端部署到独立域名/CDN 时才改成 https://api.example.com/api 这类完整地址,同时记得在服务端把前端 origin 加入 ALLOWED_ORIGINS(第 3 节)。
下一步
- 首次部署从快速开始与首次运行走一遍标准流程。
- 域名与 HTTPS 接入见反向代理与 Cloudflare。
- 全部内部调优项索引见高级调优环境变量。