---
date: 2026-05-03
topic: Temporal worktree 起不来时的 host-network 绕行
tags: [temporal, docker, worktree, dev-env]
---

# 现象

某 worktree 没有自己的 Temporal 容器；`bash scripts/dev/dev.sh up --temporal` 报：

```
Bind for 0.0.0.0:4002 failed: port is already allocated
```

# 根因

worktree 的 docker compose 在 setup 时换过 `CONTAINER_PREFIX`（旧 `ffws-wt-pg-4002` / `ffws-wt-redis-4003` → 新 `ffoa-wt-approval-form-polish-*`）。
- 老 pg/redis 容器仍在跑且占用 4002/4003 端口；
- 新 prefix 的 named volumes（`ffoa-wt-approval-form-polish_postgres_data`）已存在但是空的；
- 新 compose 想再创一套 pg/redis，端口冲突。

直接 `docker rm -f ffws-wt-pg-4002` 会丢已 seed 的开发库（数据卷是匿名 volume，不是 named volume，跟着容器一起删）。

# 解法（绕行）

不用 compose 起 Temporal，直接 `docker run --network host` 让 temporal 进程通过 host 端口连到现有 pg：

```bash
docker run -d --name <prefix>-temporal --network host --restart unless-stopped \
  -e DB=postgres12 \
  -e DB_PORT=4002 \
  -e POSTGRES_USER=ffoa_dev -e POSTGRES_PWD=dev_password \
  -e POSTGRES_SEEDS=localhost \
  -e BIND_ON_IP=0.0.0.0 \
  -e TEMPORAL_BROADCAST_ADDRESS=127.0.0.1 \
  -e FRONTEND_GRPC_PORT=4033 -e FRONTEND_HTTP_PORT=4034 \
  temporalio/auto-setup:1.25.2

# 注册 namespace（注意 4033，不是默认 7233）
docker exec <prefix>-temporal tctl --address localhost:4033 \
  --namespace <ns> namespace register --retention 3

# UI（host 网络 + 直连 4033）
docker run -d --name <prefix>-temporal-ui --network host --restart unless-stopped \
  -e TEMPORAL_ADDRESS=localhost:4033 \
  -e TEMPORAL_UI_PORT=4080 \
  -e TEMPORAL_CORS_ORIGINS=http://localhost:4000 \
  temporalio/ui:2.44.0
```

# 几个易踩的坑

1. **auto-setup 容器日志一直刷 `dial tcp 0.0.0.0:7233: connect: connection refused`** —— 那是镜像内置 wait 脚本死循环检查 7233（默认端口）；我们把 `FRONTEND_GRPC_PORT` 改成 4033 后真实端口在 4033 上，wait 永远等不到。**Temporal 服务本身已经起来了**，看 grpc tcp 端口监听确认 + 直接 `tctl --address localhost:4033` 验证。

2. **tctl 默认连 7233**：`docker exec ... tctl namespace register` 要显式 `--address localhost:4033`，否则连不上自己的 server。

3. **TEMPORAL_BROADCAST_ADDRESS** 必须设 `127.0.0.1`（host 网络下广播 0.0.0.0 给集群成员会让自己找不到自己）。

4. **backend/.env 与根 .env 的 TEMPORAL_ADDRESS 可能不同步**：本仓库根 `.env` 是 4033 但 `backend/.env` 留着别的 worktree 的 3133。改时两个都要改。namespace 同样要对齐。

# 适用范围

- 多 worktree 并存、CONTAINER_PREFIX 已被改名导致 compose 想重建 pg；
- 想给某个 worktree 临时补一个 Temporal 但不愿动现有数据库；
- 不需要持久化 Temporal 自己的 schema（host postgres 重启 / DB 重置就丢；这种用法是给 dev/E2E 验证用，不是生产）。

# 不要这么做的场景

UAT/生产部署，仍走标准 compose（`--profile temporal`）+ named volumes + 独立 pg。
