fix(docker): make runtime-staging the default Docker target for Railway (#2244)

* fix(docker): make runtime-staging the default Docker target for Railway

Railway's railway.toml doesn't support a `target` field — it was being
silently ignored, so the wasm-builder stage never ran and WASM extensions
were never pre-bundled.

Fix by reordering Dockerfile stages so runtime-staging is last (= default
target). Railway builds the default target, so it now gets WASM extensions.
CI is unaffected — it uses explicit --target flags in docker.yml.

Also reverts the CACHE_BUST arg added in efdb738a (no longer needed)
and removes the unsupported `target` field from railway.toml.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(ci): add --target runtime to CI and local docker build commands

Copilot correctly flagged that test.yml's `docker build .` would now
build the wasm-builder stage (slow, flaky) since runtime-staging is
the default target. Add explicit --target runtime to CI and update
the Dockerfile header comment for local builds.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* perf(docker): decouple wasm-builder from builder stage

wasm-builder now inherits from chef instead of builder, so WASM
extensions only rebuild when tools-src/, channels-src/, registry/,
or wit/ change — not on every src/ edit. The extensions are standalone
crates with their own lockfiles and don't depend on the main workspace.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Henry Park
2026-04-13 14:37:40 -07:00
committed by GitHub
parent 160a75e38c
commit 4dbb44cf0f
3 changed files with 19 additions and 11 deletions

View File

@@ -194,7 +194,7 @@ jobs:
ref: ${{ inputs.ref || github.sha }}
persist-credentials: false
- name: Build Docker image
run: docker build -t ironclaw-test:ci .
run: docker build --target runtime -t ironclaw-test:ci .
version-check:
name: Version Bump Check

View File

@@ -8,7 +8,7 @@
# database reopen), so we use glibc.
#
# Build:
# docker build --platform linux/amd64 -t ironclaw:latest .
# docker build --platform linux/amd64 --target runtime -t ironclaw:latest .
#
# Run:
# docker run --env-file .env -p 3000:3000 ironclaw:latest
@@ -68,11 +68,18 @@ COPY profiles/ profiles/
RUN cargo build --profile dist --bin ironclaw
# Stage 4b: Build all WASM extensions from source (only used by runtime-staging)
FROM builder AS wasm-builder
ARG CACHE_BUST
#
# Inherits from chef (not builder) so WASM extensions only rebuild when
# tools-src/, channels-src/, registry/, or wit/ change — not on every
# src/ edit. The extensions are standalone crates with their own lockfiles.
FROM chef AS wasm-builder
RUN apt-get update && apt-get install -y --no-install-recommends jq && rm -rf /var/lib/apt/lists/*
RUN echo "cache-bust=${CACHE_BUST}"
COPY tools-src/ tools-src/
COPY channels-src/ channels-src/
COPY registry/ registry/
COPY wit/ wit/
RUN set -eux; \
mkdir -p /app/wasm-bundles/tools /app/wasm-bundles/channels; \
@@ -134,12 +141,14 @@ ENV RUST_LOG=ironclaw=info
ENTRYPOINT ["ironclaw"]
# Stage 5b: Staging runtime (with pre-built WASM extensions)
# Stage 5b: Production runtime (no pre-bundled extensions)
FROM runtime-base AS runtime
USER ironclaw
# Stage 5c: Staging runtime (with pre-built WASM extensions)
# Last stage = default target. Railway doesn't support --target, so this
# must be last for Railway deploys. CI uses explicit --target flags.
FROM runtime-base AS runtime-staging
COPY --from=wasm-builder --chown=ironclaw:ironclaw /app/wasm-bundles/tools/ /home/ironclaw/.ironclaw/tools/
COPY --from=wasm-builder --chown=ironclaw:ironclaw /app/wasm-bundles/channels/ /home/ironclaw/.ironclaw/channels/
USER ironclaw
# Stage 5c: Production runtime (default — no pre-bundled extensions)
FROM runtime-base AS runtime
USER ironclaw

View File

@@ -1,7 +1,6 @@
[build]
builder = "dockerfile"
dockerfilePath = "Dockerfile"
target = "runtime-staging"
[deploy]
healthcheckPath = "/api/health"