2026-03-16 11:01:50 +00:00
|
|
|
# syntax=docker/dockerfile:1.5
|
|
|
|
|
|
2026-08-24 16:23:55 +00:00
|
|
|
# uv resolves the venv here so its ~52MB binary stays out of the runtime image.
|
|
|
|
|
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim@sha256:531f855bda2c73cd6ef67d56b733b357cea384185b3022bd09f05e002cd144ca AS builder
|
2026-04-20 18:58:33 +01:00
|
|
|
|
2026-06-08 18:02:02 +01:00
|
|
|
WORKDIR /app/engine
|
2026-08-24 16:23:55 +00:00
|
|
|
COPY engine/pyproject.toml engine/uv.lock ./
|
2026-03-16 11:01:50 +00:00
|
|
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
2026-08-24 16:23:55 +00:00
|
|
|
uv sync --frozen --no-dev --no-install-project --group engine
|
2026-03-16 11:01:50 +00:00
|
|
|
|
2026-08-24 16:23:55 +00:00
|
|
|
FROM python:3.13-slim-bookworm@sha256:00faa2debb87529f9f0764e9491d8ba400a3678976616c3bd7cb193745ac20d1 AS runtime
|
|
|
|
|
|
|
|
|
|
# Created before the COPYs so they land owned; a later chown -R duplicates the venv layer.
|
|
|
|
|
RUN set -eux; \
|
|
|
|
|
groupadd --system --gid 1000 stirling; \
|
|
|
|
|
useradd --system --uid 1000 --gid 1000 --home /app/engine stirling; \
|
|
|
|
|
mkdir -p /app/engine/data; \
|
|
|
|
|
chown stirling:stirling /app/engine /app/engine/data
|
|
|
|
|
|
|
|
|
|
WORKDIR /app/engine
|
|
|
|
|
COPY --from=builder --chown=stirling:stirling /app/engine/.venv ./.venv
|
|
|
|
|
# settings.py resolves ENGINE_ROOT to /app/engine, so .env must sit here.
|
|
|
|
|
COPY --chown=stirling:stirling engine/.env ./
|
|
|
|
|
COPY --chown=stirling:stirling engine/src/ ./src/
|
2026-06-08 18:02:02 +01:00
|
|
|
|
|
|
|
|
ENV PATH="/app/engine/.venv/bin:$PATH"
|
2026-03-16 11:01:50 +00:00
|
|
|
ENV PYTHONUNBUFFERED=1
|
2026-06-11 16:31:35 +01:00
|
|
|
ENV STIRLING_ENGINE_WORKERS=4
|
2026-06-11 20:17:57 +01:00
|
|
|
ENV STIRLING_ENGINE_PORT=5001
|
2026-08-24 16:23:55 +00:00
|
|
|
# Fail closed: without a secret the document routes trust caller-supplied X-User-Id.
|
|
|
|
|
# Set STIRLING_ENGINE_SHARED_SECRET (the backend sends it as X-Engine-Auth), or false to opt out.
|
|
|
|
|
ENV STIRLING_ENGINE_REQUIRE_AUTH=true
|
|
|
|
|
|
|
|
|
|
# `stirling` resolves from the working directory.
|
|
|
|
|
WORKDIR /app/engine/src
|
|
|
|
|
USER stirling
|
2026-03-16 11:01:50 +00:00
|
|
|
|
2026-03-26 10:35:47 +00:00
|
|
|
EXPOSE 5001
|
|
|
|
|
|
2026-08-24 16:23:55 +00:00
|
|
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=40s --retries=3 \
|
|
|
|
|
CMD ["python", "-c", "import os,sys,urllib.request; sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:%s/health' % os.environ.get('STIRLING_ENGINE_PORT','5001'), timeout=4).status==200 else 1)"]
|
|
|
|
|
|
|
|
|
|
CMD ["sh", "-c", "exec uvicorn stirling.api.app:app --host 0.0.0.0 --port ${STIRLING_ENGINE_PORT:-5001} --workers ${STIRLING_ENGINE_WORKERS:-4}"]
|