快速部署
本頁帶你在 5 分鐘內用 Docker Compose 拉起一套完整的 Aivory 生產棧:PostgreSQL、Redis、Qdrant、內建程式碼沙箱,以及一個同時伺服前端 SPA 和 /api 後端的 app 容器(二者同源,無需任何域名或 CORS 配置)。
整套棧由一份 compose 檔案描述,包含以下服務:
| 服務 | 映象 | 作用 |
|---|---|---|
postgres | postgres:16-alpine | 關係型儲存:使用者、對話、知識庫、用量等 |
redis | redis:7-alpine | 快取、限流計數器、跨程序停止流式輸出的 pub/sub |
qdrant | qdrant/qdrant:v1.12.4 | RAG 向量檢索 |
sandbox | ghcr.io/hjxwz123/aivory-sandbox-sidecar | 內建程式碼執行沙箱,僅內網可達 |
app | ghcr.io/hjxwz123/aivory-app | 單容器同源伺服 SPA 與 /api |
Aivory 的後端按環境變數自動選型:不配 PostgreSQL 就用內嵌 SQLite,不配 Redis 就用程序內快取,不配 Qdrant 則 RAG 回退為全文注入。想用最小依賴跑單機,見 SQLite 模式。本頁描述的是推薦的完整生產部署。
前置要求
| 專案 | 要求 |
|---|---|
| Docker Engine | 已安裝並可正常執行(docker info 無報錯) |
| Docker Compose | v2(docker compose 子命令,不是舊版 docker-compose) |
| 機器規格 | 2 核 CPU + 4 GB 記憶體起步 |
| 埠 | 宿主機 80 埠空閒(可改,見下文) |
| 磁碟 | 資料庫、向量、上傳檔案均持久化在本機,按使用量預留 |
內建程式碼沙箱通過掛載的 /var/run/docker.sock 在宿主機上派生每會話的隔離容器,因此宿主機必須能直接執行 Docker(不適用於無 Docker 守護程序的託管容器平臺)。沙箱服務不釋出任何宿主埠,只在私有網路內被 app 訪問。
第 1 步:獲取程式碼
git clone https://github.com/hjxwz123/Aivory.git
cd Aivory/deploy
部署相關的全部檔案都在 deploy/ 目錄下:docker-compose.prod.yml 和 .env.example。
第 2 步:建立並編輯 .env
cp .env.example .env
.env 中必須修改的只有三項,其餘全部可以保持預設。三項都留著佔位值會導致啟動失敗或嚴重安全問題:
# 生成三個強隨機值
openssl rand -hex 24 # 用作 POSTGRES_PASSWORD
openssl rand -hex 24 # 用作 REDIS_PASSWORD
openssl rand -hex 32 # 用作 JWT_SECRET
| 變數 | 要求 | 說明 |
|---|---|---|
POSTGRES_PASSWORD | 必設 | PostgreSQL 密碼。不設定時 compose 直接拒絕啟動 |
REDIS_PASSWORD | 必設 | Redis 密碼。不設定時 compose 直接拒絕啟動 |
JWT_SECRET | 必設,長度至少 32 字元 | 簽發登入令牌的金鑰。生產環境下 Aivory 檢測到佔位值或過短金鑰會拒絕啟動 |
請務必使用 openssl rand -hex 32 生成,不要用可猜測的字串。同時注意:更換 JWT_SECRET 會使所有已登入會話失效。
模型服務商的 API Key(Anthropic / OpenAI / Gemini 等)不在 .env 裡配置,它們存在資料庫的渠道表中,部署完成後在管理後臺新增,見首次執行配置。
第 3 步:啟動
方式一,拉取預構建映象(推薦,來自 GitHub Container Registry):
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d
方式二,本地從原始碼構建(在程式碼上做了修改,或官方映象未覆蓋你的 CPU 架構時):
docker compose -f docker-compose.prod.yml up -d --build
app 服務同時聲明瞭 image: 和 build::本地存在預構建映象時 Compose 優先使用映象,否則回退到本地構建。資料庫 schema 由應用啟動時自動遷移建立,不需要手動執行任何 SQL。
第 4 步:驗證
docker compose -f docker-compose.prod.yml ps
預期看到 5 個服務:postgres、redis 處於 healthy,qdrant、app 處於 running,sandbox 首次啟動時需要先拉取沙箱執行時映象,健康檢查預留了 120 秒啟動視窗,稍等即可變為 healthy。
然後請求首頁。app 容器內部監聽 8787 埠,compose 預設把它對映到宿主機 80 埠:
curl -sI http://localhost
返回 HTTP/1.1 200 且內容為 SPA 頁面即部署成功。如果你把埠對映改成了別的(例如 8080:8787),把命令裡的埠對應替換。
埠對映不走環境變數,直接編輯 docker-compose.prod.yml 中 app 服務的 ports 段,把 "80:8787" 的左邊改掉(例如 "8080:8787"),右邊的 8787 是容器內監聽埠,不要改。
第 5 步:開啟站點,進入首啟設定
瀏覽器訪問 http://<你的伺服器 IP 或域名>。全新部署沒有任何使用者,頁面會自動進入首啟設定:你建立的第一個賬號立即成為管理員。接下來的建號、新增渠道、建立模型等步驟,見首次執行配置。
一條龍命令
以下命令塊從零完成:克隆、生成金鑰、寫入 .env、拉映象、啟動。適合在一臺全新機器上直接貼上執行:
git clone https://github.com/hjxwz123/Aivory.git \
&& cd Aivory/deploy \
&& cp .env.example .env \
&& sed -i "s|^POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$(openssl rand -hex 24)|" .env \
&& sed -i "s|^REDIS_PASSWORD=.*|REDIS_PASSWORD=$(openssl rand -hex 24)|" .env \
&& sed -i "s|^JWT_SECRET=.*|JWT_SECRET=$(openssl rand -hex 32)|" .env \
&& docker compose -f docker-compose.prod.yml pull \
&& docker compose -f docker-compose.prod.yml up -d \
&& docker compose -f docker-compose.prod.yml ps
上面的命令把隨機金鑰直接寫進了 deploy/.env。這個檔案等同於你部署的鑰匙串,請納入備份,不要提交到公開倉庫。
.env.example 變數逐條說明
下面按 .env.example 中的分組逐條解釋每個變數該不該改。
映象來源
| 變數 | 預設值 | 該不該改 |
|---|---|---|
IMAGE_OWNER | hjxwz123 | 一般不改。只有當你 fork 了倉庫並用自己的 GHCR 名稱空間釋出映象時才改成自己的賬號 |
IMAGE_TAG | latest | 一般不改。如需鎖定版本,改為對應的映象標籤,避免 latest 漂移 |
網路與跨域
| 變數 | 預設值 | 該不該改 |
|---|---|---|
ALLOWED_ORIGINS | 未設定(註釋狀態) | 保持不設。單容器部署裡 SPA 與 /api 同源,不存在跨域;僅當你把前端拆到與 API 不同的 origin 時才需要。域名與 HTTPS 見反向代理 |
注意:沒有 WEB_PORT 或 PUBLIC_ORIGIN 這類變數。宿主埠在 compose 檔案裡改;域名不需要配置,容器被哪個 host 訪問,哪個 host 就能用,多個域名同時指向也可以。
PostgreSQL
| 變數 | 預設值 | 該不該改 |
|---|---|---|
POSTGRES_USER | aivory | 不必改 |
POSTGRES_DB | aivory | 不必改 |
POSTGRES_PASSWORD | 佔位值 | 必改,openssl rand -hex 24 |
Redis
| 變數 | 預設值 | 該不該改 |
|---|---|---|
REDIS_PASSWORD | 佔位值 | 必改,openssl rand -hex 24 |
Qdrant
| 變數 | 預設值 | 該不該改 |
|---|---|---|
QDRANT_URL | http://qdrant:6333 | 不必改。只有指向外部 Qdrant 叢集時才覆蓋 |
QDRANT_API_KEY | 空 | 可不改。留空時 qdrant 服務與 app 共用同一個內建內部金鑰,開箱即用;Qdrant 不釋出任何宿主埠,僅內網可達。想要獨立強金鑰可用 openssl rand -hex 24 覆蓋 |
認證
| 變數 | 預設值 | 該不該改 |
|---|---|---|
JWT_SECRET | 佔位值 | 必改,openssl rand -hex 32,至少 32 字元,否則生產環境拒絕啟動 |
資料目錄與備份
| 變數 | 預設值 | 該不該改 |
|---|---|---|
DATA_DIR | ./data | 視磁碟規劃而定。宿主機路徑,繫結掛載到容器 /app/data,存放使用者上傳檔案與生成產物,必須納入備份 |
BACKUP_DIR | /app/data/backups | 不必改。容器內路徑,管理後臺非同步生成的全量遷移 ZIP 存放處,宿主機上對應 DATA_DIR/backups |
MAX_BACKUP_BYTES | 21474836480(20 GiB) | 一般不改。管理後臺匯入備份的大小上限,含向量資料的全量包可能很大,超限時調大 |
資料庫、Redis、Qdrant 的資料分別在命名卷 pgdata、redisdata、qdrantdata 中,備份策略見備份與遷移。
演示模型
| 變數 | 預設值 | 該不該改 |
|---|---|---|
ENABLE_MOCK_PROVIDER | false | 可選。設為 true 會注入一個內建演示渠道,不需要任何真實 API Key 就能端到端跑通對話,適合先驗證部署;在管理後臺新增真實渠道後改回 false |
聯網搜尋(可選)
| 變數 | 預設值 | 該不該改 |
|---|---|---|
SEARCH_PROVIDER | 空 | 可選。搜尋後端型別:serper / brave 需配 SEARCH_API_KEY;searxng 需配 SEARCH_BASE_URL,無需 key |
SEARCH_API_KEY | 空 | 隨 SEARCH_PROVIDER 而定 |
SEARCH_BASE_URL | 空 | 僅 searxng 類後端需要 |
這三項也可以部署後在管理後臺線上配置,.env 裡的值只是啟動期兜底,可以先全部留空。
嵌入模型(可選,知識庫檢索質量相關)
| 變數 | 預設值 | 該不該改 |
|---|---|---|
EMBEDDING_BASE_URL | 空 | 建議生產配置。留空時使用內建 256 維本地 embedder,可用但檢索質量不適合生產;指向任意 OpenAI 格式的 /v1/embeddings 端點即可 |
EMBEDDING_API_KEY | 空 | 隨嵌入服務而定 |
EMBEDDING_MODEL | text-embedding-3-small | 按你的嵌入服務改 |
EMBEDDING_DIM | 1536 | 必須與嵌入模型的輸出維度一致。Qdrant 按維度使用獨立 collection,維度不匹配會退回本地 256 維 embedder |
MinerU 文件解析(可選)
| 變數 | 預設值 | 該不該改 |
|---|---|---|
MINERU_API_URL | https://mineru.net | 一般不改 |
MINERU_API_KEY | 空 | 可選。用於掃描版 / 圖片型 PDF 的 OCR 解析;不配置時這類文件仍能上傳進知識庫,但內容只有一行佔位文本。也可部署後在管理後臺配置 |
程式碼沙箱(註釋狀態,通常什麼都不用設)
沙箱服務隨本棧一起啟動,app 通過私有網路訪問它,雙方共享同一個內建預設金鑰,開箱即用。僅在需要覆蓋預設限額時取消註釋:
| 變數 | 預設值 | 說明 |
|---|---|---|
SANDBOX_API_KEY | 內建共享預設值 | 想用自定義金鑰時設定,app 與 sandbox 會同時讀到 |
SANDBOX_MEMORY | 2g | 每個會話容器的記憶體上限 |
SANDBOX_CPUS | 1 | 每個會話容器的 CPU 配額 |
SANDBOX_MAX_SESSIONS | 16 | 併發沙箱會話數上限 |
SANDBOX_WORKSPACE_SIZE | 512m | 每會話 /workspace 大小 |
SANDBOX_NETWORK | none | 沙箱內程式碼預設無網路;確需聯網時才改為 bridge |
沙箱架構與安全邊界詳見程式碼沙箱部署。同時請保持管理後臺設定裡的 sandbox_base_url / sandbox_api_key 兩個欄位為空,這樣內建沙箱才會生效。
下一步
- 首次執行配置:建立管理員、新增渠道與模型、發出第一條訊息
- 反向代理與 HTTPS:公網部署必讀,給 80 埠的明文 HTTP 加上 TLS 終止層
- Cloudflare 接入:使用 Cloudflare 時的注意事項
- 核心環境變數:全部部署級變數的完整參考