Skip to content
Closed
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
6 changes: 4 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ WORKDIR /home/bun/app

ENV NODE_ENV=production \
OPENCODEX_HOME=/home/bun/.opencodex \
CODEX_HOME=/home/bun/.codex \
OCX_API_TOKEN_FILE=/home/bun/.opencodex/service-api-token

RUN install -d -m 0700 -o bun -g bun /home/bun/.opencodex
# These homes have incompatible auth.json formats; persist them without combining them.
RUN install -d -m 0700 -o bun -g bun /home/bun/.opencodex /home/bun/.codex
COPY --chown=bun:bun --chmod=0600 docker/config.json /home/bun/.opencodex/config.json

COPY --from=build --chown=bun:bun /home/bun/app/package.json ./package.json
Expand All @@ -46,7 +48,7 @@ COPY --from=build --chown=bun:bun /home/bun/app/gui/dist ./gui/dist
USER bun
RUN ["bun", "docker/verify-compatibility.ts"]
RUN ["bun", "-e", "import { readOpenCodexCompatibilityVersion } from './src/routing/compatibility/version.ts'; if (!/^[0-9a-f]{64}$/.test(readOpenCodexCompatibilityVersion() ?? '')) throw new Error('Missing or invalid generated compatibility manifest');"]
VOLUME ["/home/bun/.opencodex"]
VOLUME ["/home/bun/.opencodex", "/home/bun/.codex"]
EXPOSE 10100

HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
Expand Down
5 changes: 5 additions & 0 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@ services:
target: runtime
init: true
read_only: true
environment:
# A custom CODEX_HOME also requires a matching writable volume target below.
CODEX_HOME: /home/bun/.codex
ports:
- "${OPENCODEX_BIND_ADDRESS:-127.0.0.1}:${OPENCODEX_PORT:-10100}:10100"
volumes:
- ocx-state:/home/bun/.opencodex
- codex-state:/home/bun/.codex
tmpfs:
- /tmp:size=64m,mode=1777
security_opt:
Expand All @@ -24,3 +28,4 @@ services:

volumes:
ocx-state:
codex-state:
19 changes: 19 additions & 0 deletions docs-site/src/content/docs/fr/guides/remote-hub.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,25 @@ La rotation garde les deux clés valides sous le même `apiKeyId` pendant dix mi

## Docker, retour arrière et dépannage

Deux volumes distincts conservent l'état : `ocx-state` pour
`OPENCODEX_HOME=/home/bun/.opencodex` et `codex-state` pour
`CODEX_HOME=/home/bun/.codex`. Leurs fichiers `auth.json` ont des formats incompatibles :
ne fusionnez pas ces répertoires. Ils restent accessibles en écriture malgré la racine en lecture seule.

Le catalogue n'est pas généré automatiquement. Avant de tester `/v1/catalog` avec authentification,
créez ou importez un fichier valide dans `/home/bun/.codex/opencodex-catalog.json`.
Un répertoire vide renvoie normalement 404 `catalog_not_found`. Une mise à jour conserve
`ocx-state` et ajoute `codex-state`, sans déplacer les fichiers. Sauvegardez tout catalogue
précédemment placé dans `.opencodex`, puis transférez seulement ce catalogue avec des permissions
réservées au propriétaire ; ne remplacez pas un `auth.json` par celui de l'autre produit.
Si vous redéfinissez `CODEX_HOME`, montez ce répertoire exact en écriture et placez le catalogue
par défaut dans `${CODEX_HOME}/opencodex-catalog.json`. Si `model_catalog_json` désigne un autre
fichier, son chemin résolu doit aussi être persistant. Conservez les variables et montages
personnalisés jusqu'à la fin d'une migration explicite.
`docker compose down` conserve les deux volumes ; `docker compose down --volumes` supprime
`ocx-state` et `codex-state`, avec les identifiants, l'historique d'utilisation, la clé de données,
l'état et le catalogue Codex. Ce n'est pas une commande de mise à jour ou de redémarrage.

