Skip to content

[Bug] Docker foreground start blocks native requests when systemd ownership is unprovable #1612

Closed

Description

@nbsp1221

Client or integration

Codex App

Area

Service lifecycle

Summary

OpenCodex 2.14.1 blocks every native OpenAI request when it is run in a normal systemd-less Docker container with ocx start. The proxy remains live and /healthz returns 200, but native requests fail locally with HTTP 503 before reaching the upstream.

This appears inconsistent with the existing Docker handling in src/service.ts, which detects /.dockerenv and explicitly tells users to run ocx start directly instead of using the service manager. The native ownership preflight does not apply the same Docker/foreground distinction: on Linux it always probes systemctl --user, an unavailable probe becomes ownership: "unknown", and 2.14.1 blocks native-main traffic for that result.

The same container layout works on 2.12.0. I expected foreground ocx start under Docker or another external process supervisor to remain a supported runtime shape, while still refusing access when there is positive evidence of a foreign service-home owner.

Reproduction

  1. Build a minimal image based on node:22.23.1-slim and install @bitkyc08/opencodex@2.14.1.
  2. Set OPENCODEX_HOME to a persistent container volume and CODEX_HOME to a container-local directory whose auth.json points to a valid Codex login mounted read-only from the host.
  3. Run OpenCodex directly under the container supervisor, as recommended for Docker:
FROM node:22.23.1-slim

RUN npm install --global --allow-scripts=bun --no-audit --no-fund @bitkyc08/opencodex@2.14.1

ENV HOME=/home/node \
    OPENCODEX_HOME=/home/node/.opencodex \
    CODEX_HOME=/home/node/.codex

RUN mkdir -p /home/node/.codex \
    && ln -s /run/codex-host/auth.json /home/node/.codex/auth.json \
    && chown -R node:node /home/node/.codex

USER node
CMD ["ocx", "start", "--port", "10100"]
  1. Confirm that the container does not contain a systemd user manager. In the minimal image, command -v systemctl prints nothing.
  2. Send a native OpenAI request through /v1/responses using a valid, redacted OpenCodex admission credential.
  3. Observe an immediate local 503 with OpenCodex local native-main profile maintenance is active; retry this request.
  4. Repeat with 2.12.0 using the same mounts and persisted OpenCodex data. The ownership-related maintenance 503 does not occur.

The relevant 2.14.1 control flow appears to be:

Docker + ocx start
-> inspectServiceManagerInstallation() selects inspectSystemd() for every Linux runtime
-> systemctl cannot be spawned, so the manager result is unknown
-> inspectNativeCodexOwnership() returns ownership: unknown
-> startServer() calls blockNativeMainStartupForUnownedServiceHome("ownership-unknown")
-> native requests fail locally with 503

src/service.ts already distinguishes this runtime shape:

Docker detected. Run 'ocx start' directly instead of using the service manager.

This suggests the Docker/externally supervised foreground case is intended but is not represented in the ownership preflight added to native request admission.

Version

2.14.1

Operating system

Docker Engine 29.6.1 on Ubuntu 24.04 x86_64; container image is Debian 12 (node:22.23.1-slim) with Node.js 22.23.1 and no systemd

Provider and model

OpenAI (Codex login) / native Codex models

Logs or error output

/healthz: HTTP 200
/readyz: HTTP 503, status "failed"

status: 503
durationMs: 3-24
usageStatus: unreported
errorCode: server_is_overloaded
closeReason: non_stream
upstreamError: OpenCodex local native-main profile maintenance is active; retry this request

The short duration, usageStatus: unreported, and exact local maintenance message indicate that these requests are rejected before an upstream connection is attempted.

Screenshots and supporting files

Image

Redacted configuration

{
  "runtime": "Docker container supervised by Docker Compose",
  "entrypoint": ["ocx", "start", "--port", "10100"],
  "opencodexHome": "persistent named volume",
  "codexAuth": "read-only host bind mount"
}

Checks

  • I searched existing issues and documentation.
  • I removed secrets, tokens, account details, request credentials, and personal data.

Activity

  1. coderabbitai commented on Aug 13, 2026

    @coderabbitai
    Contributor
    🔗 Related PRs

    #333 - fix(codex): preserve external model providers [merged]
    #1160 - fix(service): preserve supervision across restart [open]
    #1202 - fix(codex): stop reporting every history failure as a Codex DB lock [merged]
    #1427 - fix(service): align WSL Codex home ownership [merged]
    #1461 - fix(codex): preflight sync injection before catalog writes [merged]


    📝 Issue Planner

    Check the box below or use the @coderabbitai plan command to generate an implementation plan and prompts that you can use with your favorite coding assistant.

    • Create Plan

    🧪 Issue enrichment is currently in open beta.

    To disable automatic issue enrichment, add the following to your .coderabbit.yaml:

    issue_enrichment:
      auto_enrich:
        enabled: false

    💬 Have feedback or questions? Drop into our discord!

  2. added
    bugSomething isn't working
    account-poolOAuth, credentials, Codex pool, quota, failover, plans
    installInstallation or packaging
    serviceService lifecycle (WinSW/launchd/scheduler)
    on Aug 13, 2026
  3. lidge-jun commented on Aug 13, 2026

    @lidge-jun
    Owner

    Confirmed from current dev; this is not fixed.

    src/service.ts:2369-2375 explicitly tells Docker users to run ocx start directly, and src/service.ts:2897-2898 classifies Docker/systemd-less service management as unsupported. However, src/service-manager-probe.ts:791-798 still selects inspectSystemd() for every Linux runtime. When systemctl --user cannot be spawned, src/service-manager-probe.ts:260-270 returns kind: "unknown"; src/integrations/native/ownership-preflight.ts:151-156 converts that to ownership: "unknown"; and src/server/index.ts:705-711 then blocks native-main startup. src/codex/native-profile-startup.ts:321-352 confirms this is an admission fence rather than a diagnostic, so the 503 behavior you observed follows directly from the code.

    The fix must preserve fail-closed behavior for positive foreign-service evidence. Add an explicit foreground-container/external-supervisor branch that treats an unaskable systemd manager as absent only when Docker is detected and there is no service-state or manager-artifact claim to inspect. Keep malformed state, a present unit, conflicting state, or any foreign-home evidence as unknown/foreign. Add a regression that injects Docker plus an unavailable systemctl probe and proves native-main traffic starts, plus negative cases proving a service artifact or foreign state still blocks admission.

    DISPOSITION: ACCEPTED

  4. lidge-jun commented on Aug 14, 2026

    @lidge-jun
    Owner

    Fixed on dev (bb45902): Docker/foreground Linux environments without systemd no longer get 503 for native-main requests. The systemctl spawn failure is now treated as 'absent' rather than 'unknown'. 다음 배포에서 해결될 예정입니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    account-poolOAuth, credentials, Codex pool, quota, failover, plansbugSomething isn't workinginstallInstallation or packagingserviceService lifecycle (WinSW/launchd/scheduler)

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions