Higress 之二 · Compose 安装与控制台
前置:读完之一
HTML:
docs/html_cursor/Higress_之二_Compose安装与控制台_cursor.html本文含:安装步骤、本次安装实战排错、完整部署脚本附录
0. 本册涉及凭据(安装 / Console)
| 用途 | 完整值 |
|---|---|
| Console URL | http://192.168.110.207:8001 |
| Console 用户名 | admin |
| Console 密码 | Higress207admin! |
| 安装加密 Key(恰好 32 字符) | bocheng207higressenckey32chars!! |
| 验收时常用 LiteLLM Key | sk-litellm-bocheng-207 |
| 验收时常用 Xinference Key | xf-K8H3LiS27H4188XdOyWJj74MWMOlIR9tZbiybDbxbSas7eAI |
部署脚本连 207 时用的 Dify 账号(dify_api 登录,非 Higress) | 邮箱 38205036@qq.com / 密码 Difyai123456 |
系列总表见之一 §0;文件:patches_cursor/Higress部署/console.env。
1. 部署形态
官方 higress-standalone(Docker Compose),目录 /opt/higress。 内置 Nacos(--use-builtin-nacos)。Standalone 偏学习/内网;大规模生产可再迁 Helm。
2. 一键部署(推荐)
在 Windows 项目根:
python scripts_cursor/00_部署_workbuddy到207.py
python scripts_cursor/Higress部署/Higress_01_部署.py207 本机等价:
bash /opt/workbuddy/scripts_bash_cursor/Higress部署/Higress_01_部署.sh安装参数(patches_cursor/Higress部署/install_options.env):
| 参数 | 值 |
|---|---|
| 目录 | /opt/higress |
| Gateway HTTP | 18080 |
| Gateway HTTPS | 18443 |
| Console | 8001 |
| Nacos | 8848 |
| 加密 Key | bocheng207higressenckey32chars!!(恰好 32 字符) |
3. 启停与状态
/opt/higress/bin/status.sh
/opt/higress/bin/startup.sh
/opt/higress/bin/shutdown.sh
/opt/higress/bin/logs.sh期望容器:higress-gateway-1、higress-console-1、higress-nacos-1 等。
curl -sS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8001/
# 2004. Console 初始化(首次必做)
浏览器:http://192.168.110.207:8001/ 或 API(见下方案例 C):
curl -sS -X POST http://127.0.0.1:8001/system/init \
-H "Content-Type: application/json" \
-d '{"adminUser":{"name":"admin","displayName":"admin","password":"Higress207admin!"}}'
curl -sS -c /tmp/hc.ck -X POST http://127.0.0.1:8001/session/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"Higress207admin!"}'| 项 | 值 |
|---|---|
| URL | http://192.168.110.207:8001 |
| 用户名 | admin |
| 密码 | Higress207admin! |
| 初始化 API | POST /system/init,body 含 adminUser.name=admin、adminUser.password=Higress207admin! |
| 登录 API | POST /session/login,username=admin,password=Higress207admin! |
凭据文件:patches_cursor/Higress部署/console.env(完整内容见附录 B)。
5. 本次实装案例:安装与 Console 阶段排错
案例 A:Windows 跑部署脚本报 ModuleNotFoundError: _bootstrap
现象
File "...\scripts_cursor\Higress部署\Higress_01_部署.py", line 9, in <module>
import _bootstrap
ModuleNotFoundError: No module named '_bootstrap'原因
首版 Higress部署/_bootstrap.py 写成了「再 import 父级 _bootstrap」,没有把 scripts_cursor / 项目根加入 sys.path。LiteLLM 子目录的正确写法是:把 HERE、SCRIPTS_ROOT、ROOT 插入 sys.path。
解决步骤
- 用编辑器打开
scripts_cursor/Higress部署/_bootstrap.py。 - 改成与 LiteLLM 相同模式(完整代码见本文附录
_bootstrap.py)。 - 在项目根重跑:
python scripts_cursor/Higress部署/Higress_01_部署.py- 期望输出含:
[OK] Higress http://192.168.110.207:18080 | Console http://192.168.110.207:8001。
案例 B:从 Windows 传到 207 的 .sh 因 CRLF 执行失败
现象(同类环境曾出现)
/tmp/Higress_01_部署.sh: line 3: set: pipefail : invalid option name或 bash 报 $'\r': command not found。
原因
Windows 检出/保存的 shell 脚本带 \r\n,Linux bash 把 \r 当成选项名的一部分。
解决步骤
部署 Python 里在 chmod +x 前执行:
sed -i 's/\r$//' /tmp/Higress_01_部署.sh
chmod +x /tmp/Higress_01_部署.sh
bash /tmp/Higress_01_部署.sh仓库中 Higress_01_部署.py 已包含该 sed(见附录)。
手工补救:
sed -i 's/\r$//' /opt/workbuddy/scripts_bash_cursor/Higress部署/*.sh案例 C:Console 已 200,但登录失败 —— 未初始化管理员
现象
curl -sS -X POST http://127.0.0.1:8001/session/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"Higress207admin!"}'返回:
{"success":false,"message":"java.lang.IllegalStateException: No valid admin config is available.","data":null}错误排查过程(本次真实路径)
- 误试
/api/v1/user/init、/api/v1/system/init:POST 得到 405 Method Not Allowed;GET 却返回 整页 HTML(SPA 前端兜底),容易误判「接口不存在」。 - 对 jar 反查 Controller:
SystemController映射在/system,动作为/init;SessionController在/session,登录为/login。 SystemInitRequest字段是adminUser(内嵌 User),不是顶层username。
正确初始化
# 1) 看版本(应有 JSON,不是 HTML)
curl -sS http://127.0.0.1:8001/system/info
# {"version":"2.2.4","capabilities":["config.ingress.v1"]}
# 2) 初始化(仅首次;成功:{"success":true,...})
curl -sS -X POST http://127.0.0.1:8001/system/init \
-H "Content-Type: application/json" \
-d '{"adminUser":{"name":"admin","displayName":"admin","password":"Higress207admin!"}}'
# 3) 登录(应返回 name=admin)
curl -sS -c /tmp/hc.ck -b /tmp/hc.ck -X POST http://127.0.0.1:8001/session/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"Higress207admin!"}'注意
- 业务 API 前缀是
/v1/routes、/v1/service-sources(登录后带 Cookie),不是随便加/api前缀。 - 初始化成功后再跑之三的
Higress_02_配置路由.sh。
案例 D:DATA_ENC_KEY 长度必须 32
现象
脚本直接退出:
[FAIL] DATA_ENC_KEY 必须恰好 32 字符,当前 xx解决
- 统计字符数:
python -c "print(len('你的key'))"→ 必须为32。 - 本环境固定:
bocheng207higressenckey32chars!!(已写入install_options.env)。 - 改 Key 后需理解:与已有 Nacos 加密配置绑定;学习环境勿随意更换,除非准备重装
/opt/higress。
案例 E:容器内用 127.0.0.1 访问宿主机 LiteLLM 必然失败
现象 / 背景
Gateway 跑在 Docker 网络 higress_higress-net 内。若服务源填 127.0.0.1:4000,指的是 容器自己,不是 207 宿主机。
本次探测结论
# 从与 gateway 同一网络的临时 curl 容器测(gateway 镜像内无 wget)
NET=higress_higress-net
docker run --rm --network "$NET" curlimages/curl:8.5.0 \
-sS -m 5 http://192.168.110.207:4000/health/liveliness
# 返回: I'm alive!docker bridge gateway 文件记录为 192.168.200.8(本机非经典 172.17.0.1),局域网 IP 192.168.110.207 同样可达,路由配置统一用后者,好记且与文档一致。
解决
服务源 domain 使用 192.168.110.207:4000 / :80 / :9997(见之三脚本)。
下一篇:路由与验收 → Higress_之三_总入口路由配置与验收_cursor.md
附录 A:patches_cursor/Higress部署/install_options.env(完整)
# Higress standalone 安装参数(207)
# 由 Higress_01_部署.sh 读取;勿占用 Dify :80/:443
HIGRESS_DEST=/opt/higress
GATEWAY_HTTP_PORT=18080
GATEWAY_HTTPS_PORT=18443
CONSOLE_PORT=8001
NACOS_PORT=8848
# 必须恰好 32 字符(集群/重建保持一致)
DATA_ENC_KEY=bocheng207higressenckey32chars!!
# 路由后端(容器访问宿主机:优先 host-gateway IP)
# 部署脚本会探测并写入 host_gateway.ip
BACKEND_LLM=http://HOST_GATEWAY:4000
BACKEND_DIFY=http://HOST_GATEWAY:80
BACKEND_XF=http://HOST_GATEWAY:9997附录 B:patches_cursor/Higress部署/console.env(完整)
# Higress / 关联栈凭据(内网)
# 与 docs/md_cursor/Higress_之一 §0 保持一致;改密后两处一起改
# --- Higress Console ---
CONSOLE_URL=http://192.168.110.207:8001
ADMIN_USER=admin
ADMIN_PASS=Higress207admin!
# --- Higress 安装 ---
DATA_ENC_KEY=bocheng207higressenckey32chars!!
GATEWAY_HTTP=http://192.168.110.207:18080
BACKEND_HOST=192.168.110.207
DIFY_HOST=dify.ai.local
# --- LiteLLM(经 /llm 或直连 :4000)---
LITELLM_BASE=http://192.168.110.207:4000
LITELLM_VIA_HIGRESS=http://192.168.110.207:18080/llm/v1
LITELLM_MASTER_KEY=sk-litellm-bocheng-207
# --- Xinference(经 /xf 或直连 :9997)---
XF_URL=http://192.168.110.207:9997
XF_VIA_HIGRESS=http://192.168.110.207:18080/xf/v1
XF_KEY=xf-K8H3LiS27H4188XdOyWJj74MWMOlIR9tZbiybDbxbSas7eAI
XF_ADMIN_USER=admin
XF_ADMIN_PASS=admin1234
# --- vLLM 上游(LiteLLM→183,客户端一般不直连)---
VLLM_BASE=http://116.62.10.183:8000/v1
VLLM_KEY=123456
# --- Dify 控制台(浏览器 / Host 路由)---
DIFY_URL=http://192.168.110.207/
DIFY_VIA_HIGRESS=http://dify.ai.local:18080/
DIFY_EMAIL=38205036@qq.com
DIFY_PASSWORD=Difyai123456
# Dify 模型供应商 API Key(指向 LiteLLM 或 Higress /llm/v1 时)
DIFY_MODEL_API_KEY=sk-litellm-bocheng-207附录 C:scripts_cursor/Higress部署/_bootstrap.py(完整)
# -*- coding: utf-8 -*-
from pathlib import Path
import sys
HERE = Path(__file__).resolve().parent
SCRIPTS_ROOT = HERE.parent
ROOT = HERE.parents[1]
if str(ROOT).startswith("/opt/workbuddy") or str(HERE).startswith("/opt/workbuddy"):
ROOT = Path("/opt/workbuddy")
for p in (HERE, SCRIPTS_ROOT, ROOT):
s = str(p)
if s not in sys.path:
sys.path.insert(0, s)附录 D:scripts_cursor/Higress部署/Higress_01_部署.py(完整)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""同步 Higress 补丁到 207 并执行 Compose standalone 部署。"""
from __future__ import annotations
import sys
from pathlib import Path
import _bootstrap # noqa: F401
import _config as C
from dify_api import Dify
ROOT = Path(__file__).resolve().parents[2]
LOCAL_PATCH = ROOT / "patches_cursor" / "Higress部署"
LOCAL_SH = ROOT / "scripts_bash_cursor" / "Higress部署" / "Higress_01_部署.sh"
REMOTE_PATCH = C.HIGRESS_PATCH_DIR
def sync_dir(d: Dify, local: Path, remote: str) -> None:
d.sh(f"mkdir -p '{remote}'")
for fp in local.rglob("*"):
if not fp.is_file():
continue
if fp.name.startswith(".") and fp.name not in (".env",):
continue
rel = fp.relative_to(local).as_posix()
rpath = f"{remote}/{rel}"
parent = "/".join(rpath.split("/")[:-1])
d.sh(f"mkdir -p '{parent}'")
d.sftp.put(str(fp), rpath)
print(f" put {rel}")
def main() -> int:
d = Dify(C.DIFY_EMAIL, C.DIFY_PASSWORD)
try:
try:
d.login()
except Exception as e: # noqa: BLE001
print("[WARN] Dify login 跳过:", e)
print("[INFO] sync patch →", REMOTE_PATCH)
sync_dir(d, LOCAL_PATCH, REMOTE_PATCH)
remote_sh = "/tmp/Higress_01_部署.sh"
d.sftp.put(str(LOCAL_SH), remote_sh)
d.sh(f"sed -i 's/\\r$//' '{remote_sh}' && chmod +x '{remote_sh}'")
out, err = d.sh(f"bash '{remote_sh}'")
print(out or "")
if err:
print(err)
raw, _ = d.sh(
f"curl -sS -o /dev/null -w '%{{http_code}}' http://127.0.0.1:{C.HIGRESS_CONSOLE_PORT}/ || echo FAIL"
)
print("[DEBUG] console http_code:", raw)
if "FAIL" in (raw or "") or (raw or "").strip() in ("000", ""):
print("[FAIL] Higress Console 未就绪")
return 1
print("[OK] Higress", C.HIGRESS_BASE, "| Console", C.HIGRESS_CONSOLE)
return 0
finally:
d.close()
if __name__ == "__main__":
sys.exit(main())附录 E:scripts_bash_cursor/Higress部署/Higress_01_部署.sh(完整)
#!/usr/bin/env bash
# 在 207 上安装 / 启动 Higress standalone(Docker Compose)
# 端口:Gateway 18080/18443 · Console 8001 · Nacos 8848
set -euo pipefail
PATCH="/opt/workbuddy/patches_cursor/Higress部署"
ENV_FILE="${PATCH}/install_options.env"
DEST="/opt/higress"
ENC_KEY="bocheng207higressenckey32chars!!"
HTTP_PORT=18080
HTTPS_PORT=18443
CONSOLE_PORT=8001
NACOS_PORT=8848
if [ -f "$ENV_FILE" ]; then
# shellcheck disable=SC1090
set -a; source "$ENV_FILE"; set +a
DEST="${HIGRESS_DEST:-$DEST}"
ENC_KEY="${DATA_ENC_KEY:-$ENC_KEY}"
HTTP_PORT="${GATEWAY_HTTP_PORT:-$HTTP_PORT}"
HTTPS_PORT="${GATEWAY_HTTPS_PORT:-$HTTPS_PORT}"
CONSOLE_PORT="${CONSOLE_PORT:-$CONSOLE_PORT}"
NACOS_PORT="${NACOS_PORT:-$NACOS_PORT}"
fi
if [ "${#ENC_KEY}" -ne 32 ]; then
echo "[FAIL] DATA_ENC_KEY 必须恰好 32 字符,当前 ${#ENC_KEY}"
exit 1
fi
echo "[INFO] 探测宿主机网关(供容器回访 LiteLLM/Dify/Xinference)"
HG="$(docker network inspect bridge -f '{{range .IPAM.Config}}{{.Gateway}}{{end}}' 2>/dev/null || true)"
if [ -z "$HG" ]; then
HG="172.17.0.1"
fi
echo "$HG" >"${PATCH}/host_gateway.ip"
echo "[INFO] HOST_GATEWAY=$HG"
# 端口占用检查(仅警告)
for p in "$HTTP_PORT" "$HTTPS_PORT" "$CONSOLE_PORT" "$NACOS_PORT"; do
if ss -lnt | grep -qE ":${p}\\s"; then
echo "[WARN] 端口 $p 已在监听;若非 Higress 占用请先释放"
fi
done
if [ -x "${DEST}/bin/startup.sh" ] || [ -f "${DEST}/docker-compose.yml" ] || [ -f "${DEST}/compose.yaml" ]; then
echo "[INFO] 检测到已有安装目录 $DEST,尝试启动"
if [ -x "${DEST}/bin/startup.sh" ]; then
"${DEST}/bin/startup.sh" || true
elif [ -x "${DEST}/bin/reload.sh" ]; then
"${DEST}/bin/reload.sh" || true
else
(cd "$DEST" && docker compose up -d) || true
fi
else
echo "[INFO] 首次安装 Higress → $DEST"
mkdir -p "$DEST"
TMP_SH="/tmp/get-higress.sh"
if ! curl -fsSL "https://higress.io/standalone/get-higress.sh" -o "$TMP_SH"; then
echo "[WARN] higress.io 失败,尝试 github raw"
curl -fsSL "https://raw.githubusercontent.com/higress-group/higress-standalone/main/get-higress.sh" -o "$TMP_SH" \
|| curl -fsSL "https://ghproxy.com/https://raw.githubusercontent.com/higress-group/higress-standalone/main/get-higress.sh" -o "$TMP_SH"
fi
chmod +x "$TMP_SH"
bash "$TMP_SH" "$DEST" \
-a \
--use-builtin-nacos \
--gateway-http-port="$HTTP_PORT" \
--gateway-https-port="$HTTPS_PORT" \
--console-port="$CONSOLE_PORT" \
--nacos-port="$NACOS_PORT" \
-k "$ENC_KEY"
fi
echo "[INFO] 等待 Console :$CONSOLE_PORT ..."
ok=0
for i in $(seq 1 90); do
code="$(curl -sS -o /dev/null -w '%{http_code}' "http://127.0.0.1:${CONSOLE_PORT}/" 2>/dev/null || echo 000)"
if [ "$code" != "000" ] && [ "$code" != "000000" ]; then
ok=1
echo "[INFO] Console HTTP $code"
break
fi
sleep 3
done
echo "[INFO] docker ps (higress|nacos|gateway|console):"
docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}' | grep -iE 'higress|nacos|gateway|console|NAME' || docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}' | head -n 30
if [ "$ok" != "1" ]; then
echo "[FAIL] Higress Console 未在预期时间内就绪"
(cd "$DEST" && docker compose ps -a) 2>/dev/null || true
exit 1
fi
echo "[OK] Higress Gateway http://192.168.110.207:${HTTP_PORT}"
echo "[OK] Higress Console http://192.168.110.207:${CONSOLE_PORT}"
echo "[OK] HOST_GATEWAY=$HG (路由后端请用此 IP 代替 127.0.0.1)"