# Northflank 部署 xray / hysteria2(docker-for-ladder) 配套镜像仓库:[xyonium/docker-for-ladder](https://github.com/xyonium/docker-for-ladder) (容器内 `start.sh `,两个配置文件以 Northflank secret group 的 files 形式挂载)。 ## 协议可行性结论(2026-09 调研) Northflank 普通 service 端口的公网入口是**强制边缘 ingress**:TLS 在平台边缘终结, 容器内进程只收到明文 HTTP/1.1 或 H2。这就是"前面必须有个自己的 CDN 反代"的真相—— 不是可选项,是架构本身。 | 协议 | 普通端口 | 付费 L4 Load Balancer | |---|---|---| | VLESS+REALITY | ❌ 不可行(TLS 被边缘终结,xray 看不到 ClientHello;TCP 端口不能公开) | ✅ 可行(L4 纯 TCP 直通、不终结 TLS;REALITY 不需要自己有证书) | | Hysteria2(UDP/QUIC) | ❌ 不可行(UDP 不能公开) | ✅ 可行(UDP 类型 L4 LB;证书用 DNS-01 或自签,HTTP-01 不可行) | | **XHTTP / WS / gRPC** | ✅ **可行(免费层即可,官方明确支持 WS/gRPC over HTTP(S))** | 不需要 | L4 LB 注意:team 级付费资源(metered billing);每个 LB 最多 100 端口,30000-32767 保留不可用;更新配置会重新供给、**公网 IP 可能变化**(自备域名 A 记录跟进); 代理流量计 egress($0.06/GB)。 依据: - [configure-ports(TCP/UDP 不能公开)](https://northflank.com/docs/v1/application/network/configure-ports) - [networking-on-northflank(TLS 边缘终结)](https://northflank.com/docs/v1/application/network/networking-on-northflank) - [configure-load-balancers(L4 TCP/UDP 直通)](https://northflank.com/docs/v1/application/network/configure-load-balancers) ## xray:XHTTP(唯一免费路径,推荐配置) `xray-config.template.json` 按 vpsetup 最优实践编写,与 VPS 版的关键差异: - **`security: "none"`**:TLS 由 Northflank 边缘终结,容器内必须明文 HTTP,不要再开 TLS/REALITY - **`listen: 0.0.0.0`**:平台 router 要连进来,不能绑 127.0.0.1 - **客户端 `flow` 必须留空**:xtls-rprx-vision 依赖裸 TCP,HTTP 传输下不可用 - XHTTP `mode: auto` + `extra` xPadding(queryInHeader/tokenish):**服务端 extra 必须与 客户端链接的 `extra=` 参数逐字节一致**(vpsetup commit 4e4d0f4 的部署形态; 服务端单方面加 padding 会让所有客户端 400——commit 15d91b2 的教训) 占位符替换:`__XRAY_UUID__`(`xray uuid` 生成,**固定下来不要重启重新生成**)、 `__XHTTP_PATH__`(随机长串,不含斜杠)、`__XPADDING_HEADER__`/`__XPADDING_KEY__` (如 `X-a1b2` / `_c3d4`)。容器内监听端口(模板 8443)必须与 service 端口配置里 **public** 端口的 internalPort 一致;公网入口只保留这一个 public HTTP 端口即可—— 实测旧 template 把 REALITY inbound 挂在 private 443 上(private + 边缘终结 TLS, 双重失效),优化时已连同该端口一并移除。 客户端链接模板(path 和 extra 都要 URL-encode): ``` vless://__XRAY_UUID__@__PUBLIC_DOMAIN__:443?encryption=none&security=tls&sni=__PUBLIC_DOMAIN__&fp=chrome&type=xhttp&path=%2F__XHTTP_PATH__&mode=auto&extra=%7B%22xPaddingObfsMode%22%3Atrue%2C%22xPaddingMethod%22%3A%22tokenish%22%2C%22xPaddingPlacement%22%3A%22queryInHeader%22%2C%22xPaddingHeader%22%3A%22__XPADDING_HEADER__%22%2C%22xPaddingKey%22%3A%22__XPADDING_KEY__%22%7D#nf-xhttp ``` `__PUBLIC_DOMAIN__` 是 Northflank 给端口分配的 `*.code.run` 域名或自定义域名 (可在 service 端口页查看)。客户端侧:ALPN 用 `http/1.1` 最稳;XHTTP 的 H3 模式 不可用(边缘无 UDP);若给 subdomain 开了 Northflank CDN(Fastly),客户端↔Fastly 可 H3,Fastly↔源站仍 H2。 WS 兼容:WS 已被 xray 官方弃用(26.x 启动即告警)。如必须兼容旧 WS 客户端, 在配置里加一个 WS inbound(`network: "ws"` + `wsSettings.path`),并在 Northflank service 上加第二个端口映射(独立 internalPort)。新客户端一律用 XHTTP。 ## hysteria2(可选,需 UDP L4 LB) `hysteria-config.template.yaml`:占位符 `__HY2_DOMAIN__` `__EMAIL__` `__CF_API_TOKEN__` `__HY2_PASSWORD__`。注意容器里 ACME 只能走 DNS-01 (80/443 归边缘),或用自签 + 客户端 `insecure=1`。不开 UDP L4 LB 时 hy2 端口 公网不可达,但配置留着无害(start.sh 会正常拉起,仅项目内网可见)。 ## healthcheck:写进 template,不要在 service 级加 service 级的 health check 会在下次 template 同步时被覆盖。正确做法: team → templates → scilad → **edit as code**,找到 `erepr-docker-for-ladder` 的 `DeploymentService` 节点,在其 `spec` 里加(字段约束见 [OpenAPI](https://api.northflank.com/v1/swagger-json):protocol 枚举 HTTP/CMD/TCP, periodSeconds 最小 10): ```json "healthChecks": [ { "protocol": "TCP", "type": "livenessProbe", "port": 8443, "initialDelaySeconds": 15, "periodSeconds": 30, "timeoutSeconds": 5, "failureThreshold": 3 } ] ``` **为什么用 TCP 不用 HTTP**:xray 的 XHTTP 端口对未认证 GET 返回非 2xx(实测 404), HTTP 探针会误判失败;TCP 探针只验证"端口在监听",与代理协议无关。 hy2 的 UDP 端口无法被探测(Northflank 无 UDP 探针)——也不需要:`start.sh` 用 `wait -n` 等所有后台进程,任一进程(xray/hysteria/cloudflared)退出容器即退出, 平台自动重启,进程级守护已由入口脚本覆盖。 ## 其他注意事项 - **egress 计费**:代理流量即出站流量,$0.06/GB,免费层也不例外 - secret group 里 `secrets.files` 挂配置文件;uuid/密码等敏感值建议放模板 `argumentOverrides`(`${fn.randomSecret(...)}` 生成后固定,重跑不换)而非模板正文 - 镜像里还有 cloudflared(`start.sh` 第 3 参):可作为 CF Tunnel 备用入口, 同样只承载 HTTP(S),REALITY/hy2 依然不行