
TensorZero 部署实战用 NGINX Bearer Token 为 TGI 搭建安全持久推理端点【免费下载链接】tensorzeroTensorZero is an open-source LLMOps platform that unifies an LLM gateway, observability, evaluation, optimization, and experimentation.项目地址: https://gitcode.com/GitHub_Trending/te/tensorzero导读TensorZero 是一个开源的 LLMOps 平台将 LLM 网关、可观测性、评估、优化与实验统一于一体。为了让端到端E2E测试始终拥有一个持久、安全、可复用的文本生成推理TGI端点TensorZero 在仓库中提供了一个名为tensorzero/tgi-nginx的定制 Docker 镜像它把 Hugging Face 的 Text Generation Inference 包装在 NGINX 反向代理之后由 NGINX 负责 Bearer Token 鉴权。读完本文你将掌握该镜像的设计原理Dockerfile、NGINX 配置、入口脚本三者的配合方式、完整的docker run启动命令与参数含义以及如何把这样一个受保护端点接入 TensorZero 的模型配置与 E2E 测试体系。本文核心素材来自 tgi-nginx/README.md并深入其同目录下的 Dockerfile、default.conf、entrypoint.sh 以及 TensorZero 的 TGI Provider 实现与 E2E 测试配置进行佐证。一、为什么需要TGI 套 NGINX的镜像在 TensorZero 的 E2E 测试体系中多个测试用例需要调用真实的大模型推理端点。与一次性拉起测试环境不同E2E 测试希望有一个**持久persistent**的服务端点它长期在线、地址稳定从而避免每次测试都重新冷启动模型服务。但持久也意味着暴露。如果 TGI 直接裸奔在网络上任何人都可以调用它既消耗算力也存在安全风险。因此 TensorZero 的思路很直接用 NGINX 作为反向代理挡在 TGI 前面通过 Bearer Token 做鉴权只有携带正确令牌的请求才能穿透到后端的 TGI 服务。这一模式被固化成了一个可复用的 Docker 镜像tensorzero/tgi-nginxREADME 中明确说明其用途是 provide a persistent secure endpoint serving TGI for our E2E tests。仓库中还有一个同构的 sgl-nginx 镜像SGLang 版本两者的 Dockerfile、NGINX 配置与入口脚本几乎完全一致只是基础镜像和推理进程不同可见这是 TensorZero 测试基建中反复使用的一套成熟模式。二、镜像结构拆解三层组件如何协作整个镜像由三个文件构成各自职责单一、组合清晰。下面逐一分析。2.1 Dockerfile在 TGI 官方镜像上叠加 NGINXDockerfile 的内容如下FROM ghcr.io/huggingface/text-generation-inference:latest # Install nginx and remove default site RUN apt-get update apt-get install -y nginx \ rm -rf /var/lib/apt/lists/* \ rm /etc/nginx/sites-enabled/default # Copy the nginx config COPY default.conf /etc/nginx/conf.d/default.conf # Copy our entrypoint script COPY entrypoint.sh /entrypoint.sh RUN chmod x /entrypoint.sh # Nginx listens on port 80; TGI will listen on 8081 EXPOSE 80 # Entrypoint runs TGI and nginx ENTRYPOINT [/entrypoint.sh]关键设计点基础镜像直接采用官方ghcr.io/huggingface/text-generation-inference:latest保证 TGI 运行时与官方一致避免重复维护推理依赖安装nginx后删除默认站点/etc/nginx/sites-enabled/default防止默认配置抢占 80 端口或干扰代理规则自定义的default.conf被放置到/etc/nginx/conf.d/default.confnginx 启动时会自动加载conf.d下的所有配置端口分工EXPOSE 80只暴露 NGINX 端口容器内 TGI 则监听8081注释写得很清楚Nginx listens on port 80; TGI will listen on 8081入口固定为entrypoint.sh由它负责串联起 TGI 与 NGINX 两个进程。2.2 default.confBearer Token 校验 反向代理default.conf 是鉴权逻辑的核心全文如下server { listen 80; location / { # Default token check fails set $valid_token 0; # Compare provided Authorization header to environment-substituted token if ($http_authorization Bearer _MY_SECRET_) { set $valid_token 1; } # If no match, return 401 if ($valid_token 0) { return 401; } # Otherwise, proxy to TGI proxy_pass http://127.0.0.1:8081; } }实现逻辑非常朴素但有效通过set $valid_token 0;默认把令牌校验标记置为失败比较请求的Authorization头是否严格等于Bearer _MY_SECRET_。注意_MY_SECRET_只是一个占位符真实令牌由入口脚本在容器启动时用sed替换进去详见下一节若匹配则置valid_token 1否则直接return 401拒绝访问校验通过后proxy_pass把请求转发给同容器内127.0.0.1:8081上的 TGI 服务。这种占位符 启动期注入的方式有一个好处镜像本身是公开可构建、可审计的真正的密钥不写入镜像层而是在运行时通过环境变量注入避免令牌被固化进镜像历史。2.3 entrypoint.sh令牌注入 双进程编排entrypoint.sh 负责容器启动时的完整编排#!/bin/bash # Replace placeholder in nginx config with real token from env if [ -z $BEARER_TOKEN ]; then echo Missing BEARER_TOKEN env var. Exiting. exit 1 fi # Replace placeholder in nginx config with real token from env sed -i s#_MY_SECRET_#${BEARER_TOKEN}#g /etc/nginx/conf.d/default.conf ldconfig 2/dev/null || echo Note: Unable to refresh dynamic linker cache. This is expected in some container environments and will not affect functionality. # Run TGI in background; pass all command-line args directly text-generation-launcher --port 8081 $ # Start nginx in the foreground exec nginx -g daemon off;脚本的几个关键行为强校验令牌若未设置BEARER_TOKEN环境变量立即报错并以非零码退出杜绝无鉴权裸奔的隐患运行时注入密钥用sed -i s#_MY_SECRET_#${BEARER_TOKEN}#g把 nginx 配置中的占位符替换成真实令牌。这里使用#作为sed的分隔符可以安全容纳包含/的令牌值TGI 后台启动text-generation-launcher --port 8081 $ —— 强制 TGI 监听8081与 nginx 的proxy_pass严格对齐并把docker run后传入的所有命令行参数原样透传给 TGI这正是 README 中无需手动指定--port的原因nginx 前台运行exec nginx -g daemon off;让 NGINX 以前台进程方式运行并接管容器 PID 1保证容器生命周期与 NGINX 一致——NGINX 退出即容器退出ldconfig的调用是为了刷新动态链接器缓存确保 TGI 二进制在容器环境能正确加载依赖库失败也不影响功能脚本会打印提示继续运行。三、实战用 docker run 拉起受保护的 TGI 端点README 给出的完整用法如下docker run \ -p 8080:80 \ # Map port 8080 of the host to port 80 of the container # (can change this, but the container will listen on port 80) -e BEARER_TOKENSUPER_SECRET_TOKEN \ # Set the BEARER_TOKEN environment variable to your secret token tensorzero/tgi-nginx:latest \ --model-id microsoft/Phi-3.5-mini-instruct \ # The model to serve --max-input-length 1024 \ --max-total-tokens 2048 \ --max-batch-prefill-tokens 1024 \ --quantize fp8 # Do not pass --port here, it is set by the container逐段解读部分说明-p 8080:80把宿主机8080端口映射到容器80端口即 NGINX 监听端口。宿主端口可以任意调整但容器侧必须是80对外访问地址为http://宿主机:8080-e BEARER_TOKENSUPER_SECRET_TOKEN设置鉴权令牌。这是必填环境变量缺失时入口脚本会直接退出。请务必替换为你的高强度随机令牌tensorzero/tgi-nginx:latest镜像名。docker run之后的所有参数--model-id等都会原样透传给容器内的text-generation-launcher--model-id microsoft/Phi-3.5-mini-instruct指定要加载的 Hugging Face 模型仓库 E2E 测试实际使用phi-3.5-mini-instruct系列模型--max-input-length 1024限制单次请求的最大输入 token 数防止超长输入拖垮服务--max-total-tokens 2048限制单次请求输入 输出的总 token 上限配合上面的输入限制间接约束输出长度--max-batch-prefill-tokens 1024控制 prefill 阶段单批最多处理的 token 数是 TGI 吞吐与显存占用的平衡点--quantize fp8以 FP8 精度量化加载模型显著降低显存占用适合消费级 GPU 或测试环境--port禁止传入。该参数由容器内入口脚本固定为8081传入自定义值会导致 NGINX 代理与 TGI 端口失配启动成功后验证方式非常简单# 不带令牌访问 → 应返回 401 curl -i http://localhost:8080/v1/chat/completions # 携带正确令牌访问 → 请求被代理到 TGI 并正常处理 curl -i http://localhost:8080/v1/chat/completions \ -H Authorization: Bearer SUPER_SECRET_TOKEN \ -H Content-Type: application/json \ -d {model: ..., messages: [{role: user, content: Hello}]}四、接入 TensorZero把受保护端点配成模型镜像搭建好后只需在 TensorZero 配置中声明一个tgi类型的模型并把api_base指向 NGINX 的对外端口即可。E2E 测试的真实配置见 tensorzero.models.toml[models.phi-3.5-mini-instruct-tgi] routing [tgi] [models.phi-3.5-mini-instruct-tgi.providers.tgi] type tgi api_base https://zr0gj152lrhnrr-80.proxy.runpod.net/v1/对应的函数变体配置见 tensorzero.functions.basic_test.toml中测试同时覆盖了正常调用tgi、附加请求体tgi-extra-body以及携带错误鉴权头tgi-extra-headers其extra_headers中设置了Authorization: invalid_tgi_auth三种场景——后者正是用来验证 NGINX 会拒绝错误令牌、返回 401 的用例。在 providers/tgi.rs 的测试注册中TGI 端点的能力边界也被明确标注supports_batch_inference: false不支持批量推理、无工具调用、无嵌入、无缓存输入 token 测试等。这与 tgi.rs 源码 中声明的已知限制一致TGI 对流式工具调用、多工具请求、工具响应回传支持不完善因此 TensorZero 对 TGI不显式支持工具调用仅通过tool方式支持 JSON 模式。如果你的业务依赖工具调用应优先选择其他 Provider。五、原理小结与延伸阅读核心原理一句话tgi-nginx镜像通过入口脚本在启动期把BEARER_TOKEN注入 NGINX 配置由 NGINX 在80端口完成 Bearer 鉴权后反向代理到容器内8081端口的 TGI从而以最小改动得到一个鉴权前置、推理后置的安全持久端点。可继续深入仓库的入口tgi-nginx 完整部署目录README、Dockerfile、default.conf、entrypoint.sh 四件套同构的 SGLang 版本 sgl-nginx 部署目录TensorZero 的 TGI Provider 实现 src/providers/tgi.rs内含完整的能力限制说明与流式/非流式实现细节E2E 测试注册文件 tests/e2e/providers/tgi.rs展示了该端点在测试矩阵中的全部使用场景。这套推理服务 反向代理鉴权的镜像模板同样适用于企业内部把自建推理端点安全地暴露给网关或测试流水线的场景只要替换--model-id与BEARER_TOKEN即可复用到任何 TGI 兼容模型上。【免费下载链接】tensorzeroTensorZero is an open-source LLMOps platform that unifies an LLM gateway, observability, evaluation, optimization, and experimentation.项目地址: https://gitcode.com/GitHub_Trending/te/tensorzero创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考