文檔中心 / OntiCards Docker Compose 部署指南

OntiCards Docker Compose 部署指南

本文檔适用于倉庫根目錄的 compose.yaml。生產環境推薦部署在 x86_64(amd64)Linux 伺服器;項目 API 镜像包含 amd64 版的 Microsoft ODBC 與 Oracle Instant Client 依赖,ARM 伺服器需要另行适配。

1. 部署前準備

1.1 资源與網絡要求

項目最低組態生產建議
作業系統Ubuntu 22.04 / 24.04 x86_64Ubuntu 24.04 x86_64
CPU2 核4 核或以上
記憶體4 GB8 GB 或以上
磁盘30 GB50 GB 或以上 SSD
DockerDocker Engine 当前穩定版Docker Engine 当前穩定版
ComposeDocker Compose v2.24.0+ 插件Docker Compose 当前穩定版插件

請確保伺服器可以訪問所需的镜像倉庫、軟件源和模型服務。首次構建 API 與 Web 除了拉取容器镜像,還可能訪問 Debian APT、PyPI、Yarn/NPM、Microsoft 軟件源和 Oracle 下載站;只組態 Docker 镜像加速器並不能解决這些構建依赖的網絡問題。

仅 Nginx 會向宿主機暴露埠,預設是 9107。PostgreSQL、Weaviate、API 與 Web 仅在 Docker 內部網絡中通信,不需要、也不應單独暴露到公網。

Docker 發布的埠可能绕過 UFW/firewalld 的常規規則。生產環境應同時限製云安全組和主機防火墙,並只開放實际需要的 Nginx 主機埠。參见 Docker 的防火墙說明

1.2 当前服務拓扑

onticards-db + onticards-weaviate
              ↓
      onticards_api + onticards_web
              ↓
        onticards_nginx :9107
              ↓
          浏览器 / 外层反向代理

Compose 會自動創建名為 onticards 的 bridge 網絡,不需要預先執行 docker network create。啟動顺序是"資料庫與向量庫容器先啟動 → API 與 Web 容器啟動 → Nginx 容器啟動"。

本項目沒有 Docker healthcheck,因此不會定時請求 /healthz 並刷應用日誌。service_started 只保證容器啟動顺序,不代表資料庫或 API 已完成初始化;請以 docker compose ps 與服務日誌判斷實际狀態。

2. 安裝 Docker 與 Docker Compose

2.1 已有 Docker 的伺服器

先檢查版本:

docker --version
docker compose version

若命令正常且 Compose 為 v2.24.0 或更高版本,跳過安裝步驟。当前編排使用了 env_file.required 長語法,該欄位要求 Docker Compose 2.24.0+。不要在正在運行其他 Docker 工作負載的伺服器上,為了安裝而直接卸載 dockercontainerd 或修改 /etc/docker/daemon.json;先評估現有容器與運維視窗。

2.2 Ubuntu 22.04 / 24.04:使用 Docker 官方 APT 倉庫

以下步驟适用于全新 Ubuntu 伺服器。命令来自 Docker Engine 官方 Ubuntu 安裝文檔

sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

sudo tee /etc/apt/sources.list.d/docker.sources >/dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker

驗證安裝:

sudo docker run --rm hello-world
docker compose version

Docker 官方安裝包已經包含 docker-compose-plugin,日常命令請使用 docker compose,不要使用已歸為 legacy 的独立版 docker-compose。參见 Compose 安裝說明

如需让非 root 用戶執行 Docker 命令,可執行:

sudo usermod -aG docker "$USER"
newgrp docker

docker 用戶組等同于获得主機 root 級能力;生產伺服器應按最小權限原則授權。详见 Docker Linux post-installation

2.3 RHEL / Rocky / AlmaLinux

請使用對應發行版的 Docker 官方安裝流程,不要套用 Ubuntu 的 APT 命令。RHEL 8/9/10 可參考 Docker Engine on RHEL;安裝完成後同樣應確認:

docker --version
docker compose version
sudo systemctl enable --now docker

2.4 Windows 開發機

Windows 本地開發建議安裝 Docker Desktop for Windows,選擇 Linux containers 與 WSL 2 後端。Docker Desktop 已自带 Docker Engine、CLI 與 Compose;安裝後在 PowerShell 中驗證:

docker version
docker compose version

Windows Docker Desktop 與 Linux 伺服器的镜像加速組態位置不同,见下文"國內/企業镜像倉庫"章節。