Il n’existe pas d’image Docker officielle, mais le dépôt fournit un `Dockerfile` et un `compose.yaml` maintenus pour construire localement une image Bun épinglée par digest. Initialisez une seule fois la clé de données via stdin ; elle est enregistrée avec des permissions réservées au propriétaire dans le volume `ocx-state` et n’est jamais affichée.

Installez Git et Bun sur l’hôte. Avant chaque construction, générez le manifeste canonique depuis les sources suivies par Git, sans modifier les sources entre la génération et la construction. Le JSON généré reste non suivi ; `.git` est exclu du contexte Docker. Le port hôte est lié à `127.0.0.1` par défaut. Pour un accès distant, utilisez explicitement `OPENCODEX_BIND_ADDRESS=<IP-LAN-ou-Tailscale> docker compose up -d` ; `0.0.0.0` expose toutes les interfaces. Protégez cet accès par un pare-feu et un frontal TLS/tailnet authentifié.
Expand Down
28 changes: 26 additions & 2 deletions docs-site/src/content/docs/guides/remote-hub.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,30 @@ Before the first normal start, stream a freshly generated data-plane token into
The helper accepts at most one 4096-byte line, never prints the token, refuses to replace an existing
token, and persists it as the canonical owner-only `service-api-token` in the `ocx-state` volume.

The deployment persists two separate homes: `ocx-state` at `/home/bun/.opencodex` for
OpenCodex configuration, provider credentials and usage, and `codex-state` at
`/home/bun/.codex` for Codex state and `opencodex-catalog.json`. The image and Compose
explicitly set `CODEX_HOME=/home/bun/.codex`, so this catalog path remains writable
with `read_only: true` and survives container recreation. The image creates both
directories for the non-root `bun` user with mode `0700`; existing volume
ownership and permissions are not migrated automatically.

Do not combine `CODEX_HOME` and `OPENCODEX_HOME`: both products use an `auth.json`
filename with different formats. This packaging change adds persistence, not a
catalog generator. Materialize or import a valid catalog into
`/home/bun/.codex/opencodex-catalog.json` before the catalog acceptance check below;
without one, `catalog_not_found` remains the expected response.

Upgrading preserves the existing `ocx-state` volume and adds `codex-state`; no files
are migrated automatically. If a previous workaround placed a catalog directly
under `/home/bun/.opencodex`, back it up and deliberately copy only the catalog to
the new Codex home, preserving owner-only access. Do not copy either product's
`auth.json` over the other. Deployments with a custom `CODEX_HOME` should retain
their explicit environment and writable volume mapping until migration is complete.
Comment thread
Ingwannu marked this conversation as resolved.
When overriding `CODEX_HOME`, mount that exact directory writable and persist the
default catalog at `${CODEX_HOME}/opencodex-catalog.json`. If `model_catalog_json`
explicitly selects another file, that resolved path must also be persisted.

Comment thread
Ingwannu marked this conversation as resolved.
Install Git and Bun on the host first. Before **every** image build, run the existing canonical
generator from this Git checkout. It hashes Git-tracked working-tree sources (stage any newly
added source files first), not an arbitrary directory scan. Do not change source files between
Expand Down Expand Up @@ -244,9 +268,9 @@ docker compose exec hub bun -e \
Then send one real authenticated routed response with a configured model. If the secret is absent or
unreadable, a non-loopback hub must not be accepted as ready. Never treat liveness alone as proof.

`docker compose down` removes the container and network but retains the named volume. Treat
`docker compose down` removes the container and network but retains both named volumes. Treat
`docker compose down --volumes` as destructive: it deletes configuration, OAuth credentials, usage
history, and the data-plane token together.
history, the data-plane token, and persisted Codex state together.

## Rollback

Expand Down
20 changes: 20 additions & 0 deletions docs-site/src/content/docs/ja/guides/remote-hub.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,26 @@ OAuth は `POST /api/oauth/login` で開始し、コールバックできない

## Docker とトラブルシューティング

状態は二つのボリュームに分けて永続化します。`ocx-state` は
`OPENCODEX_HOME=/home/bun/.opencodex`、`codex-state` は
`CODEX_HOME=/home/bun/.codex` に対応します。両製品の `auth.json` は形式が
異なるため、ホームを同じディレクトリにしないでください。読み取り専用の
ルートでも、この二つのホームは書き込み可能です。

