Files

6.9 KiB
Executable File
Raw Permalink Blame History

Fixed public deployment

The public demo is hosted directly on the server at https://511.kendeji.fun. Caddy terminates HTTPS and proxies only to the container port bound on 127.0.0.1:8511; the application port is not exposed to the public network.

The server layout is:

/opt/511-project/
├── .env                 # OpenAI connection settings, mode 0600
├── .env.auth            # Web authentication settings, mode 0600
├── deploy/server/
├── artifacts/runs/      # Persistent request artifacts
├── artifacts/user-presets/
├── artifacts/server/    # GSCU infrared catalog and server-side state
├── artifacts/tmp/       # Runtime gateway and calibration state
├── artifacts/self-repair/
└── artifacts/mode-profiles/ # User-created modes for all vehicles

User-created function modes are persisted from the ignored host path artifacts/mode-profiles/ into the service's separate writable user-mode registry at /app/artifacts/mode-profiles/, including common and future vehicle-specific modes. Preset files under /app/config/modes remain read-only and are never modified.

Build and start the service:

cd /opt/511-project
mkdir -p \
  artifacts/runs \
  artifacts/user-presets \
  artifacts/server \
  artifacts/tmp \
  artifacts/self-repair \
  artifacts/mode-profiles
chown -R 10001:10001 \
  artifacts/runs \
  artifacts/user-presets \
  artifacts/server \
  artifacts/tmp \
  artifacts/self-repair \
  artifacts/mode-profiles
chmod 0700 \
  artifacts/runs \
  artifacts/user-presets \
  artifacts/server \
  artifacts/tmp \
  artifacts/self-repair \
  artifacts/mode-profiles
docker compose -f deploy/server/compose.yaml up -d --build
docker compose -f deploy/server/compose.yaml ps

镜像固定安装 @openai/codex@0.150.0-alpha.8。AI 助手使用命名卷 codex_home 保存 Codex 运行状态。N7Web 会在 App Server 启动握手期间验证模型认证, 认证缺失或初始化失败时不会把 /api/health 误报为 ready。

若 .env 同时设置 OPENAI_BASE_URL 和 OPENAI_API_KEY,且地址不是 OpenAI 官方 默认地址,N7Web 会为每个助手线程注入一个完整、固定的 OpenAI-compatible provider: base_url 使用该地址,密钥只通过 provider 的 env_key=OPENAI_API_KEY 从子进程环境 读取,不会出现在命令行、状态或日志中。这一步是必须的;Codex 内置 openai provider 不会把应用的 OPENAI_BASE_URL 自动当作模型端点。

若未设置自定义 OPENAI_BASE_URL,则使用 Codex 内置 OpenAI provider。已有 codex_home/auth.json 时复用现有登录;没有缓存登录但设置了 OPENAI_API_KEY 时, N7Web 通过 App Server 的 API-key 登录接口完成初始化,Codex 会把认证状态写入 codex_home。因此该命名卷属于含凭据的持久数据,应限制管理员访问并纳入密钥轮换 流程。不要把 auth.json 复制进镜像、日志或仓库。仅设置 CODEX_API_KEY 不会让固定 版本的 App Server 自动登录。

若使用 ChatGPT 账号认证,推荐在无浏览器的服务器上执行 device-code 登录;普通网页 OAuth 依赖容器内 localhost 回调,容易在 headless 环境失败。登录完成后重启服务:

docker compose -f deploy/server/compose.yaml run --rm web codex login --device-auth
docker compose -f deploy/server/compose.yaml restart web
docker compose -f deploy/server/compose.yaml exec web codex login status
curl -fsS http://127.0.0.1:8511/api/health

App Server 线程采用 read-only sandbox 和线程级 approvalPolicy=never,并关闭 内置 shell、统一执行器、浏览器和应用工具;因此命令执行或文件修改不能通过交互式 审批获得额外权限。Codex 子进程只继承启动及模型认证所需的环境变量。容器使用无特权 UID 10001 和只读根文件系统。

唯一启用的 n7_vehicle MCP 服务将工具级 default_tools_approval_mode=approve 固定为 approve。这与 approvalPolicy=never 不矛盾:前者仅避免 App Server 对已经进入 N7Web 安全边界的 MCP 调用再发起一次当前嵌入式网页无法响应的审批,后者仍让 App Server 自身的命令和 文件权限失败关闭。MCP 只开放运行时能力目录查询和回环地址上的座舱执行桥,其中只有 执行桥有副作用。工具令牌绑定原始用户请求,结构化候选计划还会经过原文证据、能力 注册表、参数 Schema、执行模式、车辆硬件审批与安全策略校验;模型不能提交替代指令 或原始 CAN,approve 也不会绕过这些应用层门禁。审批字段语义见 Codex App Server 官方文档 与 Codex 配置参考。

Add deploy/server/Caddyfile.example to the host Caddyfile, validate, and reload Caddy:

caddy validate --config /etc/caddy/Caddyfile
systemctl restart caddy

This host disables Caddy's admin endpoint, so caddy reload and systemctl reload caddy cannot apply configuration. Validate first, then use a service restart.

Operational checks:

curl -I https://511.kendeji.fun/
docker compose -f /opt/511-project/deploy/server/compose.yaml logs --tail=100
systemctl status caddy

Never place .env, .env.auth, API keys, login passwords, or SSH credentials inside the image or source control. Updating the application uses the same source synchronization followed by docker compose ... up -d --build.

Public physical-bench gateway

When the physical T2G bench is attached to a separate trusted workstation, Caddy may prefer a restricted reverse-SSH upstream on 127.0.0.1:18512 and retain the container on 127.0.0.1:8511 as the unavailable-bench fallback. The workstation service must use the same .env.auth as the public container; the SSH key must be restricted to that single reverse-listen port and must not be allowed to run remote commands.

Public physical execution uses a local-approval lease. A browser first submits an access request, and the bench operator chooses one terminal at http://127.0.0.1:8000/hardware-control. The decision API is restricted to unproxied loopback traffic, so it cannot be used through the public domain or the SSH tunnel. The approved terminal may run multiple tests; its lease is revoked after 180 seconds without a physical test, on voluntary release, or by the local operator. A process restart clears all leases and pending requests.

Inside the approved lease, the physical bench remains a process-wide single-flight resource. A hardware action owns the bench from intent planning through final physical feedback. Concurrent actions and passive physical-state reads receive HTTP 409 (hardware_busy) with Retry-After; they never enter the CAN path or wait to run later against stale position state. Dry-run and simulated-hardware requests are not serialized by this action-level gate.