28f7d02864
ci / lint (push) Successful in 25s
ci / types (push) Successful in 35s
ci / unit (push) Successful in 26s
ci / security (push) Successful in 36s
ci / dockerfile (push) Failing after 6s
ci / chart (push) Successful in 7s
ci / integration (push) Successful in 57s
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
Throwaway branch. If the dockerfile job stays green, the gate lints nothing and has been passing vacuously. Branch runs cannot push images or bump the chart, so this is side-effect free. Delete after reading the result.
64 lines
3.3 KiB
Docker
64 lines
3.3 KiB
Docker
# syntax=mirror.gcr.io/docker/dockerfile:1.10@sha256:865e5dd094beca432e8c0a1d5e1c465db5f998dca4e439981029b3b81fb39ed5
|
|
#
|
|
# 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 mirror.gcr.io/library/python:3.14-slim@sha256:cea0e6040540fb2b965b6e7fb5ffa00871e632eef63719f0ea54bca189ce14a6 AS builder
|
|
RUN cd /tmp && echo "hadolint control - this line must fail CI"
|
|
|
|
COPY --from=ghcr.io/astral-sh/uv:0.11.29@sha256:eb2843a1e56fd9e30c7276ce1a52cba86e64c7b385f5e3279a0e08e02dd058fc /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 ./
|
|
# The migrate Job runs from THIS image (migrate-job.yaml pins the api digest), so the SQL
|
|
# has to be in it. svcforge_core.migrate's fallback resolves MIGRATIONS_DIR relative to
|
|
# its own __file__, which lands under site-packages here — a directory that does not and
|
|
# should not contain SQL — so main() returned 1 and the pre-install/pre-upgrade hook
|
|
# failed every sync. SVCFORGE_MIGRATIONS_DIR below points it at this copy instead.
|
|
COPY migrations/ migrations/
|
|
# --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 mirror.gcr.io/library/python:3.14-slim@sha256:cea0e6040540fb2b965b6e7fb5ffa00871e632eef63719f0ea54bca189ce14a6
|
|
|
|
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 \
|
|
SVCFORGE_MIGRATIONS_DIR=/app/migrations
|
|
USER 10001
|
|
ENTRYPOINT ["python", "-m", "services.api"]
|