カタログは自動生成されません。認証付き `/v1/catalog` の確認前に、有効な
`/home/bun/.codex/opencodex-catalog.json` を生成または取り込んでください。
空のホームでは `catalog_not_found` の 404 が正常です。アップグレードは既存の
`ocx-state` を保持して `codex-state` を追加しますが、ファイルは自動移行しません。
以前 `.opencodex` に置いたカタログはバックアップし、カタログだけを所有者限定の
権限で移してください。`auth.json` を相互に上書きしないでください。
`CODEX_HOME` を変更する場合は、そのディレクトリ自体を書き込み可能なボリュームに
マウントし、既定のカタログを `${CODEX_HOME}/opencodex-catalog.json` に置きます。
`model_catalog_json` で別のファイルを指定した場合は、その解決先も永続化します。
カスタム構成は、明示的な移行が完了するまで環境変数とボリュームの対応を維持します。
`docker compose down` は両ボリュームを保持しますが、`docker compose down --volumes`
は `ocx-state` と `codex-state` の両方を削除し、認証情報・使用履歴・データキー・
Codex の状態とカタログも失われます。更新や再起動の代わりに使わないでください。

公式 Docker イメージはありませんが、リポジトリには digest 固定の Bun イメージをローカルビルドするための、管理された `Dockerfile` と `compose.yaml` があります。初回起動前にデータキーを stdin から一度だけ初期化します。キーは表示されず、`ocx-state` ボリューム内に所有者限定の権限で保存されます。

ホストに Git と Bun が必要です。イメージをビルドするたびに、Git 管理下のソースから正規のマニフェストを生成し、生成後はビルドまでソースを変更しないでください。生成 JSON は Git に追加せず、`.git` は Docker コンテキストから除外します。ホスト側は既定で `127.0.0.1` にバインドします。リモート公開は `OPENCODEX_BIND_ADDRESS=<LANまたはTailscaleのIP> docker compose up -d` で明示的に指定し、`0.0.0.0` は全インターフェースを公開します。ファイアウォールと認証付き TLS/tailnet フロントエンドで保護してください。
Expand Down
18 changes: 17 additions & 1 deletion docs-site/src/content/docs/ko/guides/remote-hub.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,22 @@ ocx connect rotate --admin-token-stdin

## Docker

상태는 두 볼륨에 분리해 보관합니다. `ocx-state`는
`OPENCODEX_HOME=/home/bun/.opencodex`, `codex-state`는
`CODEX_HOME=/home/bun/.codex`에 연결됩니다. 두 제품의 `auth.json` 형식이 다르므로
홈을 같은 폴더로 합치지 마세요. 루트 파일 시스템이 read-only여도 이 두 홈은 쓰기 가능합니다.

카탈로그는 자동 생성되지 않습니다. 인증된 `/v1/catalog` 검사 전에 유효한
`/home/bun/.codex/opencodex-catalog.json`을 생성하거나 가져와야 합니다.
빈 홈에서 `catalog_not_found` 404는 정상입니다. 업그레이드는 기존 `ocx-state`를
유지하고 `codex-state`를 추가하지만 파일을 자동 이동하지 않습니다. 이전 우회 설정으로
`.opencodex`에 둔 카탈로그는 백업한 뒤 카탈로그만 owner-only 권한으로 옮기세요.
두 제품의 `auth.json`을 서로 덮어쓰면 안 됩니다. 사용자 지정 `CODEX_HOME`은 그 정확한
디렉터리를 쓰기 가능한 볼륨에 연결하고, 기본 카탈로그를
`${CODEX_HOME}/opencodex-catalog.json`에 준비해야 합니다. `model_catalog_json`으로
별도 파일을 지정했다면 그 경로도 영속 보관하세요. 명시적 이전이 완료되기 전까지는
기존 사용자 지정 환경 변수와 볼륨 경로의 대응을 유지하세요.

