# ---- build stage ------------------------------------------------------------ # pin builder and runtime to the same Debian release — a floating `rust:1-slim` # drifts to a newer glibc than the runtime image and the binary refuses to start FROM rust:1-slim-trixie AS builder WORKDIR /app # the cortiq runtime CANNOT be auto-installed inside the container (no cargo in # the runtime image), so it is compiled here and shipped alongside the gateway — # local .cmf chat models and image/video generation work in Docker out of the box RUN cargo install cortiq-cli --locked # the admin SPA (web/) is embedded at compile time via rust-embed, so it must be present COPY Cargo.toml Cargo.lock ./ COPY src ./src COPY web ./web RUN cargo build --release # ---- runtime stage ---------------------------------------------------------- FROM debian:trixie-slim # curl — model imports download ready .cmf files with it; # libvulkan1 — optional GPU offload for cortiq (falls back to CPU without a GPU) RUN apt-get update \ && apt-get install -y --no-install-recommends ca-certificates curl libvulkan1 \ && rm -rf /var/lib/apt/lists/* \ && useradd -r -u 10001 cortiq \ && mkdir -p /app/config /app/data/models COPY --from=builder /app/target/release/cortiq-gateway /usr/local/bin/cortiq-gateway COPY --from=builder /usr/local/cargo/bin/cortiq /usr/local/bin/cortiq # ship the example as the default config so `docker run` works out of the box COPY config/gateway.example.toml /app/config/gateway.toml RUN chown -R 10001:10001 /app WORKDIR /app # all gateway state (downloaded models, stats, secrets) lives under /app/data — # mount a volume there to keep it across container recreates ENV CORTIQ_GATEWAY_HOME=/app/data # runs as root so writes to bind-mounted host folders (Docker Desktop on # Windows/macOS) don't fail with permission errors (curl exit code 23); # add `--user 10001` to docker run to harden when not using host bind mounts EXPOSE 9000 ENTRYPOINT ["cortiq-gateway"] CMD ["--config", "/app/config/gateway.toml"]