Files
anyllm-proxy/Dockerfile
T
whit3rabbitandClaude Sonnet 4.6 dfed5b14ff feat: React admin UI migration — React 19 + TypeScript + Traffic/Uptime tabs
Replace 1,928-line monolithic vanilla JS admin SPA with React 19 + TypeScript 5
application. Adds Traffic and Uptime tabs backed by new Rust API endpoints.

- Vite + vite-plugin-singlefile: single dist/index.html with inlined JS/CSS
- Custom closeBundle plugin preserves __CSP_NONCE__ placeholder for Rust injection
- React Query v5 for server state, Zustand v5 for auth + WS connection state
- All existing backend contracts preserved (CSRF, WS auth, sessionStorage key)
- New: GET /admin/api/traffic (route load, P95, req/min, time series)
- New: GET /admin/api/uptime (proxy start time, per-backend 30d history)
- New: health_checks SQLite table + background Tokio health-checker (30s probe)
- BackendHealthChanged WS event for immediate Uptime tab refresh on status flip
- Dockerfile gains Node.js Stage 1 for frontend build
- CI gains frontend job (tsc + lint + build) before Rust test job

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 15:29:47 -05:00

51 lines
2.3 KiB
Docker

# syntax=docker/dockerfile:1
# ── Stage 1: build frontend ───────────────────────────────────────────────────
FROM node:20-alpine AS frontend
WORKDIR /app/crates/proxy/admin-ui
COPY crates/proxy/admin-ui/package.json crates/proxy/admin-ui/package-lock.json ./
RUN npm ci
COPY crates/proxy/admin-ui/ ./
RUN npm run build
# ── Stage 2: install cargo-chef ───────────────────────────────────────────────
FROM rust:1-alpine AS chef
RUN apk add --no-cache musl-dev openssl-dev openssl-libs-static
RUN cargo install cargo-chef --locked
WORKDIR /app
# ── Stage 3: compute dependency recipe ───────────────────────────────────────
FROM chef AS planner
COPY Cargo.toml Cargo.lock ./
COPY crates crates
RUN cargo chef prepare --recipe-path recipe.json
# ── Stage 4: build dependencies (cached layer) + compile binary ───────────────
FROM chef AS builder
# OPENSSL_STATIC must be set before cook so openssl-sys links statically
# when building reqwest/native-tls dependencies.
ENV OPENSSL_STATIC=1
COPY --from=planner /app/recipe.json recipe.json
RUN cargo chef cook --release --recipe-path recipe.json -p anyllm_proxy
COPY Cargo.toml Cargo.lock ./
COPY crates crates
COPY assets assets
# Inject frontend build output so include_str!() resolves at compile time.
COPY --from=frontend /app/crates/proxy/admin-ui/dist/ crates/proxy/admin-ui/dist/
RUN cargo build --release -p anyllm_proxy
# ── Stage 5: minimal Alpine runtime ──────────────────────────────────────────
FROM alpine:3.21 AS runtime
RUN apk add --no-cache ca-certificates tzdata
RUN addgroup -S -g 1001 anyllm && adduser -S -u 1001 -G anyllm anyllm
WORKDIR /app
RUN chown anyllm:anyllm /app
COPY --from=builder /app/target/release/anyllm_proxy /usr/local/bin/anyllm_proxy
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
RUN mkdir /data && chown anyllm:anyllm /data
VOLUME ["/data"]
USER anyllm
EXPOSE 3000 3001
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]