Skip to content

[Feature]: Add first-class Docker / Docker Compose deployment support #3449

Closed

Description

@xcai413

Area

Installation or packaging

What are you trying to accomplish?

Run OpenCodex as a self-contained containerized proxy/dashboard without installing OpenCodex globally on the host.

The intended deployment shape is:

Codex CLI / Codex App / Claude Code on host or remote clients
                    ↓
              localhost / LAN
                    ↓
        OpenCodex container (:10100)
                    ↓
       configured providers / account pools

OpenCodex already contains meaningful Docker-aware runtime behavior, and users are already running it under Docker, Docker Compose, k3s, and other external supervisors. However, there is no official Dockerfile, Compose example, published container image, or container-specific deployment guide.

Why this is worth making first-class

Existing issues show that Docker is already an intended/real deployment shape rather than an unsupported experiment:

Today operators have to reconstruct the container contract themselves: which process to run, which directories to persist, which ports to expose, how to handle non-loopback authentication, and which commands must not be used inside a container.

What should OpenCodex do?

Provide a small, supported container deployment surface.

At minimum:

  1. Official Dockerfile or published image

    • Node 22 base (or another maintainer-selected supported base).
    • Run OpenCodex in foreground with ocx start.
    • Do not rely on systemd, launchd, Windows Task Scheduler, or ocx service inside the container.
    • Prefer a non-root runtime user.
    • Pin/package the same released OpenCodex version as the image tag.
  2. Official compose.yaml example

    • Persistent OPENCODEX_HOME volume.
    • Port 10100 exposed to the host.
    • Example of host-only publication such as 127.0.0.1:10100:10100.
    • Clear example for hostname: "0.0.0.0" inside the container.
    • OPENCODEX_API_AUTH_TOKEN handling for non-loopback binds.
    • Restart policy managed by Docker/Compose instead of ocx service.
  3. Health/readiness contract

    • Docker HEALTHCHECK example using /healthz or /readyz.
    • Document when /readyz should be used instead of liveness.
  4. Persistent data contract

    • Document which state belongs under OPENCODEX_HOME and should be persisted.
    • Document optional CODEX_HOME / auth mounts when native ChatGPT/Codex credentials are used.
    • Prefer read-only credential mounts where possible.
  5. OAuth/headless guidance

  6. Container lifecycle guidance

    • Explicitly document that ocx service is not used in Docker.
    • Explicitly document whether ocx codex-shim install is meaningful only when Codex itself runs in the same container.
    • Document how upgrades should work: pull/rebuild image + restart, rather than invoking an in-container self-update that mutates the running image.

Example interface

A minimal supported Compose deployment could look approximately like this (exact image/name/config are illustrative):

services:
  opencodex:
    image: ghcr.io/lidge-jun/opencodex:2.42.0
    restart: unless-stopped
    ports:
      - "127.0.0.1:10100:10100"
    environment:
      OPENCODEX_HOME: /data
      OPENCODEX_API_AUTH_TOKEN: ${OPENCODEX_API_AUTH_TOKEN}
    volumes:
      - opencodex-data:/data

volumes:
  opencodex-data:

With container-side config:

{
  "port": 10100,
  "hostname": "0.0.0.0"
}

And a healthcheck along the lines of:

healthcheck:
  test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:10100/healthz').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
  interval: 30s
  timeout: 5s
  retries: 3

Alternatives or workarounds

Operators can already build a custom image by installing the npm package into a Node image and running ocx start, or clone the repository and run the Bun entrypoint directly. That works, but every operator has to rediscover the same details:

  • foreground-only lifecycle;
  • service manager is unsupported/unnecessary in Docker;
  • persistent OPENCODEX_HOME;
  • 0.0.0.0 bind + admission token;
  • OAuth callback routing;
  • native Codex auth mounts;
  • container-safe upgrade behavior.

The runtime already contains Docker-specific handling, so documenting and packaging that contract would reduce duplicated deployment work and make existing Docker support easier to test continuously.

Scope / non-goals

