跳至主要内容

快速部署

本頁帶你在 5 分鐘內用 Docker Compose 拉起一套完整的 Aivory 生產棧:PostgreSQL、Redis、Qdrant、內建程式碼沙箱,以及一個同時伺服前端 SPA 和 /api 後端的 app 容器(二者同源,無需任何域名或 CORS 配置)。

整套棧由一份 compose 檔案描述,包含以下服務:

服務映象作用
postgrespostgres:16-alpine關係型儲存:使用者、對話、知識庫、用量等
redisredis:7-alpine快取、限流計數器、跨程序停止流式輸出的 pub/sub
qdrantqdrant/qdrant:v1.12.4RAG 向量檢索
sandboxghcr.io/hjxwz123/aivory-sandbox-sidecar內建程式碼執行沙箱,僅內網可達
appghcr.io/hjxwz123/aivory-app單容器同源伺服 SPA 與 /api
不想跑完整棧?

Aivory 的後端按環境變數自動選型:不配 PostgreSQL 就用內嵌 SQLite,不配 Redis 就用程序內快取,不配 Qdrant 則 RAG 回退為全文注入。想用最小依賴跑單機,見 SQLite 模式。本頁描述的是推薦的完整生產部署。

前置要求

專案要求
Docker Engine已安裝並可正常執行(docker info 無報錯)
Docker Composev2(docker compose 子命令,不是舊版 docker-compose)
機器規格2 核 CPU + 4 GB 記憶體起步
宿主機 80 埠空閒(可改,見下文)
磁碟資料庫、向量、上傳檔案均持久化在本機,按使用量預留
沙箱需要 Docker socket

內建程式碼沙箱通過掛載的 /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 檢測到佔位值或過短金鑰會拒絕啟動
JWT_SECRET 一旦洩露等於交出全部賬號

請務必使用 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
同一份 compose 檔案支援兩種方式

app 服務同時聲明瞭 image:build::本地存在預構建映象時 Compose 優先使用映象,否則回退到本地構建。資料庫 schema 由應用啟動時自動遷移建立,不需要手動執行任何 SQL。

第 4 步:驗證

docker compose -f docker-compose.prod.yml ps

預期看到 5 個服務:postgresredis 處於 healthy,qdrantapp 處於 running,sandbox 首次啟動時需要先拉取沙箱執行時映象,健康檢查預留了 120 秒啟動視窗,稍等即可變為 healthy

然後請求首頁。app 容器內部監聽 8787 埠,compose 預設把它對映到宿主機 80 埠:

curl -sI http://localhost

返回 HTTP/1.1 200 且內容為 SPA 頁面即部署成功。如果你把埠對映改成了別的(例如 8080:8787),把命令裡的埠對應替換。

80 埠被佔用怎麼辦

埠對映不走環境變數,直接編輯 docker-compose.prod.ymlapp 服務的 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
儲存好 .env

上面的命令把隨機金鑰直接寫進了 deploy/.env。這個檔案等同於你部署的鑰匙串,請納入備份,不要提交到公開倉庫。

.env.example 變數逐條說明

下面按 .env.example 中的分組逐條解釋每個變數該不該改。

映象來源

變數預設值該不該改
IMAGE_OWNERhjxwz123一般不改。只有當你 fork 了倉庫並用自己的 GHCR 名稱空間釋出映象時才改成自己的賬號
IMAGE_TAGlatest一般不改。如需鎖定版本,改為對應的映象標籤,避免 latest 漂移

網路與跨域

變數預設值該不該改
ALLOWED_ORIGINS未設定(註釋狀態)保持不設。單容器部署裡 SPA 與 /api 同源,不存在跨域;僅當你把前端拆到與 API 不同的 origin 時才需要。域名與 HTTPS 見反向代理

注意:沒有 WEB_PORTPUBLIC_ORIGIN 這類變數。宿主埠在 compose 檔案裡改;域名不需要配置,容器被哪個 host 訪問,哪個 host 就能用,多個域名同時指向也可以。

PostgreSQL

變數預設值該不該改
POSTGRES_USERaivory不必改
POSTGRES_DBaivory不必改
POSTGRES_PASSWORD佔位值必改,openssl rand -hex 24

Redis

變數預設值該不該改
REDIS_PASSWORD佔位值必改,openssl rand -hex 24

Qdrant

變數預設值該不該改
QDRANT_URLhttp://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_BYTES21474836480(20 GiB)一般不改。管理後臺匯入備份的大小上限,含向量資料的全量包可能很大,超限時調大

資料庫、Redis、Qdrant 的資料分別在命名卷 pgdataredisdataqdrantdata 中,備份策略見備份與遷移

演示模型

變數預設值該不該改
ENABLE_MOCK_PROVIDERfalse可選。設為 true 會注入一個內建演示渠道,不需要任何真實 API Key 就能端到端跑通對話,適合先驗證部署;在管理後臺新增真實渠道後改回 false

聯網搜尋(可選)

變數預設值該不該改
SEARCH_PROVIDER可選。搜尋後端型別:serper / brave 需配 SEARCH_API_KEY;searxng 需配 SEARCH_BASE_URL,無需 key
SEARCH_API_KEYSEARCH_PROVIDER 而定
SEARCH_BASE_URLsearxng 類後端需要

這三項也可以部署後在管理後臺線上配置,.env 裡的值只是啟動期兜底,可以先全部留空。

嵌入模型(可選,知識庫檢索質量相關)

變數預設值該不該改
EMBEDDING_BASE_URL建議生產配置。留空時使用內建 256 維本地 embedder,可用但檢索質量不適合生產;指向任意 OpenAI 格式的 /v1/embeddings 端點即可
EMBEDDING_API_KEY隨嵌入服務而定
EMBEDDING_MODELtext-embedding-3-small按你的嵌入服務改
EMBEDDING_DIM1536必須與嵌入模型的輸出維度一致。Qdrant 按維度使用獨立 collection,維度不匹配會退回本地 256 維 embedder

MinerU 文件解析(可選)

變數預設值該不該改
MINERU_API_URLhttps://mineru.net一般不改
MINERU_API_KEY可選。用於掃描版 / 圖片型 PDF 的 OCR 解析;不配置時這類文件仍能上傳進知識庫,但內容只有一行佔位文本。也可部署後在管理後臺配置

程式碼沙箱(註釋狀態,通常什麼都不用設)

沙箱服務隨本棧一起啟動,app 通過私有網路訪問它,雙方共享同一個內建預設金鑰,開箱即用。僅在需要覆蓋預設限額時取消註釋:

變數預設值說明
SANDBOX_API_KEY內建共享預設值想用自定義金鑰時設定,appsandbox 會同時讀到
SANDBOX_MEMORY2g每個會話容器的記憶體上限
SANDBOX_CPUS1每個會話容器的 CPU 配額
SANDBOX_MAX_SESSIONS16併發沙箱會話數上限
SANDBOX_WORKSPACE_SIZE512m每會話 /workspace 大小
SANDBOX_NETWORKnone沙箱內程式碼預設無網路;確需聯網時才改為 bridge

沙箱架構與安全邊界詳見程式碼沙箱部署。同時請保持管理後臺設定裡的 sandbox_base_url / sandbox_api_key 兩個欄位為空,這樣內建沙箱才會生效。

下一步