docs: fix ACK manifest reachability and OD_ALLOWED_ORIGINS alias

Address PerishCode review on PR #3275:

- The daemon defaults to OD_BIND_HOST=127.0.0.1 (apps/daemon/src/server.ts),
  so the readinessProbe and ClusterIP Service in the previous manifest could
  never reach the Pod. Add OD_BIND_HOST=0.0.0.0 + OD_API_TOKEN (required by
  the bound-API-token guard for non-loopback binds) and a kubectl secret step.

- The daemon reads OD_ALLOWED_ORIGINS, not OPEN_DESIGN_ALLOWED_ORIGINS.
  OPEN_DESIGN_* names are Compose-only aliases mapped in deploy/docker-compose.yml.
  Use OD_ALLOWED_ORIGINS for the direct-container ACK path and call out both
  names in the network-exposure section and the pitfalls table.

Also adds an Ingress / Bearer-token note for operators fronting the
Service externally.
This commit is contained in:
dhaksdhakshin 2026-05-29 14:16:17 +05:30
parent 8b8ed68dbc
commit 9d5f6ec545

View file

@ -143,6 +143,20 @@ Set `OPEN_DESIGN_ALLOWED_ORIGINS` in `deploy/.env` to the public URL so CORS cle
Open Design does not yet ship an official Helm chart. The minimal manifest below is a starting point — production users should harden it (resource limits, PodDisruptionBudget, NetworkPolicy, persistent storage class).
> **Required env for Kubernetes:** the daemon defaults to `OD_BIND_HOST=127.0.0.1`, which makes the readiness probe (and the Service) unable to reach the container. To make the Pod reachable inside the cluster you must set `OD_BIND_HOST=0.0.0.0`, and the daemon's bound-API-token guard then requires `OD_API_TOKEN` to be set whenever it binds to a non-loopback interface. Both env vars are reflected in the manifest below.
>
> Also note that the daemon reads `OD_ALLOWED_ORIGINS` directly. The `OPEN_DESIGN_ALLOWED_ORIGINS` name documented in `deploy/.env.example` is a Compose-only alias mapped in `deploy/docker-compose.yml`; for the direct-container ACK path you must set `OD_ALLOWED_ORIGINS` instead.
Create the API-token secret first:
```bash
# Generate a random token and store it in the cluster
kubectl create secret generic open-design-secrets \
--from-literal=api-token="$(openssl rand -hex 32)"
```
Then apply the manifest:
```yaml
# open-design.yaml
apiVersion: apps/v1
@ -165,6 +179,15 @@ spec:
env:
- name: OD_DATA_DIR
value: /data
- name: OD_BIND_HOST
value: "0.0.0.0" # required so the readinessProbe and Service can reach the daemon
- name: OD_API_TOKEN
valueFrom:
secretKeyRef:
name: open-design-secrets
key: api-token # required whenever OD_BIND_HOST is non-loopback
- name: OD_ALLOWED_ORIGINS
value: "https://design.example.cn" # set when fronting with an Ingress; daemon reads OD_*, not OPEN_DESIGN_*
volumeMounts:
- name: data
mountPath: /data
@ -191,7 +214,7 @@ spec:
targetPort: 7456
```
Apply with `kubectl apply -f open-design.yaml`. Front the Service with an Ingress (NGINX Ingress Controller is preinstalled on ACK Pro) and an ACM-issued certificate.
Apply with `kubectl apply -f open-design.yaml`. Front the Service with an Ingress (NGINX Ingress Controller is preinstalled on ACK Pro) and an ACM-issued certificate. With `OD_API_TOKEN` set, every `/api/*` request from non-loopback origins must carry an `Authorization: Bearer <token>` header — wire that into your Ingress / proxy auth layer.
> **Note on `replicas: 1`:** the daemon writes SQLite at `.od/app.sqlite` (see [`AGENTS.md`](../../../AGENTS.md) FAQ "Where is data written?"). Running multiple replicas without shared storage will diverge state. A multi-replica ACK topology needs an external database; that is out of scope for this guide.
@ -237,7 +260,7 @@ Open Design's daemon binds to `127.0.0.1:7456` and is never exposed directly. Pu
1. A reverse proxy that terminates TLS (Nginx, Caddy, Alibaba Cloud SLB/ALB).
2. An ICP-filed domain (for mainland regions).
3. CORS allowlist set via `OPEN_DESIGN_ALLOWED_ORIGINS`.
3. CORS allowlist set via `OPEN_DESIGN_ALLOWED_ORIGINS` (Compose / `deploy/.env` path) or `OD_ALLOWED_ORIGINS` (direct-container / Kubernetes path).
See [`docs/install-guide.md`](../../install-guide.md) for the full topology and reverse-proxy guidance.
@ -249,7 +272,8 @@ See [`docs/install-guide.md`](../../install-guide.md) for the full topology and
| HTTP/HTTPS to your domain is blocked | Domain not ICP-filed for a mainland region | Complete ICP filing, or move to a non-mainland region (HK/SG) |
| `aliyun ecs RunInstances` fails with "Real-name authentication required" | Account not 实名认证 | Complete real-name verification in the account console |
| ACK pods stuck in `ImagePullBackOff` from a private ACR repo | Cluster lacks pull credentials for the namespace | Create an `aliyun-acr-credential-helper` secret or use the cluster's ACR plugin |
| 200 from `/api/health` but UI fails to load | CORS rejecting the proxied origin | Set `OPEN_DESIGN_ALLOWED_ORIGINS` to the public URL |
| 200 from `/api/health` but UI fails to load | CORS rejecting the proxied origin | Set `OPEN_DESIGN_ALLOWED_ORIGINS` (Compose / `deploy/.env`) or `OD_ALLOWED_ORIGINS` (direct container / ACK) to the public URL |
| ACK Pod stuck in `NotReady`, readiness probe fails | Daemon defaulting to `OD_BIND_HOST=127.0.0.1` so the kubelet can't reach it | Set `OD_BIND_HOST=0.0.0.0` and `OD_API_TOKEN` in the Pod env (the daemon refuses non-loopback binds without a token) |
| SLB health check fails | SLB hits `7456` but security group blocks intra-VPC | Allow the SLB backend CIDR on `7456/tcp` in the security group |
## Follow-up work