# Caddy auto-HTTPS 在没 DNS 的开发/Phase 0 场景下会 308 redirect 把请求带走

> **日期**: 2026-05-14
> **类型**: 工具链陷阱 / 反代/TLS

## 现象

internal-app-platform Phase 0 在测试服 (43.166.182.155) 配 Caddy 反代：

```caddy
lijian-hello.apps.faradayfuture.com {
    reverse_proxy ffoa-app-lijian-hello:3000
}
```

容器跑得好好的（`docker logs` 显示 `listening on 3000`），但 `curl -H "Host: lijian-hello.apps.faradayfuture.com" http://127.0.0.1/` **返回空 body**。

`curl -v` 揭穿真相：

```
> GET / HTTP/1.1
< HTTP/1.1 308 Permanent Redirect
< Location: https://lijian-hello.apps.faradayfuture.com/
```

Caddy 把 HTTP 请求 308 强制改去 HTTPS。然后 Caddy 后台日志：

```
ACME challenge failed ... NXDOMAIN looking up A for lijian-hello.apps.faradayfuture.com
```

Let's Encrypt 验证一直拿不到证书（域名根本没在 DNS 注册），HTTPS 端口也起不起来 → 整条链路废。

## 根因

Caddy 默认 **auto-HTTPS = on**：只要 site 块的 host 不是 `:port` / `localhost` / IP，Caddy 就：

1. 把 HTTP（:80）站 308 强制重定向到 HTTPS
2. 后台调 Let's Encrypt 申 cert（HTTP-01 / TLS-ALPN-01 challenge）
3. 拿到证书前 HTTPS 端口拒连

Phase 0 / 开发环境的特点：**域名先有，DNS 后到**。Caddy 不会"先 HTTP 跑着、DNS 上线后再升 HTTPS"——它一开始就当生产配置走完整流程。

## 解决（已采纳）

site 名前面加 `http://` 显式声明只走 HTTP：

```caddy
http://lijian-hello.apps.faradayfuture.com {
    reverse_proxy ffoa-app-lijian-hello:3000
}
```

Caddy 看到 `http://` 就**完全跳过 auto-HTTPS**——不 308、不申 cert、不监听 :443。

deploy-container.sh 把 scheme 做成 env 可调：

```bash
CADDY_SCHEME="${INTERNAL_APP_CADDY_SCHEME:-http://}"
# DNS + LE 上线后改成 CADDY_SCHEME= 即可一行切回 auto-HTTPS
```

## 其它常见绕法（对比）

| 方案 | 适用 | 副作用 |
|---|---|---|
| `http://host {}` 前缀 | Phase 0 / 开发 | 一行切，干净 ✅ |
| 全局 `auto_https off` | 全站不要 HTTPS | 影响所有 site，太宽 |
| `auto_https disable_redirects` | 想要 HTTPS 但别强制 308 | 仍会申 cert → 仍 NXDOMAIN |
| 改用 `tls internal` | 完全离线场景 | curl 默认不信任 self-signed |
| 用 IP/`:port` 当 host | 仅本机调试 | 失去多 app 多 host 区分能力 |

## 适用面

- 任何"先用 IP / Host header 测，DNS 后补"的 Caddy 部署（开发、staging、PoC）
- 接 ACME 限流的场景（连续失败超 5 次 LE 会拉黑 1h，**这次差点中招**）
- 容器化反代 + 自动 TLS 的初始化阶段

## 状态

- [x] deploy-container.sh 默认 `http://` 前缀
- [x] 实测通过：`curl -H "Host: lijian-hello.apps.faradayfuture.com" http://43.166.182.155/` 返回 hello 内容
- [ ] DNS + wildcard cert 就绪后：`INTERNAL_APP_CADDY_SCHEME=` 重跑 deploy 即升 HTTPS