opencodex는 공식 컨테이너 이미지를 배포하지 않지만, 저장소 루트의 `Dockerfile`과 `compose.yaml`로 digest가 고정된 소스 이미지를 직접 빌드할 수 있습니다. 최초 실행 전에 데이터 키를 stdin으로 초기화하세요. 키는 출력되지 않으며 `ocx-state` 볼륨의 owner-only `service-api-token`에 저장됩니다.

호스트에 Git과 Bun이 필요합니다. 이미지를 빌드할 때마다 Git이 추적하는 소스로 정식 매니페스트를 생성하고, 생성부터 빌드 사이에는 소스를 변경하지 마세요. 생성된 JSON은 Git에 추가하지 않으며 `.git`은 Docker 컨텍스트에서 제외됩니다. 호스트 포트는 기본적으로 `127.0.0.1`에 바인딩됩니다. 원격 공개는 `OPENCODEX_BIND_ADDRESS=<LAN-또는-Tailscale-IP> docker compose up -d`로 명시적으로 선택하며, `0.0.0.0`은 모든 인터페이스에 공개합니다. 방화벽과 인증된 TLS/tailnet 프런트엔드로 보호하세요.
Expand All @@ -105,7 +121,7 @@ docker compose up -d

컨테이너 healthcheck의 `/healthz`가 통과한 뒤 `/readyz`, 인증된 `/v1/catalog`, 실제 모델 응답을 별도로 확인하세요.

`docker compose down`은 `ocx-state` 볼륨을 보존합니다. `docker compose down --volumes`는 설정, OAuth 인증 정보, 사용량 기록, 데이터 키를 함께 삭제하므로 파괴적 작업으로 취급하세요.
`docker compose down`은 `ocx-state`와 `codex-state`를 모두 보존합니다. `docker compose down --volumes`는 두 볼륨을 모두 삭제하여 설정, OAuth 인증 정보, 사용량 기록, 데이터 키, Codex 상태와 카탈로그를 지웁니다. 업그레이드나 재시작 대신 사용하지 마세요.

## 롤백과 문제 해결

Expand Down
22 changes: 22 additions & 0 deletions docs-site/src/content/docs/ru/guides/remote-hub.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,28 @@ OAuth запускается через `POST /api/oauth/login`. Если callba

## Docker и устранение неполадок

Состояние хранится в двух отдельных томах: `ocx-state` для
`OPENCODEX_HOME=/home/bun/.opencodex` и `codex-state` для
`CODEX_HOME=/home/bun/.codex`. Форматы `auth.json` у двух продуктов несовместимы,
поэтому не объединяйте их домашние каталоги. Оба тома доступны для записи при
корневой файловой системе только для чтения.

Каталог моделей автоматически не создаётся. Перед проверкой авторизованного
`/v1/catalog` создайте или импортируйте корректный файл
`/home/bun/.codex/opencodex-catalog.json`. Для пустого каталога состояния ответ
404 `catalog_not_found` ожидаем. Обновление сохраняет `ocx-state` и добавляет
`codex-state`, но не переносит файлы автоматически. Если обходное решение хранило
каталог моделей в `.opencodex`, сначала сделайте резервную копию, затем перенесите
только каталог моделей с доступом лишь для владельца. Не перезаписывайте один
`auth.json` другим. При переопределении `CODEX_HOME` монтируйте именно эту директорию
для записи и сохраняйте каталог по умолчанию в `${CODEX_HOME}/opencodex-catalog.json`.
Если `model_catalog_json` задаёт другой файл, его разрешённый путь также должен
храниться постоянно. До явного переноса сохраняйте прежнее соответствие переменных
окружения и томов. `docker compose down` сохраняет оба тома, а
`docker compose down --volumes` удаляет и `ocx-state`, и `codex-state`, включая
учётные данные, историю использования, ключ данных, состояние и каталог Codex.
Это разрушительная операция, а не способ обновления или перезапуска.

Официального Docker-образа нет, но репозиторий содержит поддерживаемые `Dockerfile` и `compose.yaml` для локальной сборки Bun-образа, закреплённого по digest. Перед первым запуском один раз передайте ключ данных через stdin; он не выводится и сохраняется с доступом только для владельца в volume `ocx-state`.

