Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ RUN cd gui && bun run build
FROM ${BUN_IMAGE} AS runtime
WORKDIR /home/bun/app

# Docker supervises this foreground process; retain routed state on stop/recreate.
# This uses the existing service lifecycle mode and does not install a service manager.
ENV NODE_ENV=production \
OCX_SERVICE=1 \
OPENCODEX_HOME=/home/bun/.opencodex \
CODEX_HOME=/home/bun/.codex \
OCX_API_TOKEN_FILE=/home/bun/.opencodex/service-api-token
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Container lifecycle mode

Amendment after real Docker recreation verification. Docker supervises the foreground hub and must retain persisted routed state across replacement.

MODIFY Dockerfile runtime ENV: set existing OCX_SERVICE=1, with no service manager installation or privilege change. Preserve image digest, foreground CMD, listener authentication, separate writable homes and read-only root.
MODIFY scripts/ci/docker-smoke.ts: assert the actual container process receives service lifecycle mode. Retain the routed synthetic slug and exact token/catalog/config hashes across graceful recreation.
MODIFY tests/service/container-bootstrap.test.ts: include the runtime ENV declaration in the existing packaging contract.
MODIFY docs-site/src/content/docs/guides/remote-hub.md: document service-mode foreground lifecycle, Compose restart/recreation, and the limit on other dashboard restart paths.

Independent Astra high lifecycle/security review accepted the bounded packaging change. Actual remote CLI comparison confirmed preservation with service mode. Final image CI must prove the same real container lifecycle; no local tests or Docker execution. This does not change shared CLI cleanup, restart policy, or authentication code.
6 changes: 5 additions & 1 deletion docs-site/src/content/docs/guides/remote-hub.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,11 @@ opencodex does not publish an official container image. The repository does main
[`compose.yaml`](https://github.com/lidge-jun/opencodex/blob/main/compose.yaml), and a narrow
`.dockerignore`. The build pins the multi-platform Bun 1.4.0 image index by digest, runs the proxy as
the non-root `bun` user, keeps the root filesystem read-only, drops Linux capabilities, and publishes
only the data listener on the host's `127.0.0.1:10100` by default.
only the data listener on the host's `127.0.0.1:10100` by default. The foreground process uses
`OCX_SERVICE=1`, so stopping or recreating the container preserves routed Codex state instead
of restoring a native desktop configuration. Docker supplies supervision; no OS service manager
is installed in the image. Use Compose to restart/recreate the container; this does not extend
support to every dashboard restart path.

The image seeds a first-run `hub` configuration that binds the container listener to `0.0.0.0`.
Before the first normal start, stream a freshly generated data-plane token into the bootstrap helper.
Expand Down
25 changes: 24 additions & 1 deletion docs-site/src/content/docs/reference/proxy-formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,30 @@ default provider is enabled and is not itself an OpenAI-family entry; account-qu
such as `side/gpt-5.6-sol` still fail closed. The proxy logs one notice per provider when this
fallback engages. Configurations with an enabled canonical `openai` provider are unchanged.

Native compact responses are buffered with a 32 MiB maximum, including responses whose declared
Inbound bodies on both `/v1/responses` and `/v1/responses/compact` retain the shared 256 MiB
wire/decompression admission limit. Application-level size rejection returns HTTP 413 with
`type` and `code` both `invalid_request_error`. Its message includes a bounded diagnostic suffix,
for example:

```text
Decompressed request body exceeds 268435456 bytes [measurement=decoded_lower_bound; bytes=268435457]
```

| Measurement | Meaning of `bytes` |
| --- | --- |
| `declared_wire` | Numeric `Content-Length` declared by the sender; rejected before reading, not a measured decoded size |
| `observed_wire_lower_bound` | Wire bytes encountered when reading stopped; the complete body may be larger |
| `decoded_exact` | Exact size of the buffer supplied to the identity decoder or returned by a decoder |
| `decoded_lower_bound` | Admission limit plus one after inflation aborts; a lower bound, never the exact decoded size |

The suffix contains only a fixed category and a finite numeric byte value. Rejected bodies are
not read or inflated further, parsed for item counts, or retained for diagnostics. Legacy errors
without measurement provenance retain the limit-only message. Bun's listener can reject an
oversized wire body before application diagnostics run, so not every 413 carries this suffix.
A lower-bound diagnostic cannot establish the complete compact payload size. The admission
limit and retry behavior are unchanged.

Native compact responses are buffered with a separate 32 MiB maximum, including responses whose declared
`Content-Length` already exceeds the limit. The compact-specific failures include:

| Status | Type or code | Meaning |
Expand Down
Loading
Loading