This request does not require:

  • Kubernetes operators or Helm charts;
  • multi-tenant isolation ([Roadmap] Centrally hosted multi-user OpenCodex with tenant isolation #95 owns that larger architecture);
  • weakening authentication for non-loopback binds;
  • running systemd inside the container;
  • bundling Codex CLI unless maintainers explicitly want a separate all-in-one image;
  • solving every OAuth flow in this issue.

A minimal official image + Compose example + container deployment documentation would already close the main packaging gap.

Acceptance criteria

  • An official Dockerfile or published container image exists.
  • A documented Compose example persists OpenCodex state.
  • The container runs ocx start directly and does not depend on a service manager.
  • Non-loopback bind/auth requirements are documented and tested.
  • /healthz and/or /readyz are wired into a documented container healthcheck.
  • Upgrade guidance does not require mutating the running image in place.
  • OAuth/headless callback considerations are documented.
  • The supported container path has at least one CI smoke test.

Checks

Activity

  1. added
    enhancementNew feature or request
    account-poolOAuth, credentials, Codex pool, quota, failover, plans
    installInstallation or packaging
    platformOS/service/tray/ACL (Windows-heavy, not Windows-only)
    serviceService lifecycle (WinSW/launchd/scheduler)
    on Sep 4, 2026
  2. lidge-jun commented on Sep 4, 2026

    @lidge-jun
    Owner

    리뷰 · 우선순위 48 / 80

    설명

    이 이슈는 OpenCodex를 호스트에 전역 설치하지 않고, Docker/Compose로 프록시·대시보드를 띄우는 “공식 컨테이너 계약”을 요구합니다. 지금 dev HEAD에는 루트 Dockerfile도 compose.yaml도 없습니다. 그런데 런타임 쪽에는 이미 Docker를 염두에 둔 동작이 있습니다. #1612에서 Docker 포그라운드 기동이 받아들여졌고, #2114는 컨테이너/tini 환경을 다뤘으며, #3366은 headless/k3s에서 OAuth가 남은 마찰이라고 적혀 있습니다. #95는 원격/중앙 배포의 큰 그림입니다. 즉 “Docker로 돌린다”는 실험이 아니라 이미 있는 배포 형태인데, 이미지·Compose 예시·헬스체크·볼륨·비루프백 인증·업그레이드 안내가 공식으로 정리되지 않은 상태입니다.

    요청 범위는 작습니다. 공식 Dockerfile 또는 퍼블리시 이미지, OPENCODEX_HOME 유지 볼륨, 10100 포트, 컨테이너 안 hostname: 0.0.0.0, OPENCODEX_API_AUTH_TOKEN, /healthz·/readyz 헬스체크, ocx service를 쓰지 말 것, 이미지 안 self-update 금지. K8s/Helm·멀티테넌트·인증 약화는 비목표로 잘 잘랐습니다. 같은 주제의 구현 PR이 이미 열려 있습니다. #3421 “Add Docker Compose deployment support”가 digest-pin Dockerfile, 읽기 전용 루트, non-root, stdin 토큰 부트스트랩, Compose, 문서까지 가져가고 있습니다. 이슈 #3449는 그 PR의 제품 스펙 문서에 가깝고, 중복 요청이라기보다 #3421이 닫아야 할 수용 기준 목록으로 읽는 편이 맞습니다.

    경로/심볼 - 현재 dev에 Dockerfile/compose.yaml 없음. 공식 표면이 아직 HEAD에 없다는 이슈 전제가 맞습니다.

    경로/심볼 - #1612/#2114/#3366/#95와의 연결이 정확합니다. 다만 #95 전체(비루프백 데이터플레인·원격 클라이언트)를 이 이슈 하나로 끌면 범위가 커집니다. 본문이 non-goals로 막은 선을 유지하는 게 좋습니다.

    경로/심볼 - #3421이 이미 이미지 퍼블리시 워크플로는 out of scope라고 합니다. 이 이슈 수용 기준의 “published container image”와 “CI smoke”는 #3421만으로 전부 충족되지 않을 수 있습니다. 문서+로컬 빌드 Compose로 1차를 닫고, GHCR 퍼블리시·CI 스모크는 후속 이슈로 쪼개는 판단이 필요합니다.

    메인테이너의 판단이 필요한 지점

    너의 추천

    이슈는 열어 두되, 본문에 #3421을 구현 PR로 명시하고 중복 구현 PR은 받지 마세요. #3421 리뷰·머지가 우선입니다. GHCR 퍼블리시와 컨테이너 CI 스모크가 #3421 범위 밖이면, merge 후 이 이슈에서 남은 체크만 후속 티켓으로 자르거나 #3449를 partial-close하세요. Preview 배포 계획은 없고, types/config split과도 무관합니다.

    이 댓글은 grok-bot이 작성했습니다

  3. lidge-jun commented on Sep 7, 2026

    @lidge-jun
    Owner

    The remaining source-build container acceptance is now implemented and verified on dev through #3822 and #3823.

    The runtime image now declares the existing service lifecycle mode, so Docker-managed stop/recreation preserves routed catalog rows rather than restoring a native desktop catalog. The real CI probe builds the image, checks non-root/read-only operation, readiness and token admission, refuses token replacement, recreates the container, and verifies exact config/token/routed-catalog persistence and scoped cleanup.

    Verification: https://github.com/lidge-jun/opencodex/actions/runs/34068218011 — final candidate 6f2ad1e, all 26 jobs successful after a single cancelled macOS shard was rerun unchanged. Merged dev 7fdb0e9 has the exact tree additionally checked against the integration base (129 focused tests passed remotely).

    The source-build Dockerfile/Compose route, foreground startup, authentication, health checks, recreate-based upgrades and headless OAuth guidance satisfy this issue's acceptance list. This does not claim a published registry image, every architecture, arbitrary existing mount migration, or every in-app restart path.

    Thanks to Buseong Kim for the original #3421 container contribution and Ingwannu for the separate Codex-home persistence work; both are retained as Co-authored-by trailers in the landed commits.

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, plansenhancementNew feature or requestinstallInstallation or packagingplatformOS/service/tray/ACL (Windows-heavy, not Windows-only)serviceService lifecycle (WinSW/launchd/scheduler)

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions