spicebook/backend/Dockerfile
Ryan Malloy 896a8535cf Add LTspice simulation engine via mcltspice
Wire up LTspice as a second simulation engine using mcltspice (Wine-based
LTspice runner). The backend architecture already had the ABC + factory
pattern; this connects the ltspice branch.

- Extract shared raw_to_waveform() into raw_convert.py with Protocol typing
  so both ngspice and mcltspice RawFile objects work without coupling
- Add LtspiceEngine with deferred mcltspice import for graceful degradation
- Register "ltspice" in get_engine() with availability check
  (mcltspice + Wine + LTspice.exe must all be present)
- Add startup validation log for LTspice availability
- Add mcltspice as optional dependency: pip install spicebook[ltspice]
- Integration tests auto-skip when LTspice is unavailable (Docker/CI)
2026-03-05 15:06:41 -07:00

60 lines
2.0 KiB
Docker

FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS base
# System dependencies -- ngspice is required for simulation
# NOTE: LTspice requires Wine + a Windows LTspice install, which is only
# available on the dev host (not in this container). The backend gracefully
# degrades -- LTspice engine returns UnsupportedEngineError in Docker.
RUN apt-get update && \
apt-get install -y --no-install-recommends ngspice && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Copy dependency metadata first for layer caching
COPY pyproject.toml ./
# ---------------------------------------------------------------------------
# Development target
# ---------------------------------------------------------------------------
FROM base AS dev
# Install in editable mode (source mounted via docker-compose volume)
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv pip install --system -e ".[dev]"
# Copy source for initial build (overridden by volume mount in dev)
COPY src/ ./src/
EXPOSE 8000
CMD ["uv", "run", "uvicorn", "spicebook.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
# ---------------------------------------------------------------------------
# Production target
# ---------------------------------------------------------------------------
FROM base AS prod
ENV UV_COMPILE_BYTECODE=1
# Install dependencies first (no source yet -- better caching)
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv pip install --system .
COPY src/ ./src/
# Re-install with source to get the package registered
RUN --mount=type=cache,target=/root/.cache/uv \
uv pip install --system .
# Run as non-root
RUN useradd --create-home --shell /bin/bash spicebook && \
mkdir -p /app/notebooks/user /app/notebooks/examples && \
chown -R spicebook:spicebook /app/notebooks
USER spicebook
EXPOSE 8000
CMD ["python", "-m", "uvicorn", "spicebook.main:app", "--host", "0.0.0.0", "--port", "8000"]