# syntax=docker/dockerfile:1 # Multi-stage production image for KCA (kaya backend + Sycamore/WASM frontend). # The build context is the repository root (see ../docker-compose.yml). # --- Frontend -------------------------------------------------------------- FROM rust:1-slim AS web-builder ARG TRUNK_VERSION=0.21.14 RUN sed -i 's|http://deb.debian.org|https://deb.debian.org|g' \ /etc/apt/sources.list.d/debian.sources 2>/dev/null || true \ && apt-get update \ && apt-get install -y --no-install-recommends curl ca-certificates \ && rm -rf /var/lib/apt/lists/* RUN curl -sSfL \ "https://github.com/trunk-rs/trunk/releases/download/v${TRUNK_VERSION}/trunk-x86_64-unknown-linux-gnu.tar.gz" \ | tar -xz -C /usr/local/bin \ && rustup target add wasm32-unknown-unknown WORKDIR /web COPY web/Cargo.toml web/Cargo.lock ./ COPY web/index.html web/style.css web/theme.css web/Trunk.toml ./ COPY web/vendor ./vendor COPY web/pwa ./pwa COPY web/src ./src RUN --mount=type=cache,target=/usr/local/cargo/registry \ --mount=type=cache,target=/web/target \ trunk build --release --public-url /static/ # --- Backend --------------------------------------------------------------- FROM alpine:3.24 AS builder COPY --from=ghcr.io/astral-sh/uv:0.13.1 /uv /uvx /bin/ RUN --mount=type=cache,target=/var/cache/apk \ apk add python3 build-base python3-dev git RUN git config --global --add safe.directory /repo ENV UV_PYTHON_DOWNLOADS=0 \ UV_PROJECT_ENVIRONMENT=/opt/venv \ UV_LINK_MODE=copy WORKDIR /repo/server COPY server/uv.lock server/pyproject.toml ./ COPY server/packages/kca-core/pyproject.toml packages/kca-core/ COPY server/packages/kca-app/pyproject.toml packages/kca-app/ RUN --mount=type=cache,target=/root/.cache/uv \ uv sync --frozen --no-install-workspace --package kca-app --no-dev COPY server/packages/ ./packages/ RUN --mount=type=cache,target=/root/.cache/uv \ uv sync --locked --no-editable --package kca-app --no-dev \ --reinstall-package kca-core --reinstall-package kca-app COPY server/migrations ./migrations # --- Runtime --------------------------------------------------------------- FROM alpine:3.24 RUN --mount=type=cache,target=/var/cache/apk \ apk add python3 ca-certificates tzdata \ && addgroup -S app && adduser -S -G app app COPY --from=builder /opt/venv /opt/venv COPY --from=builder /repo/server/migrations /app/migrations COPY --from=builder /repo/server/pyproject.toml /app/pyproject.toml COPY --from=web-builder /web/dist /app/web/dist ENV PATH="/opt/venv/bin:$PATH" \ PYTHONUNBUFFERED=1 \ PYTHONDONTWRITEBYTECODE=1 \ GRANIAN_HOST=0.0.0.0 \ GRANIAN_PORT=8080 \ GRANIAN_INTERFACE=rsgi \ GRANIAN_STATIC_PATH_ROUTE="/static" \ GRANIAN_STATIC_PATH_MOUNT="/app/web/dist" \ GRANIAN_STATIC_PATH_DIR_TO_FILE=index.html \ STATIC_DIR=/app/web/dist USER app EXPOSE 8080 HEALTHCHECK --interval=30s --timeout=3s --start-period=10s \ CMD wget -q -O- http://127.0.0.1:8080/api/health || exit 1 CMD ["granian", "kca.app:app"]