7db64aedd9
Co-Authored-By: Claude Code <noreply@anthropic.com>
103 lines
6.0 KiB
Markdown
103 lines
6.0 KiB
Markdown
# Northflank 部署 xray / hysteria2(docker-for-ladder)
|
||
|
||
配套镜像仓库:[xyonium/docker-for-ladder](https://github.com/xyonium/docker-for-ladder)
|
||
(容器内 `start.sh <hy2配置路径> <xray配置路径> <cloudflared token>`,两个配置文件以
|
||
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 依然不行
|