50c2fe2a1e
ci / lint (push) Successful in 1m19s
ci / unit (push) Failing after 1m2s
ci / integration (push) Has been skipped
ci / types (push) Successful in 1m37s
ci / security (push) Failing after 38s
ci / dockerfile (push) Successful in 14s
ci / image (api) (push) Has been skipped
ci / image (reconciler) (push) Has been skipped
ci / image (worker) (push) Has been skipped
ci / bump (push) Has been skipped
Complete working build of the system learn-python/ teaches. 164 tests, mypy --strict clean, domain coverage 99%.
56 lines
2.6 KiB
Docker
56 lines
2.6 KiB
Docker
# syntax=docker/dockerfile:1.10
|
|
#
|
|
# svcforge api. Build from the REPO ROOT:
|
|
# docker buildx build -f services/api/Dockerfile -t svcforge/api:dev .
|
|
# `COPY ../..` is illegal, so the context must be the root. There is no other option.
|
|
#
|
|
# Two syncs, not one: deps change rarely and our own code changes every commit, so the
|
|
# expensive layer (third-party wheels) must land before the cheap one (our source).
|
|
|
|
FROM python:3.12-slim@sha256:57cd7c3a7a273101a6485ba99423ee568157882804b1124b4dd04266317710de AS builder
|
|
|
|
COPY --from=ghcr.io/astral-sh/uv:0.5.11@sha256:0ac957607303916420297a4c9c213bb33fbd3c888f9cd7f4f7273596ebf42b85 /uv /usr/local/bin/uv
|
|
|
|
ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy UV_PYTHON_DOWNLOADS=never
|
|
WORKDIR /app
|
|
|
|
# --- layer 1: third-party dependencies only -------------------------------------------
|
|
# --no-install-project skips the root; --no-install-package skips our path dependency.
|
|
# Without the latter, uv would try to build svcforge-core here, where its source is not
|
|
# yet in the context, and the build would fail.
|
|
COPY pyproject.toml uv.lock ./
|
|
COPY libs/svcforge_core/pyproject.toml libs/svcforge_core/
|
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
uv sync --frozen --no-dev --no-editable \
|
|
--no-install-project --no-install-package svcforge-core
|
|
|
|
# --- layer 2: our code ----------------------------------------------------------------
|
|
COPY libs/ libs/
|
|
COPY services/api/ services/api/
|
|
COPY catalog.yaml ./
|
|
# --no-editable is what turns svcforge-core into a real wheel in site-packages.
|
|
# pyproject.toml declares it `editable = true` for local dev; an editable install in an
|
|
# image points at /app/libs, which is a source tree that need not survive the final stage.
|
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
uv sync --frozen --no-dev --no-editable && \
|
|
/app/.venv/bin/python -c 'import svcforge_core, sys; \
|
|
p = svcforge_core.__file__; \
|
|
sys.exit(0) if "site-packages" in p else sys.exit("not a wheel install: " + p)'
|
|
|
|
# --- runtime --------------------------------------------------------------------------
|
|
FROM python:3.12-slim@sha256:57cd7c3a7a273101a6485ba99423ee568157882804b1124b4dd04266317710de
|
|
|
|
ARG BUILD_SHA=unknown
|
|
LABEL org.opencontainers.image.title="svcforge-api" \
|
|
org.opencontainers.image.source="https://gitea.oci-oci.duckdns.org/gitea_admin/svcforge" \
|
|
org.opencontainers.image.revision="${BUILD_SHA}"
|
|
|
|
RUN useradd -u 10001 -m -s /usr/sbin/nologin svcforge
|
|
WORKDIR /app
|
|
COPY --from=builder --chown=10001:10001 /app /app
|
|
ENV PATH="/app/.venv/bin:$PATH" \
|
|
PYTHONUNBUFFERED=1 \
|
|
PYTHONDONTWRITEBYTECODE=1
|
|
USER 10001
|
|
ENTRYPOINT ["python", "-m", "services.api"]
|