Docker image
GHCR image tags, multi-arch matrix, OCI labels, cosign signatures, provenance, and SBOM.
The maintainer-distributed Docker image lets consumers run custom-trimmed wasm builds without setting up emsdk, libclang, and Python locally.
Pulling
docker pull ghcr.io/taucad/opencascade.js:single-threadedTags
| Tag | Points to |
|---|---|
:single-threaded | Latest release, single-threaded warm cache (default for browser CAD UIs) |
:multi-threaded | Latest release, multi-threaded warm cache (requires COOP/COEP on consumer pages) |
:bindgen-base | Latest release, post-PCH/generate but pre-compile (custom-bindings starting point) |
:{{version}}-single-threaded:{{version}}-multi-threaded | Pinned release (e.g. :3.0.0-single-threaded); manifest list of linux/amd64+arm64 |
:{{version}}-bindgen-base | Pinned release, bindgen-base |
:branch-<slug> / :branch-<slug>-<sha> | Branch tip, single-threaded, linux/amd64-only, 7-day GHCR retention |
:multi-threaded-branch-<slug> / …-<sha> | Branch tip, multi-threaded, amd64-only, 7-day retention |
:bindgen-base-branch-<slug> / …-<sha> | Branch tip, bindgen-base, amd64-only, 7-day retention |
@sha256:<digest> | Immutable pin — use in CI |
Pin by digest in production. The bare-name tags (:single-threaded,
:multi-threaded, :bindgen-base) are mutable and roll forward with every
release. See Reproducible CI for the pinning
workflow.
The legacy :beta, :rolling, and :latest tags are not published by
this fork. Use a version-pinned tag (e.g. :3.0.0-single-threaded) or the
manifest-list digest for explicit version control.
Entrypoint
docker run --rm \
-v "$(pwd):/src" \
-u "$(id -u):$(id -g)" \
ghcr.io/taucad/opencascade.js:single-threaded \
link mybuild.ymlThe entrypoint dispatches subcommands through npx nx run ocjs:<target> so
runs benefit from Nx's content-addressed cache:
| Subcommand | What it does |
|---|---|
link <yaml> | End-to-end build. Nx walks apply-patches → pch → generate → compile-bindings → compile-sources → link with cache reuse — fresh container = full build, cached re-run = link only. |
compile-bindings, compile-sources, pch, … | Run an individual Nx target |
validate <yaml> | Validate YAML without building |
nx <args…> | Pass-through to npx nx (escape hatch) |
Outputs land in /src next to your YAML (OCJS_OUTPUT_DIR=/src default).
Override the entrypoint
docker run --rm -it -v "$(pwd):/src" --entrypoint bash \
ghcr.io/taucad/opencascade.js:single-threaded…drops you into a shell with emsdk, libclang, and Python on the PATH.
Multi-arch matrix
| Tag family | Manifest list | Built on |
|---|---|---|
| Release tags | linux/amd64 + linux/arm64 | ubuntu-latest (amd64) + ubuntu-24.04-arm (arm64), GitHub Actions native runners |
| Branch tags | linux/amd64 only | ubuntu-latest, GitHub Actions |
Releases ship full manifest lists so Apple Silicon and ARM Linux hosts pull the native arch transparently. Branch tags are amd64-only by design (R12 in the production-readiness blueprint) — ARM hosts will run under Rosetta / QEMU for branch tags.
OCI labels
Inspect via docker inspect ghcr.io/taucad/opencascade.js:single-threaded:
| Label | Purpose |
|---|---|
org.opencontainers.image.title | Stage-specific title (single-threaded, multi-threaded, …) |
org.opencontainers.image.description | Threading model and consumer prerequisites |
org.opencontainers.image.source | https://github.com/taucad/opencascade.js |
org.opencontainers.image.url | Same as source |
org.opencontainers.image.revision | Git commit the image was built from |
org.opencontainers.image.version | Semver tag |
org.opencontainers.image.licenses | LGPL-2.1-only |
org.opencontainers.image.vendor | taucad |
Cosign signatures
Every published image is signed with cosign via OIDC keyless signing — no rotating private keys, signatures published to the Sigstore Rekor transparency log. Release tags carry one signature on the manifest-list digest that verifies regardless of which arch the consumer pulls; branch tags carry per-arch image-digest signatures.
cosign verify ghcr.io/taucad/opencascade.js:single-threaded \
--certificate-identity-regexp 'https://github.com/taucad/opencascade\.js/\.github/workflows/docker\.yml@.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.comA successful verification confirms the image was built by the
taucad/opencascade.js GitHub Actions docker.yml workflow and has not
been tampered with since publication.
Provenance
cosign verify-attestation \
--type slsaprovenance \
--certificate-identity-regexp 'https://github\.com/taucad/opencascade\.js/\.github/workflows/docker\.yml@.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
ghcr.io/taucad/opencascade.js:single-threadedThe attestation records the source commit, the workflow, and the runner that produced the image.
SBOM
docker buildx imagetools inspect \
--format '{{ json .SBOM }}' \
ghcr.io/taucad/opencascade.js:single-threadedDiff the SBOM across image digests in CI to flag unexpected dep bumps.
Image stages
The Dockerfile is multi-stage with five logical stages, three of which are published:
| Stage | Published as | Contents |
|---|---|---|
deps-base | (not published) | emsdk + apt + Node 24 + uv + Python + OCCT/rapidjson/freetype + LLVM 17 headers |
bindgen-base | :bindgen-base | deps + npm ci + patches + PCH + .d.ts.json index |
compiled-single-threaded | (not published) | bindgen + compiled .o files + OCCT .a (single-threaded) |
compiled-multi-threaded | (not published) | bindgen + compiled .o files + OCCT .a (multi-threaded) |
final-single | :single-threaded | compiled-single + OCI labels + entrypoint |
final-multi | :multi-threaded | compiled-multi + OCI labels + entrypoint |
Each stage is independently rebuildable via docker buildx build --target <stage>. See Bindgen pipeline for how the
stages compose with the build pipeline.