ARG PYTHON_BASE=python:3.14.5-slim-bookworm@sha256:ec58d916f9e24a6035cab2bdf07f6206c4cc092a16613c60597534711332d9d6 FROM ${PYTHON_BASE} AS prepared ARG DEBIAN_MIRROR=deb.debian.org ARG DEBIAN_SECURITY_MIRROR=deb.debian.org ARG TARGETARCH ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 TZ=Asia/Shanghai \ DATA_DIR=/data CONFIG_DIR=/config WORKDIR /app # CJK fonts intentionally retained for readable Chinese rendering. RUN --mount=type=cache,id=frameflow-bookworm-apt-${TARGETARCH},target=/var/cache/apt,sharing=locked \ --mount=type=cache,id=frameflow-bookworm-lists-${TARGETARCH},target=/var/lib/apt/lists,sharing=locked \ --mount=type=bind,source=build-cache/debs,target=/build-debs,readonly \ rm -f /etc/apt/apt.conf.d/docker-clean \ && printf 'Binary::apt::APT::Keep-Downloaded-Packages "true";\n' > /etc/apt/apt.conf.d/keep-cache \ && sed -i "s|http://deb.debian.org/debian-security|https://${DEBIAN_SECURITY_MIRROR}/debian-security|g; s|http://deb.debian.org/debian|https://${DEBIAN_MIRROR}/debian|g" /etc/apt/sources.list.d/debian.sources \ && apt-get -o Acquire::Retries=3 -o Acquire::https::Timeout=60 update \ && if [ -f /build-debs/fonts-noto-cjk.deb ]; then \ font_version=$(apt-cache policy fonts-noto-cjk | awk '$1=="Candidate:" {print $2}'); \ font_sha=$(apt-cache show "fonts-noto-cjk=$font_version" | awk '$1=="SHA256:" {print $2;exit}'); \ test -n "$font_sha"; \ echo "$font_sha /build-debs/fonts-noto-cjk.deb" | sha256sum -c -; \ apt-get install -y --no-install-recommends tzdata; \ dpkg -i /build-debs/fonts-noto-cjk.deb; \ else apt-get install -y --no-install-recommends fonts-noto-cjk tzdata; fi \ && groupadd --gid 10333 frameflow && useradd --uid 10333 --gid 10333 --no-create-home frameflow \ && mkdir -p /data/images /data/generated /data/cache /config \ && chown -R 10333:10333 /data /config COPY requirements.lock ./ COPY scripts/ci-install.py /build-tools/install.py ARG DOCKER_PIP_INDEX_URL=https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple ARG DOCKER_PIP_FALLBACK_INDEX_URL=https://pypi.org/simple RUN --mount=type=cache,id=frameflow-pip-py314-${TARGETARCH},target=/root/.cache/pip,sharing=locked \ --mount=type=bind,source=build-cache/wheels,target=/build-wheels,readonly \ if [ -f /build-wheels/SHA256SUMS ]; then \ (cd /build-wheels && sha256sum -c SHA256SUMS) \ && pip install --no-index --find-links=/build-wheels -r requirements.lock; \ else python /build-tools/install.py --locked; fi COPY pigway_frame_flow ./pigway_frame_flow COPY vendor ./vendor COPY LICENSE NOTICE.md ./ # Publish only the cleaned filesystem, without retaining build-stage layers. RUN rm -rf /usr/local/lib/python*/site-packages/pip \ /usr/local/lib/python*/site-packages/pip-*.dist-info \ /usr/local/lib/python*/ensurepip \ && rm -f /usr/local/bin/pip /usr/local/bin/pip[0-9]* \ && find / -name .DS_Store -type f -delete FROM scratch COPY --from=prepared / / ENV PATH=/usr/local/bin:/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin LANG=C.UTF-8 ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 TZ=Asia/Shanghai \ DATA_DIR=/data CONFIG_DIR=/config WORKDIR /app ARG BUILD_COMMIT=development ARG BUILD_TIME=unknown ENV BUILD_COMMIT=$BUILD_COMMIT BUILD_TIME=$BUILD_TIME USER 10333:10333 EXPOSE 18787 HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \ CMD python -c "import urllib.request; urllib.request.urlopen('http://127.0.0.1:18787/health',timeout=3)" CMD ["python", "-m", "uvicorn", "pigway_frame_flow.main:app", "--host", "0.0.0.0", "--port", "18787", "--workers", "1", "--no-access-log"]