Files
infosave2007 15de36be3b feat: ops & UX batch — jobs survive restarts, logs/system in the console, media queue, gallery, chat, exact stream tokens
Fifteen changes aimed at the first day of real use:

- Import and media jobs persist to <data>/jobs-*.json and reload on start
  (running ones settle as errors); the Register button no longer vanishes
  because the gateway restarted.
- Docker ships the cortiq binary (built in the builder stage) — local .cmf
  chat models and image/video generation now work in containers, where
  auto-install never could (no cargo in the runtime image). libvulkan1 added
  for optional GPU offload.
- Open admin console on 0.0.0.0 without a token now warns in the log and
  shows a dismissible banner — the VPS footgun is at least labeled.
- "Restart gateway" button in Settings: stops managed model servers, spawns
  a fresh copy (bind retried while the port frees), Docker relies on the
  container restart policy instead.
- Dashboard "System" panel: CPU sparkline + load, RAM (with the gateway's
  own RSS), free disk at the models dir — sampled by sysinfo every 2 s.
- Featured model cards warn "not enough disk" / "may not fit in RAM" before
  the download, from the same live snapshot.
- Log viewer in the sidebar: a 500-line in-memory ring fed by a second
  ANSI-free tracing layer; filter, level, pause, copy.
- Update check: crates.io polled twice a day, the console shows an
  "update available" notice.
- Media generations queue up (with position shown) instead of being
  rejected; progress gained an honest ETA from measured throughput.
- Generation gallery under the image/video tabs: lazy PPM thumbnails,
  click to reopen with seed/steps, delete.
- Playground chat is a real dialogue now: history is resent, bubbles,
  Clear, Cmd/Ctrl+Enter.
- "Connect your app" snippets (curl / Python / JS) on the keys page, with
  the real key inlined right after creation.
- One-click benchmark on the Models page via `cortiq bench --json`.
- Config export now downloads the actual gateway.toml (comments intact);
  import accepts TOML (validated, hot-reloaded) and the legacy JSON.
- Streaming token counts are exact when the model server provides usage
  (cortiq-server patch, shipped separately); the gateway fallback now
  counts content chunks (1/token on cortiq) instead of chars/4.

Wizard's Finish lands on the Playground. 37 new strings in all 7 languages.
2026-08-07 17:07:48 +03:00

40 lines
2.0 KiB
Docker

# ---- 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"]