На хосте нужны Git и Bun. Перед каждой сборкой создавайте канонический манифест из отслеживаемых Git исходников и не меняйте их до завершения сборки. Сгенерированный JSON не добавляйте в Git; `.git` исключён из контекста Docker. По умолчанию порт хоста привязан к `127.0.0.1`. Для удалённого доступа явно задайте `OPENCODEX_BIND_ADDRESS=<LAN-или-Tailscale-IP> docker compose up -d`; `0.0.0.0` открывает все интерфейсы. Защитите доступ брандмауэром и аутентифицированным TLS/tailnet-фронтендом.
Expand Down
22 changes: 22 additions & 0 deletions docs-site/src/content/docs/tr/guides/remote-hub.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,28 @@ Döndürme sırasında eski ve yeni anahtar aynı `apiKeyId` altında en fazla o

## Docker ve sorun giderme

Durum iki ayrı kalıcı volume'da tutulur: `ocx-state`,
`OPENCODEX_HOME=/home/bun/.opencodex` yoluna; `codex-state` ise
`CODEX_HOME=/home/bun/.codex` yoluna bağlanır. İki ürünün `auth.json` biçimleri
uyumsuzdur; bu dizinleri birleştirmeyin. Kök dosya sistemi salt okunur olsa da
bu iki volume yazılabilir durumda kalır.

Katalog otomatik oluşturulmaz. Kimlik doğrulamalı `/v1/catalog` kontrolünden önce
`/home/bun/.codex/opencodex-catalog.json` konumunda geçerli bir katalog oluşturun
veya içe aktarın. Boş dizinde 404 `catalog_not_found` beklenen sonuçtur. Güncelleme
mevcut `ocx-state` volume'unu korur ve `codex-state` ekler; dosyaları otomatik taşımaz.
Önceden `.opencodex` içine konmuş kataloğu yedekleyin ve yalnızca katalog dosyasını,
sadece sahibine erişim veren izinlerle taşıyın. Bir ürünün `auth.json` dosyasını
diğerininkiyle değiştirmeyin. `CODEX_HOME` özelleştirilirse bu dizinin tam yolunu
yazılabilir bir volume'a bağlayın ve varsayılan kataloğu
`${CODEX_HOME}/opencodex-catalog.json` konumuna koyun. `model_catalog_json` başka
bir dosya seçiyorsa çözümlenen yol da kalıcı olmalıdır. Açık bir taşıma tamamlanana
kadar mevcut özel ortam ve volume eşlemesini koruyun.
`docker compose down` iki volume'u da korur; `docker compose down --volumes` hem
`ocx-state` hem `codex-state` ile birlikte kimlik bilgilerini, kullanım geçmişini,
veri anahtarını ve Codex durumunu/kataloğunu siler. Güncelleme veya yeniden başlatma
yerine kullanılmamalıdır.

Resmî Docker imajı yoktur; ancak depo, digest ile sabitlenmiş Bun imajını yerelde oluşturmak için bakımı yapılan bir `Dockerfile` ve `compose.yaml` sağlar. İlk başlatmadan önce veri anahtarını stdin üzerinden bir kez başlatın; anahtar yazdırılmaz ve `ocx-state` volume içinde yalnızca sahibinin okuyabileceği izinlerle saklanır.

Host üzerinde Git ve Bun gereklidir. Her imaj derlemesinden önce Git tarafından izlenen kaynaklardan kanonik manifesti üretin ve derleme bitene kadar kaynakları değiştirmeyin. Üretilen JSON dosyasını Git'e eklemeyin; `.git` Docker bağlamının dışında kalır. Host portu varsayılan olarak `127.0.0.1` adresine bağlanır. Uzak erişim için açıkça `OPENCODEX_BIND_ADDRESS=<LAN-veya-Tailscale-IP> docker compose up -d` kullanın; `0.0.0.0` tüm arayüzleri açar. Erişimi güvenlik duvarı ve kimlik doğrulamalı TLS/tailnet ön ucu ile koruyun.
Expand Down
Loading
Loading