3. 國內或企業镜像倉庫

3.1 先判斷是哪一類別拉取失败

资源当前来源Docker Hub 加速器是否通常覆盖
PostgreSQLpostgres:15-alpine
Nginxnginx:1.27-alpine
API 基础镜像python:3.10-slim-bookworm
Web 基础镜像node:20.11-alpine3.19
BuildKit Dockerfile 前端docker/dockerfile:1
Weaviatecr.weaviate.io/semitechnologies/weaviate:1.36.0否,需單独同步或代理
APT / pip / Yarn / Oracle 等構建依赖各自的軟件源

Docker 的 registry-mirrors 是 Docker Hub 的镜像加速機製,不能自動代理 cr.weaviate.io 等其他 Registry。不要使用来源不明的公共镜像站;镜像可能過期、失效或带来供應鏈風險。

3.2 開發/測試:組態云厂商專屬 Docker Hub 加速器

在阿裡云等云厂商控製台获取自己帳號對應的加速地址。以 阿裡云 ACR 镜像加速器 為例,控製台會生成專屬地址;該服務的官方說明將其定位為個人開發場景,生產環境應使用镜像同步或私有倉庫。

在 Linux Docker Engine 上,先備份已有組態;若 /etc/docker/daemon.json 已存在,必須將下列欄位合並到原有 JSON 中,不能覆盖其他組態:

sudo install -d -m 0755 /etc/docker
sudo test ! -f /etc/docker/daemon.json || \
  sudo cp -a /etc/docker/daemon.json "/etc/docker/daemon.json.bak.$(date +%Y%m%d%H%M%S)"
sudoedit /etc/docker/daemon.json

填寫从云厂商控製台获得的真實地址:

{
  "registry-mirrors": [
    "https://<云厂商或企业分配的加速地址>"
  ]
}

在維護視窗重啟 Docker 並驗證。重啟 Docker 可能中斷正在運行的容器:

sudo systemctl daemon-reload
sudo systemctl restart docker
docker info | sed -n '/Registry Mirrors:/,/Live Restore:/p'
docker pull nginx:1.27-alpine

Docker 的 registry-mirrors 組態格式见 dockerd 官方參考Docker Hub mirror 說明

在 Docker Desktop 中,不要修改 Linux 的 /etc/docker/daemon.json。打開 Settings → Docker Engine,將同一 JSON 欄位合並進去,再點击 Apply & Restart

3.3 生產環境:同步到受控的國內/企業私有倉庫

推薦在可訪問海外镜像的 CI 或構建機中,先驗證並同步所需镜像到企業 ACR/TCR/SWR/Harbor,再让生產伺服器只訪問受控的國內或內網倉庫。請固定版本或 digest,不要將 latest 用于生產。

以 Weaviate 為例,以下命令必須在能訪問 cr.weaviate.io 的機器執行:

docker pull cr.weaviate.io/semitechnologies/weaviate:1.36.0
docker tag cr.weaviate.io/semitechnologies/weaviate:1.36.0 \
  registry.example.com/onticards/weaviate:1.36.0
docker login registry.example.com
docker push registry.example.com/onticards/weaviate:1.36.0

同樣同步 postgres:15-alpinenginx:1.27-alpinepython:3.10-slim-bookwormnode:20.11-alpine3.19docker/dockerfile:1。不要隨意改變 Weaviate 的版本;当前 Compose 版本與項目依赖的 Weaviate client 相匹配。

為避免直接修改倉庫的主編排檔案,可在根目錄創建仅供本環境使用的 compose.images.override.yaml

services:
  onticards-db:
    image: registry.example.com/onticards/postgres:15-alpine

  onticards-weaviate:
    image: registry.example.com/onticards/weaviate:1.36.0

  onticards_nginx:
    image: registry.example.com/onticards/nginx:1.27-alpine

使用覆盖檔案啟動:

docker compose -f compose.yaml -f compose.images.override.yaml config -q
docker compose -f compose.yaml -f compose.images.override.yaml up -d --build

生產伺服器从私有倉庫拉取镜像前,同樣需要登入(或由企業凭據系統提供凭據):

docker login registry.example.com

建議使用只具備拉取權限的機器人帳號或凭據助手;不要把用戶名、密碼、AccessKey 或 token 寫進 Git、.env.prod、Compose 檔案或覆盖檔案。

API 和 Web 會从源碼構建;若 Docker Hub 完全不可达,還需把两個 Dockerfile 的基础镜像改為企業倉庫地址:

# OntiCards_Api/Dockerfile
FROM registry.example.com/onticards/python:3.10-slim-bookworm AS base

# OntiCards_Web/Dockerfile
FROM registry.example.com/onticards/node:20.11-alpine3.19 AS base

API Dockerfile 首行的 # syntax=docker/dockerfile:1 也依赖 Docker Hub 的 BuildKit 前端。完全離線時,應將該镜像同步到企業倉庫並改為對應的私有倉庫地址,或者在上網構建機上預構建 API/Web 镜像後推送到企業倉庫。

3.4 無外網環境

最可靠的方式是在上網構建機執行镜像構建與導出,在離線伺服器導入:

# 联网构建机:先完成 docker compose build 和所需 docker pull
docker save -o onticards-images.tar \
  onticards-api:local onticards-web:local \
  postgres:15-alpine nginx:1.27-alpine \
  cr.weaviate.io/semitechnologies/weaviate:1.36.0

# 离线服务器
docker load -i onticards-images.tar

# 已导入 API/Web 镜像时,禁止 Compose 再次触发源码构建
docker compose up -d --no-build --pull never

離線伺服器還需拥有與構建機相同的項目源碼、镜像標簽和運行組態。長期生產使用仍推薦企業私有倉庫,而不是手工傳輸镜像 tar 包。

4. 获取代碼與組態環境變數

git clone https://github.com/stepll2026/OntiCards.git
cd OntiCards

根目錄的 .env.prod 是可直接啟動的開發/測試預設組態。生產部署請創建未提交的 .env 覆盖檔案:

cp .env.prod .env
chmod 600 .env

編輯 .env 時,至少替換下列敏感組態:

類別別需要處理的組態
PostgreSQLDB_PASSWORD;首次啟動前確認 DB_USERNAMEDB_DATABASE
應用與 SSOSECRET_KEYSSO_SECRET_KEY
數據源連接資訊加密CONNECT_INFO_MASTER_KEY
對外訪問PUBLIC_BASE_URLALLOWED_ORIGINSNGINX_SERVER_NAMENGINX_HOST_PORT
资源與日誌GUNICORN_WORKER_MEMORY_LIMIT_MBLOG_

Docker Compose 會強製 API 使用 Docker 服務名:

DB_HOST=onticards-db
WEAVIATE_URL=http://onticards-weaviate:8080

不要把它們改成宿主機 IP 或外部 IP。API 與資料庫/向量庫在 onticards 網絡內通過服務名解析;外部訪問應始終經過 Nginx。

首次初始化後,./volumes/postgresql/data 已經存在時,再修改 DB_USERNAMEDB_PASSWORDDB_DATABASE 不會自動修改已有 PostgreSQL 的帳號、密碼或資料庫名稱。變更前先備份並按 PostgreSQL 迁移流程操作。

域名與埠示例

NGINX_SERVER_NAME=onticards.example.com
NGINX_HOST_PORT=9107
PUBLIC_BASE_URL=https://onticards.example.com
ALLOWED_ORIGINS=https://onticards.example.com

NGINX_SERVER_NAME 只是 Nginx 的 server_name 槽位;它不會自動簽發 HTTPS 證書,也不是訪問白名單。ALLOWED_ORIGINS 是瀏覽器 CORS 来源列表,不是 IP 訪問控製。

5. 啟動與驗證

5.1 首次啟動

docker compose config -q
docker compose up -d --build
docker compose ps

docker compose config -q 只校驗組態,不會啟動容器。首次執行 up -d --build 會構建 API 和 Web 镜像,並啟動五個服務。

查看日誌時按服務篩選,避免無關日誌淹沒問題:

docker compose logs --tail=200 onticards_api
docker compose logs --tail=200 onticards_web
docker compose logs --tail=200 onticards_nginx

訪問入口:

http://<服务器 IP 或域名>:9107/

可以只檢查 Nginx 首頁連通性,不要使用 /healthz

curl -I http://127.0.0.1:9107/

5.2 埠 9107 被占用

檢查埠:

sudo ss -lntp | grep ':9107'

在根目錄 .env 中換一個宿主機埠,例如:

NGINX_HOST_PORT=19107

然後重新應用組態:

docker compose up -d

容器內 Nginx 始終監聽 9107,只改變宿主機映射埠。此時對外地址、PUBLIC_BASE_URLALLOWED_ORIGINS 也應改成實际公開地址。

5.3 域名與 HTTPS

建議让云負載均衡或宿主機已有的 Nginx/Caddy 負責證書與 443,再反向代理到 OntiCards 的宿主機埠:

server {
    listen 80;
    server_name onticards.example.com;

    location / {
        proxy_pass http://127.0.0.1:9107;
        proxy_http_version 1.1;
        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;
    }
}

組態證書後,將 PUBLIC_BASE_URLALLOWED_ORIGINS 改為 https://onticards.example.com。不要在未組態證書的情况下把 HTTPS 地址寫入這两個變數。

6. 數據持久化、備份與升級

本項目使用宿主機綁定挂載,而不是 Docker named volumes。需要纳入備份的目錄是:

volumes/postgresql/data/
volumes/weaviate/data/
volumes/governance/reports/
.env

PostgreSQL 運行中時,使用逻輯導出以保證一致性:

mkdir -p backups
docker compose exec -T onticards-db \
  sh -c 'pg_dumpall -U "$POSTGRES_USER"' \
  > backups/postgresql-$(date +%F).sql

Weaviate 的檔案級備份應在服務停止後執行,避免得到不一致的數據檔案:

docker compose stop onticards_api onticards_web onticards_nginx onticards-weaviate
tar -C volumes/weaviate -czf backups/weaviate-$(date +%F).tar.gz data
docker compose up -d

治理報告可按檔案備份;若業務正在生成報告,為获得時間點一致性也應在低峰期或停寫視窗執行:

tar -C volumes/governance -czf backups/governance-reports-$(date +%F).tar.gz reports

如必須做 PostgreSQL 數據目錄的物理檔案級備份,應先停止資料庫及其依赖服務,或使用經過驗證的存储快照方案;不要對運行中的 volumes/postgresql/data 直接執行 tar

docker compose down 會停止並刪除容器與網絡,但不會刪除上述宿主機數據目錄。不要在未備份的情况下手工刪除這些目錄。

升級應用:

git pull --ff-only
# 手工对比 .env.prod 的新增项,不要覆盖已有 .env 中的生产密钥。
docker compose config -q
docker compose up -d --build
docker compose ps

7. 常用運維與故障排查

場景命令或處理方式
查看狀態docker compose ps
查看全部日誌docker compose logs -f
查看 API 日誌docker compose logs -f onticards_api
查看 Web 日誌docker compose logs -f onticards_web
重啟單個服務docker compose restart onticards_api
停止整套服務docker compose down
重新創建容器docker compose up -d --force-recreate
組態渲染檢查docker compose config -q

常见問題:

  1. 镜像拉取超時或 i/o timeout:先按第 3 章組態受控镜像加速器或私有倉庫;Weaviate 與構建軟件源需要單独處理。
  2. API 容器反復重啟:執行 docker compose logs --tail=300 onticards_api,檢查資料庫初始化、組態項、外部模型服務或可用記憶體。当前編排沒有健康檢查,因此沒有 /healthz 轮詢日誌。
  3. 刚啟動時短暫 502:由于仅保證容器啟動顺序,資料庫/API 初次初始化期間可能尚未接受請求;等待日誌完成後再訪問。
  4. 域名能解析但瀏覽器請求失败:核對 PUBLIC_BASE_URLALLOWED_ORIGINS、外層反向代理的 Host/X-Forwarded-* 頭及云安全組規則。
  5. 磁盘空間不足:先用 docker system df 查看 Docker 占用,再製定保留镜像與構建快取的清理方案;不要在不了解影響的情况下執行全局清理命令。

8. 上線前檢查清單

  • [ ] 已使用 Docker Engine 與 Compose v2,並通過 docker compose version 驗證。
  • [ ] .env 已創建且權限受限,生產密碼與密鑰均已替換。
  • [ ] DB_HOST=onticards-dbWEAVIATE_URL=http://onticards-weaviate:8080 保持 Docker 服務名。
  • [ ] 只開放 Nginx 對應的宿主機埠;資料庫、API、Web、Weaviate 未直接暴露公網。
  • [ ] 已為生產環境準備可信的私有镜像倉庫或經過驗證的镜像加速方案。
  • [ ] 已驗證 APT、PyPI、Yarn/NPM、Microsoft/Oracle 等構建依赖的網絡策略。
  • [ ] 已備份 volumes/ 目錄與 .env,並驗證恢復流程。
  • [ ] 已組態域名、HTTPS、云安全組和日誌監控。